From 74c49c7ac14f3a7cc500be959709f3473a6a49e7 Mon Sep 17 00:00:00 2001 From: Harry Wentland Date: Mon, 8 May 2017 15:17:39 -0400 Subject: [PATCH] drm/amdgpu/display: Add calcs code for DCN Bandwidth and scaling calculations for DCN. Signed-off-by: Harry Wentland Signed-off-by: Alex Deucher --- .../drm/amd/display/dc/calcs/dcn_calc_auto.c | 3629 +++++++++++++++++ .../drm/amd/display/dc/calcs/dcn_calc_auto.h | 37 + .../drm/amd/display/dc/calcs/dcn_calc_math.c | 104 + .../drm/amd/display/dc/calcs/dcn_calc_math.h | 40 + .../gpu/drm/amd/display/dc/calcs/dcn_calcs.c | 1366 +++++++ .../gpu/drm/amd/display/dc/inc/dcn_calcs.h | 629 +++ 6 files changed, 5805 insertions(+) create mode 100644 drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.c create mode 100644 drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.h create mode 100644 drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c create mode 100644 drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h create mode 100644 drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c create mode 100644 drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.c new file mode 100644 index 000000000000..21b83e403ef2 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.c @@ -0,0 +1,3629 @@ +/* + * 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 "dm_services.h" +#include "dcn_calc_auto.h" +#include "dcn_calc_math.h" + +/*REVISION#247*/ +void scaler_settings_calculation(struct dcn_bw_internal_vars *v) +{ + int k; + /*scaler settings calculation*/ + + /*scale ratio calculation*/ + + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->allow_different_hratio_vratio == dcn_bw_yes) { + if (v->source_scan[k] == dcn_bw_hor) { + v->h_ratio[k] = v->viewport_width[k] / v->scaler_rec_out_width[k]; + v->v_ratio[k] = v->viewport_height[k] / v->scaler_recout_height[k]; + } else { + v->h_ratio[k] = v->viewport_height[k] / v->scaler_rec_out_width[k]; + v->v_ratio[k] = v->viewport_width[k] / v->scaler_recout_height[k]; + } + } else { + if (v->source_scan[k] == dcn_bw_hor) { + v->h_ratio[k] = dcn_bw_max2( + v->viewport_width[k] / v->scaler_rec_out_width[k], + v->viewport_height[k] / v->scaler_recout_height[k]); + } else { + v->h_ratio[k] = dcn_bw_max2( + v->viewport_height[k] / v->scaler_rec_out_width[k], + v->viewport_width[k] / v->scaler_recout_height[k]); + } + v->v_ratio[k] = v->h_ratio[k]; + } + if (v->interlace_output[k] == 1.0) { + v->v_ratio[k] = 2.0 * v->v_ratio[k]; + } + if ((v->underscan_output[k] == 1.0)) { + v->h_ratio[k] = v->h_ratio[k] * v->under_scan_factor; + v->v_ratio[k] = v->v_ratio[k] * v->under_scan_factor; + } + } + /*scaler taps calculation*/ + + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->h_ratio[k] > 1.0) { + v->acceptable_quality_hta_ps = dcn_bw_min2( + v->max_hscl_taps, + 2.0 * dcn_bw_ceil2(v->h_ratio[k], 1.0)); + } else if (v->h_ratio[k] < 1.0) { + v->acceptable_quality_hta_ps = 4.0; + } else { + v->acceptable_quality_hta_ps = 1.0; + } + if (v->ta_pscalculation == dcn_bw_override) { + v->htaps[k] = v->override_hta_ps[k]; + } else { + v->htaps[k] = v->acceptable_quality_hta_ps; + } + if (v->v_ratio[k] > 1.0) { + v->acceptable_quality_vta_ps = dcn_bw_min2( + v->max_vscl_taps, + 2.0 * dcn_bw_ceil2(v->v_ratio[k], 1.0)); + } else if (v->v_ratio[k] < 1.0) { + v->acceptable_quality_vta_ps = 4.0; + } else { + v->acceptable_quality_vta_ps = 1.0; + } + if (v->ta_pscalculation == dcn_bw_override) { + v->vtaps[k] = v->override_vta_ps[k]; + } else { + v->vtaps[k] = v->acceptable_quality_vta_ps; + } + if (v->source_pixel_format[k] == dcn_bw_rgb_sub_64 + || v->source_pixel_format[k] == dcn_bw_rgb_sub_32 + || v->source_pixel_format[k] == dcn_bw_rgb_sub_16) { + v->vta_pschroma[k] = 0.0; + v->hta_pschroma[k] = 0.0; + } else { + if (v->ta_pscalculation == dcn_bw_override) { + v->vta_pschroma[k] = v->override_vta_pschroma[k]; + v->hta_pschroma[k] = v->override_hta_pschroma[k]; + } else { + v->vta_pschroma[k] = v->acceptable_quality_vta_ps; + v->hta_pschroma[k] = v->acceptable_quality_hta_ps; + } + } + } +} +void mode_support_and_system_configuration(struct dcn_bw_internal_vars *v) +{ + int i, j, k; + /*mode support, voltage state and soc configuration*/ + + /*scale ratio support check*/ + + v->scale_ratio_support = dcn_bw_yes; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->h_ratio[k] > v->max_hscl_ratio || v->v_ratio[k] > v->max_vscl_ratio + || v->h_ratio[k] > v->htaps[k] || v->v_ratio[k] > v->vtaps[k] + || (v->source_pixel_format[k] != dcn_bw_rgb_sub_64 + && v->source_pixel_format[k] != dcn_bw_rgb_sub_32 + && v->source_pixel_format[k] != dcn_bw_rgb_sub_16 + && (v->h_ratio[k] / 2.0 > v->hta_pschroma[k] + || v->v_ratio[k] / 2.0 + > v->vta_pschroma[k]))) { + v->scale_ratio_support = dcn_bw_no; + } + } + /*source format, pixel format and scan support check*/ + + v->source_format_pixel_and_scan_support = dcn_bw_yes; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if ((v->source_surface_mode[k] == dcn_bw_sw_linear + && v->source_scan[k] != dcn_bw_hor) + || ((v->source_surface_mode[k] == dcn_bw_sw_4_kb_d + || v->source_surface_mode[k] == dcn_bw_sw_4_kb_d_x + || v->source_surface_mode[k] == dcn_bw_sw_64_kb_d + || v->source_surface_mode[k] == dcn_bw_sw_64_kb_d_t + || v->source_surface_mode[k] == dcn_bw_sw_64_kb_d_x + || v->source_surface_mode[k] == dcn_bw_sw_var_d + || v->source_surface_mode[k] == dcn_bw_sw_var_d_x) + && v->source_pixel_format[k] != dcn_bw_rgb_sub_64)) { + v->source_format_pixel_and_scan_support = dcn_bw_no; + } + } + /*bandwidth support check*/ + + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->source_scan[k] == dcn_bw_hor) { + v->swath_width_ysingle_dpp[k] = v->viewport_width[k]; + } else { + v->swath_width_ysingle_dpp[k] = v->viewport_height[k]; + } + if (v->source_pixel_format[k] == dcn_bw_rgb_sub_64) { + v->byte_per_pixel_in_dety[k] = 8.0; + v->byte_per_pixel_in_detc[k] = 0.0; + } else if (v->source_pixel_format[k] == dcn_bw_rgb_sub_32) { + v->byte_per_pixel_in_dety[k] = 4.0; + v->byte_per_pixel_in_detc[k] = 0.0; + } else if (v->source_pixel_format[k] == dcn_bw_rgb_sub_16) { + v->byte_per_pixel_in_dety[k] = 2.0; + v->byte_per_pixel_in_detc[k] = 0.0; + } else if (v->source_pixel_format[k] == dcn_bw_yuv420_sub_8) { + v->byte_per_pixel_in_dety[k] = 1.0; + v->byte_per_pixel_in_detc[k] = 2.0; + } else { + v->byte_per_pixel_in_dety[k] = 4.0f / 3; + v->byte_per_pixel_in_detc[k] = 8.0f / 3; + } + } + v->total_read_bandwidth_consumed_gbyte_per_second = 0.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + v->read_bandwidth[k] = v->swath_width_ysingle_dpp[k] + * (dcn_bw_ceil2(v->byte_per_pixel_in_dety[k], 1.0) * v->v_ratio[k] + + dcn_bw_ceil2(v->byte_per_pixel_in_detc[k], 2.0) / 2.0 + * v->v_ratio[k] / 2) + / (v->htotal[k] / v->pixel_clock[k]); + if (v->dcc_enable[k] == dcn_bw_yes) { + v->read_bandwidth[k] = v->read_bandwidth[k] * (1 + 1 / 256); + } + if (v->pte_enable == dcn_bw_yes && v->source_scan[k] != dcn_bw_hor + && (v->source_surface_mode[k] == dcn_bw_sw_4_kb_s + || v->source_surface_mode[k] == dcn_bw_sw_4_kb_s_x + || v->source_surface_mode[k] == dcn_bw_sw_4_kb_d + || v->source_surface_mode[k] == dcn_bw_sw_4_kb_d_x)) { + v->read_bandwidth[k] = v->read_bandwidth[k] * (1 + 1 / 64); + } else if (v->pte_enable == dcn_bw_yes && v->source_scan[k] == dcn_bw_hor + && (v->source_pixel_format[k] == dcn_bw_rgb_sub_64 + || v->source_pixel_format[k] == dcn_bw_rgb_sub_32) + && (v->source_surface_mode[k] == dcn_bw_sw_64_kb_s + || v->source_surface_mode[k] == dcn_bw_sw_64_kb_s_t + || v->source_surface_mode[k] == dcn_bw_sw_64_kb_s_x + || v->source_surface_mode[k] == dcn_bw_sw_64_kb_d + || v->source_surface_mode[k] == dcn_bw_sw_64_kb_d_t + || v->source_surface_mode[k] == dcn_bw_sw_64_kb_d_x)) { + v->read_bandwidth[k] = v->read_bandwidth[k] * (1 + 1 / 256); + } else if (v->pte_enable == dcn_bw_yes) { + v->read_bandwidth[k] = v->read_bandwidth[k] * (1 + 1 / 512); + } + v->total_read_bandwidth_consumed_gbyte_per_second = + v->total_read_bandwidth_consumed_gbyte_per_second + + v->read_bandwidth[k] / 1000.0; + } + v->total_write_bandwidth_consumed_gbyte_per_second = 0.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->output[k] == dcn_bw_writeback && v->output_format[k] == dcn_bw_444) { + v->write_bandwidth[k] = v->scaler_rec_out_width[k] + / (v->htotal[k] / v->pixel_clock[k]) * 4.0; + } else if (v->output[k] == dcn_bw_writeback) { + v->write_bandwidth[k] = v->scaler_rec_out_width[k] + / (v->htotal[k] / v->pixel_clock[k]) * 1.5; + } else { + v->write_bandwidth[k] = 0.0; + } + v->total_write_bandwidth_consumed_gbyte_per_second = + v->total_write_bandwidth_consumed_gbyte_per_second + + v->write_bandwidth[k] / 1000.0; + } + v->total_bandwidth_consumed_gbyte_per_second = + v->total_read_bandwidth_consumed_gbyte_per_second + + v->total_write_bandwidth_consumed_gbyte_per_second; + v->dcc_enabled_in_any_plane = dcn_bw_no; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->dcc_enable[k] == dcn_bw_yes) { + v->dcc_enabled_in_any_plane = dcn_bw_yes; + } + } + for (i = 0; i <= number_of_states_plus_one; i++) { + v->return_bw_todcn_per_state = + dcn_bw_min2( + v->return_bus_width * v->dcfclk_per_state[i], + v->fabric_and_dram_bandwidth_per_state[i] * 1000.0 + * v->percent_of_ideal_drambw_received_after_urg_latency + / 100.0); + v->return_bw_per_state[i] = v->return_bw_todcn_per_state; + if (v->dcc_enabled_in_any_plane == dcn_bw_yes + && v->return_bw_todcn_per_state + > v->dcfclk_per_state[i] * v->return_bus_width + / 4.0) { + v->return_bw_per_state[i] = + dcn_bw_min2( + v->return_bw_per_state[i], + v->return_bw_todcn_per_state * 4.0 + * (1.0 + - v->urgent_latency + / ((v->rob_buffer_size_in_kbyte + - v->pixel_chunk_size_in_kbyte) + * 1024.0 + / (v->return_bw_todcn_per_state + - v->dcfclk_per_state[i] + * v->return_bus_width + / 4.0) + + v->urgent_latency))); + } + v->critical_point = 2.0 * v->return_bus_width * v->dcfclk_per_state[i] + * v->urgent_latency + / (v->return_bw_todcn_per_state * v->urgent_latency + + (v->rob_buffer_size_in_kbyte + - v->pixel_chunk_size_in_kbyte) + * 1024.0); + if (v->dcc_enabled_in_any_plane == dcn_bw_yes && v->critical_point > 1.0 + && v->critical_point < 4.0) { + v->return_bw_per_state[i] = + dcn_bw_min2( + v->return_bw_per_state[i], + dcn_bw_pow( + 4.0 + * v->return_bw_todcn_per_state + * (v->rob_buffer_size_in_kbyte + - v->pixel_chunk_size_in_kbyte) + * 1024.0 + * v->return_bus_width + * v->dcfclk_per_state[i] + * v->urgent_latency + / (v->return_bw_todcn_per_state + * v->urgent_latency + + (v->rob_buffer_size_in_kbyte + - v->pixel_chunk_size_in_kbyte) + * 1024.0), + 2)); + } + v->return_bw_todcn_per_state = dcn_bw_min2( + v->return_bus_width * v->dcfclk_per_state[i], + v->fabric_and_dram_bandwidth_per_state[i] * 1000.0); + if (v->dcc_enabled_in_any_plane == dcn_bw_yes + && v->return_bw_todcn_per_state + > v->dcfclk_per_state[i] * v->return_bus_width + / 4.0) { + v->return_bw_per_state[i] = + dcn_bw_min2( + v->return_bw_per_state[i], + v->return_bw_todcn_per_state * 4.0 + * (1.0 + - v->urgent_latency + / ((v->rob_buffer_size_in_kbyte + - v->pixel_chunk_size_in_kbyte) + * 1024.0 + / (v->return_bw_todcn_per_state + - v->dcfclk_per_state[i] + * v->return_bus_width + / 4.0) + + v->urgent_latency))); + } + v->critical_point = 2.0 * v->return_bus_width * v->dcfclk_per_state[i] + * v->urgent_latency + / (v->return_bw_todcn_per_state * v->urgent_latency + + (v->rob_buffer_size_in_kbyte + - v->pixel_chunk_size_in_kbyte) + * 1024.0); + if (v->dcc_enabled_in_any_plane == dcn_bw_yes && v->critical_point > 1.0 + && v->critical_point < 4.0) { + v->return_bw_per_state[i] = + dcn_bw_min2( + v->return_bw_per_state[i], + dcn_bw_pow( + 4.0 + * v->return_bw_todcn_per_state + * (v->rob_buffer_size_in_kbyte + - v->pixel_chunk_size_in_kbyte) + * 1024.0 + * v->return_bus_width + * v->dcfclk_per_state[i] + * v->urgent_latency + / (v->return_bw_todcn_per_state + * v->urgent_latency + + (v->rob_buffer_size_in_kbyte + - v->pixel_chunk_size_in_kbyte) + * 1024.0), + 2)); + } + } + for (i = 0; i <= number_of_states_plus_one; i++) { + if ((v->total_read_bandwidth_consumed_gbyte_per_second * 1000.0 + <= v->return_bw_per_state[i]) + && (v->total_bandwidth_consumed_gbyte_per_second * 1000.0 + <= v->fabric_and_dram_bandwidth_per_state[i] + * 1000.0 + * v->percent_of_ideal_drambw_received_after_urg_latency + / 100.0)) { + v->bandwidth_support[i] = dcn_bw_yes; + } else { + v->bandwidth_support[i] = dcn_bw_no; + } + } + /*writeback latency support check*/ + + v->writeback_latency_support = dcn_bw_yes; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->output[k] == dcn_bw_writeback && v->output_format[k] == dcn_bw_444 + && v->scaler_rec_out_width[k] / (v->htotal[k] / v->pixel_clock[k]) + * 4.0 + > (v->writeback_luma_buffer_size + + v->writeback_chroma_buffer_size) + * 1024.0 / v->write_back_latency) { + v->writeback_latency_support = dcn_bw_no; + } else if (v->output[k] == dcn_bw_writeback + && v->scaler_rec_out_width[k] / (v->htotal[k] / v->pixel_clock[k]) + > dcn_bw_min2( + v->writeback_luma_buffer_size, + 2.0 + * v->writeback_chroma_buffer_size) + * 1024.0 / v->write_back_latency) { + v->writeback_latency_support = dcn_bw_no; + } + } + /*re-ordering buffer support check*/ + + for (i = 0; i <= number_of_states_plus_one; i++) { + v->urgent_round_trip_and_out_of_order_latency_per_state[i] = + (v->round_trip_ping_latency_cycles + 32.0) / v->dcfclk_per_state[i] + + v->urgent_out_of_order_return_per_channel + * v->number_of_channels + / v->return_bw_per_state[i]; + if ((v->rob_buffer_size_in_kbyte - v->pixel_chunk_size_in_kbyte) * 1024.0 + / v->return_bw_per_state[i] + > v->urgent_round_trip_and_out_of_order_latency_per_state[i]) { + v->rob_support[i] = dcn_bw_yes; + } else { + v->rob_support[i] = dcn_bw_no; + } + } + /*display io support check*/ + + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->output[k] == dcn_bw_dp && v->dsc_capability == dcn_bw_yes) { + if (v->output_format[k] == dcn_bw_420) { + v->required_output_bw = v->pixel_clock[k] / 2.0; + } else { + v->required_output_bw = v->pixel_clock[k]; + } + } else if (v->output_format[k] == dcn_bw_420) { + v->required_output_bw = v->pixel_clock[k] * 3.0 / 2.0; + } else { + v->required_output_bw = v->pixel_clock[k] * 3.0; + } + if (v->output[k] == dcn_bw_hdmi) { + v->required_phyclk[k] = v->required_output_bw / 3.0; + } else if (v->output[k] == dcn_bw_dp) { + v->required_phyclk[k] = v->required_output_bw / 4.0; + } else { + v->required_phyclk[k] = 0.0; + } + } + for (i = 0; i <= number_of_states_plus_one; i++) { + v->dio_support[i] = dcn_bw_yes; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->required_phyclk[k] > v->phyclk_per_state[i] + || (v->output[k] == dcn_bw_hdmi + && v->required_phyclk[k] > 600.0)) { + v->dio_support[i] = dcn_bw_no; + } + } + } + /*total available writeback support check*/ + + v->total_number_of_active_writeback = 0.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->output[k] == dcn_bw_writeback) { + v->total_number_of_active_writeback = v->total_number_of_active_writeback + + 1.0; + } + } + if (v->total_number_of_active_writeback <= v->max_num_writeback) { + v->total_available_writeback_support = dcn_bw_yes; + } else { + v->total_available_writeback_support = dcn_bw_no; + } + /*maximum dispclk/dppclk support check*/ + + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->h_ratio[k] > 1.0) { + v->pscl_factor[k] = dcn_bw_min2( + v->max_dchub_topscl_throughput, + v->max_pscl_tolb_throughput * v->h_ratio[k] + / dcn_bw_ceil2(v->htaps[k] / 6.0, 1.0)); + } else { + v->pscl_factor[k] = dcn_bw_min2( + v->max_dchub_topscl_throughput, + v->max_pscl_tolb_throughput); + } + if (v->byte_per_pixel_in_detc[k] == 0.0) { + v->pscl_factor_chroma[k] = 0.0; + v->min_dppclk_using_single_dpp[k] = + v->pixel_clock[k] + * dcn_bw_max3( + v->vtaps[k] / 6.0 + * dcn_bw_min2( + 1.0, + v->h_ratio[k]), + v->h_ratio[k] + * v->v_ratio[k] + / v->pscl_factor[k], + 1.0); + } else { + if (v->h_ratio[k] / 2.0 > 1.0) { + v->pscl_factor_chroma[k] = + dcn_bw_min2( + v->max_dchub_topscl_throughput, + v->max_pscl_tolb_throughput + * v->h_ratio[k] + / 2.0 + / dcn_bw_ceil2( + v->hta_pschroma[k] + / 6.0, + 1.0)); + } else { + v->pscl_factor_chroma[k] = dcn_bw_min2( + v->max_dchub_topscl_throughput, + v->max_pscl_tolb_throughput); + } + v->min_dppclk_using_single_dpp[k] = + v->pixel_clock[k] + * dcn_bw_max5( + v->vtaps[k] / 6.0 + * dcn_bw_min2( + 1.0, + v->h_ratio[k]), + v->h_ratio[k] + * v->v_ratio[k] + / v->pscl_factor[k], + v->vta_pschroma[k] / 6.0 + * dcn_bw_min2( + 1.0, + v->h_ratio[k] + / 2.0), + v->h_ratio[k] + * v->v_ratio[k] + / 4.0 + / v->pscl_factor_chroma[k], + 1.0); + } + } + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if ((v->source_pixel_format[k] == dcn_bw_rgb_sub_64 + || v->source_pixel_format[k] == dcn_bw_rgb_sub_32 + || v->source_pixel_format[k] == dcn_bw_rgb_sub_16)) { + if (v->source_surface_mode[k] == dcn_bw_sw_linear) { + v->read256_block_height_y[k] = 1.0; + } else if (v->source_pixel_format[k] == dcn_bw_rgb_sub_64) { + v->read256_block_height_y[k] = 4.0; + } else { + v->read256_block_height_y[k] = 8.0; + } + v->read256_block_width_y[k] = 256.0 + / dcn_bw_ceil2(v->byte_per_pixel_in_dety[k], 1.0) + / v->read256_block_height_y[k]; + v->read256_block_height_c[k] = 0.0; + v->read256_block_width_c[k] = 0.0; + } else { + if (v->source_surface_mode[k] == dcn_bw_sw_linear) { + v->read256_block_height_y[k] = 1.0; + v->read256_block_height_c[k] = 1.0; + } else if (v->source_pixel_format[k] == dcn_bw_yuv420_sub_8) { + v->read256_block_height_y[k] = 16.0; + v->read256_block_height_c[k] = 8.0; + } else { + v->read256_block_height_y[k] = 8.0; + v->read256_block_height_c[k] = 8.0; + } + v->read256_block_width_y[k] = 256.0 + / dcn_bw_ceil2(v->byte_per_pixel_in_dety[k], 1.0) + / v->read256_block_height_y[k]; + v->read256_block_width_c[k] = 256.0 + / dcn_bw_ceil2(v->byte_per_pixel_in_detc[k], 2.0) + / v->read256_block_height_c[k]; + } + if (v->source_scan[k] == dcn_bw_hor) { + v->max_swath_height_y[k] = v->read256_block_height_y[k]; + v->max_swath_height_c[k] = v->read256_block_height_c[k]; + } else { + v->max_swath_height_y[k] = v->read256_block_width_y[k]; + v->max_swath_height_c[k] = v->read256_block_width_c[k]; + } + if ((v->source_pixel_format[k] == dcn_bw_rgb_sub_64 + || v->source_pixel_format[k] == dcn_bw_rgb_sub_32 + || v->source_pixel_format[k] == dcn_bw_rgb_sub_16)) { + if (v->source_surface_mode[k] == dcn_bw_sw_linear + || (v->source_pixel_format[k] == dcn_bw_rgb_sub_64 + && (v->source_surface_mode[k] + == dcn_bw_sw_4_kb_s + || v->source_surface_mode[k] + == dcn_bw_sw_4_kb_s_x + || v->source_surface_mode[k] + == dcn_bw_sw_64_kb_s + || v->source_surface_mode[k] + == dcn_bw_sw_64_kb_s_t + || v->source_surface_mode[k] + == dcn_bw_sw_64_kb_s_x + || v->source_surface_mode[k] + == dcn_bw_sw_var_s + || v->source_surface_mode[k] + == dcn_bw_sw_var_s_x) + && v->source_scan[k] == dcn_bw_hor)) { + v->min_swath_height_y[k] = v->max_swath_height_y[k]; + } else { + v->min_swath_height_y[k] = v->max_swath_height_y[k] / 2.0; + } + v->min_swath_height_c[k] = v->max_swath_height_c[k]; + } else { + if (v->source_surface_mode[k] == dcn_bw_sw_linear) { + v->min_swath_height_y[k] = v->max_swath_height_y[k]; + v->min_swath_height_c[k] = v->max_swath_height_c[k]; + } else if (v->source_pixel_format[k] == dcn_bw_yuv420_sub_8 + && v->source_scan[k] == dcn_bw_hor) { + v->min_swath_height_y[k] = v->max_swath_height_y[k] / 2.0; + if (v->bug_forcing_luma_and_chroma_request_to_same_size_fixed + == dcn_bw_yes) { + v->min_swath_height_c[k] = v->max_swath_height_c[k]; + } else { + v->min_swath_height_c[k] = v->max_swath_height_c[k] / 2.0; + } + } else if (v->source_pixel_format[k] == dcn_bw_yuv420_sub_10 + && v->source_scan[k] == dcn_bw_hor) { + v->min_swath_height_c[k] = v->max_swath_height_c[k] / 2.0; + if (v->bug_forcing_luma_and_chroma_request_to_same_size_fixed + == dcn_bw_yes) { + v->min_swath_height_y[k] = v->max_swath_height_y[k]; + } else { + v->min_swath_height_y[k] = v->max_swath_height_y[k] / 2.0; + } + } else { + v->min_swath_height_y[k] = v->max_swath_height_y[k]; + v->min_swath_height_c[k] = v->max_swath_height_c[k]; + } + } + if (v->source_surface_mode[k] == dcn_bw_sw_linear) { + v->maximum_swath_width = 8192.0; + } else { + v->maximum_swath_width = 5120.0; + } + v->number_of_dpp_required_for_det_size = + dcn_bw_ceil2( + v->swath_width_ysingle_dpp[k] + / dcn_bw_min2( + v->maximum_swath_width, + v->det_buffer_size_in_kbyte + * 1024.0 + / 2.0 + / (v->byte_per_pixel_in_dety[k] + * v->min_swath_height_y[k] + + v->byte_per_pixel_in_detc[k] + / 2.0 + * v->min_swath_height_c[k])), + 1.0); + if (v->byte_per_pixel_in_detc[k] == 0.0) { + v->number_of_dpp_required_for_lb_size = dcn_bw_ceil2( + (v->vtaps[k] + + dcn_bw_max2( + dcn_bw_ceil2(v->v_ratio[k], 1.0) + - 2, + 0.0)) + * v->swath_width_ysingle_dpp[k] + / dcn_bw_max2(v->h_ratio[k], 1.0) + * v->lb_bit_per_pixel[k] + / v->line_buffer_size, + 1.0); + } else { + v->number_of_dpp_required_for_lb_size = + dcn_bw_max2( + dcn_bw_ceil2( + (v->vtaps[k] + + dcn_bw_max2( + dcn_bw_ceil2( + v->v_ratio[k], + 1.0) + - 2, + 0.0)) + * v->swath_width_ysingle_dpp[k] + / dcn_bw_max2( + v->h_ratio[k], + 1.0) + * v->lb_bit_per_pixel[k] + / v->line_buffer_size, + 1.0), + dcn_bw_ceil2( + (v->vta_pschroma[k] + + dcn_bw_max2( + dcn_bw_ceil2( + v->v_ratio[k] + / 2.0, + 1.0) + - 2, + 0.0)) + * v->swath_width_ysingle_dpp[k] + / 2.0 + / dcn_bw_max2( + v->h_ratio[k] + / 2.0, + 1.0) + * v->lb_bit_per_pixel[k] + / v->line_buffer_size, + 1.0)); + } + v->number_of_dpp_required_for_det_and_lb_size[k] = dcn_bw_max2( + v->number_of_dpp_required_for_det_size, + v->number_of_dpp_required_for_lb_size); + } + for (i = 0; i <= number_of_states_plus_one; i++) { + for (j = 0; j <= 1; j++) { + v->total_number_of_active_dpp[i][j] = 0.0; + v->required_dispclk[i][j] = 0.0; + v->dispclk_dppclk_support[i][j] = dcn_bw_yes; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + v->min_dispclk_using_single_dpp = dcn_bw_max2( + v->pixel_clock[k], + v->min_dppclk_using_single_dpp[k] * (j + 1)) + * (1.0 + v->downspreading / 100.0); + if (v->odm_capability == dcn_bw_yes) { + v->min_dispclk_using_dual_dpp = dcn_bw_max2( + v->pixel_clock[k] / 2.0, + v->min_dppclk_using_single_dpp[k] / 2.0 + * (j + 1)) + * (1.0 + v->downspreading / 100.0); + } else { + v->min_dispclk_using_dual_dpp = dcn_bw_max2( + v->pixel_clock[k], + v->min_dppclk_using_single_dpp[k] / 2.0 + * (j + 1)) + * (1.0 + v->downspreading / 100.0); + } + if (i < number_of_states) { + v->min_dispclk_using_single_dpp = + v->min_dispclk_using_single_dpp + * (1.0 + + v->dispclk_ramping_margin + / 100.0); + v->min_dispclk_using_dual_dpp = + v->min_dispclk_using_dual_dpp + * (1.0 + + v->dispclk_ramping_margin + / 100.0); + } + if (v->min_dispclk_using_single_dpp + <= dcn_bw_min2( + v->max_dispclk[i], + (j + 1) * v->max_dppclk[i]) + && v->number_of_dpp_required_for_det_and_lb_size[k] + <= 1.0) { + v->no_of_dpp[i][j][k] = 1.0; + v->required_dispclk[i][j] = dcn_bw_max2( + v->required_dispclk[i][j], + v->min_dispclk_using_single_dpp); + } else if (v->min_dispclk_using_dual_dpp + <= dcn_bw_min2( + v->max_dispclk[i], + (j + 1) * v->max_dppclk[i])) { + v->no_of_dpp[i][j][k] = 2.0; + v->required_dispclk[i][j] = dcn_bw_max2( + v->required_dispclk[i][j], + v->min_dispclk_using_dual_dpp); + } else { + v->no_of_dpp[i][j][k] = 2.0; + v->required_dispclk[i][j] = dcn_bw_max2( + v->required_dispclk[i][j], + v->min_dispclk_using_dual_dpp); + v->dispclk_dppclk_support[i][j] = dcn_bw_no; + } + v->total_number_of_active_dpp[i][j] = + v->total_number_of_active_dpp[i][j] + + v->no_of_dpp[i][j][k]; + } + if (v->total_number_of_active_dpp[i][j] > v->max_num_dpp) { + v->total_number_of_active_dpp[i][j] = 0.0; + v->required_dispclk[i][j] = 0.0; + v->dispclk_dppclk_support[i][j] = dcn_bw_yes; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + v->min_dispclk_using_single_dpp = dcn_bw_max2( + v->pixel_clock[k], + v->min_dppclk_using_single_dpp[k] * (j + 1)) + * (1.0 + v->downspreading / 100.0); + v->min_dispclk_using_dual_dpp = dcn_bw_max2( + v->pixel_clock[k], + v->min_dppclk_using_single_dpp[k] / 2.0 + * (j + 1)) + * (1.0 + v->downspreading / 100.0); + if (i < number_of_states) { + v->min_dispclk_using_single_dpp = + v->min_dispclk_using_single_dpp + * (1.0 + + v->dispclk_ramping_margin + / 100.0); + v->min_dispclk_using_dual_dpp = + v->min_dispclk_using_dual_dpp + * (1.0 + + v->dispclk_ramping_margin + / 100.0); + } + if (v->number_of_dpp_required_for_det_and_lb_size[k] + <= 1.0) { + v->no_of_dpp[i][j][k] = 1.0; + v->required_dispclk[i][j] = dcn_bw_max2( + v->required_dispclk[i][j], + v->min_dispclk_using_single_dpp); + if (v->min_dispclk_using_single_dpp + > dcn_bw_min2( + v->max_dispclk[i], + (j + 1) + * v->max_dppclk[i])) { + v->dispclk_dppclk_support[i][j] = dcn_bw_no; + } + } else { + v->no_of_dpp[i][j][k] = 2.0; + v->required_dispclk[i][j] = dcn_bw_max2( + v->required_dispclk[i][j], + v->min_dispclk_using_dual_dpp); + if (v->min_dispclk_using_dual_dpp + > dcn_bw_min2( + v->max_dispclk[i], + (j + 1) + * v->max_dppclk[i])) { + v->dispclk_dppclk_support[i][j] = dcn_bw_no; + } + } + v->total_number_of_active_dpp[i][j] = + v->total_number_of_active_dpp[i][j] + + v->no_of_dpp[i][j][k]; + } + } + } + } + /*viewport size check*/ + + v->viewport_size_support = dcn_bw_yes; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->number_of_dpp_required_for_det_and_lb_size[k] > 2.0) { + v->viewport_size_support = dcn_bw_no; + } + } + /*total available pipes support check*/ + + for (i = 0; i <= number_of_states_plus_one; i++) { + for (j = 0; j <= 1; j++) { + if (v->total_number_of_active_dpp[i][j] <= v->max_num_dpp) { + v->total_available_pipes_support[i][j] = dcn_bw_yes; + } else { + v->total_available_pipes_support[i][j] = dcn_bw_no; + } + } + } + /*urgent latency support check*/ + + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + for (i = 0; i <= number_of_states_plus_one; i++) { + for (j = 0; j <= 1; j++) { + v->swath_width_yper_state[i][j][k] = v->swath_width_ysingle_dpp[k] + / v->no_of_dpp[i][j][k]; + v->swath_width_granularity_y = 256.0 + / dcn_bw_ceil2(v->byte_per_pixel_in_dety[k], 1.0) + / v->max_swath_height_y[k]; + v->rounded_up_max_swath_size_bytes_y = (dcn_bw_ceil2( + v->swath_width_yper_state[i][j][k] - 1.0, + v->swath_width_granularity_y) + + v->swath_width_granularity_y) + * v->byte_per_pixel_in_dety[k] + * v->max_swath_height_y[k]; + if (v->source_pixel_format[k] == dcn_bw_yuv420_sub_10) { + v->rounded_up_max_swath_size_bytes_y = dcn_bw_ceil2( + v->rounded_up_max_swath_size_bytes_y, + 256.0) + 256; + } + if (v->max_swath_height_c[k] > 0.0) { + v->swath_width_granularity_c = + 256.0 + / dcn_bw_ceil2( + v->byte_per_pixel_in_detc[k], + 2.0) + / v->max_swath_height_c[k]; + } + v->rounded_up_max_swath_size_bytes_c = (dcn_bw_ceil2( + v->swath_width_yper_state[i][j][k] / 2.0 - 1.0, + v->swath_width_granularity_c) + + v->swath_width_granularity_c) + * v->byte_per_pixel_in_detc[k] + * v->max_swath_height_c[k]; + if (v->source_pixel_format[k] == dcn_bw_yuv420_sub_10) { + v->rounded_up_max_swath_size_bytes_c = dcn_bw_ceil2( + v->rounded_up_max_swath_size_bytes_c, + 256.0) + 256; + } + if (v->rounded_up_max_swath_size_bytes_y + + v->rounded_up_max_swath_size_bytes_c + <= v->det_buffer_size_in_kbyte * 1024.0 / 2.0) { + v->swath_height_yper_state[i][j][k] = + v->max_swath_height_y[k]; + v->swath_height_cper_state[i][j][k] = + v->max_swath_height_c[k]; + } else { + v->swath_height_yper_state[i][j][k] = + v->min_swath_height_y[k]; + v->swath_height_cper_state[i][j][k] = + v->min_swath_height_c[k]; + } + if (v->byte_per_pixel_in_detc[k] == 0.0) { + v->lines_in_det_luma = v->det_buffer_size_in_kbyte * 1024.0 + / v->byte_per_pixel_in_dety[k] + / v->swath_width_yper_state[i][j][k]; + v->lines_in_det_chroma = 0.0; + } else if (v->swath_height_yper_state[i][j][k] + <= v->swath_height_cper_state[i][j][k]) { + v->lines_in_det_luma = v->det_buffer_size_in_kbyte * 1024.0 + / 2.0 / v->byte_per_pixel_in_dety[k] + / v->swath_width_yper_state[i][j][k]; + v->lines_in_det_chroma = + v->det_buffer_size_in_kbyte * 1024.0 / 2.0 + / v->byte_per_pixel_in_detc[k] + / (v->swath_width_yper_state[i][j][k] + / 2.0); + } else { + v->lines_in_det_luma = v->det_buffer_size_in_kbyte * 1024.0 + * 2.0 / 3.0 / v->byte_per_pixel_in_dety[k] + / v->swath_width_yper_state[i][j][k]; + v->lines_in_det_chroma = + v->det_buffer_size_in_kbyte * 1024.0 / 3.0 + / v->byte_per_pixel_in_dety[k] + / (v->swath_width_yper_state[i][j][k] + / 2.0); + } + v->effective_lb_latency_hiding_source_lines_luma = + dcn_bw_min2( + v->max_line_buffer_lines, + dcn_bw_floor2( + v->line_buffer_size + / v->lb_bit_per_pixel[k] + / (v->swath_width_yper_state[i][j][k] + / dcn_bw_max2( + v->h_ratio[k], + 1.0)), + 1.0)) + - (v->vtaps[k] - 1.0); + v->effective_lb_latency_hiding_source_lines_chroma = + dcn_bw_min2( + v->max_line_buffer_lines, + dcn_bw_floor2( + v->line_buffer_size + / v->lb_bit_per_pixel[k] + / (v->swath_width_yper_state[i][j][k] + / 2.0 + / dcn_bw_max2( + v->h_ratio[k] + / 2.0, + 1.0)), + 1.0)) + - (v->vta_pschroma[k] - 1.0); + v->effective_detlb_lines_luma = + dcn_bw_floor2( + v->lines_in_det_luma + + dcn_bw_min2( + v->lines_in_det_luma + * v->required_dispclk[i][j] + * v->byte_per_pixel_in_dety[k] + * v->pscl_factor[k] + / v->return_bw_per_state[i], + v->effective_lb_latency_hiding_source_lines_luma), + v->swath_height_yper_state[i][j][k]); + v->effective_detlb_lines_chroma = + dcn_bw_floor2( + v->lines_in_det_chroma + + dcn_bw_min2( + v->lines_in_det_chroma + * v->required_dispclk[i][j] + * v->byte_per_pixel_in_detc[k] + * v->pscl_factor_chroma[k] + / v->return_bw_per_state[i], + v->effective_lb_latency_hiding_source_lines_chroma), + v->swath_height_cper_state[i][j][k]); + if (v->byte_per_pixel_in_detc[k] == 0.0) { + v->urgent_latency_support_us_per_state[i][j][k] = + v->effective_detlb_lines_luma + * (v->htotal[k] + / v->pixel_clock[k]) + / v->v_ratio[k] + - v->effective_detlb_lines_luma + * v->swath_width_yper_state[i][j][k] + * dcn_bw_ceil2( + v->byte_per_pixel_in_dety[k], + 1.0) + / (v->return_bw_per_state[i] + / v->no_of_dpp[i][j][k]); + } else { + v->urgent_latency_support_us_per_state[i][j][k] = + dcn_bw_min2( + v->effective_detlb_lines_luma + * (v->htotal[k] + / v->pixel_clock[k]) + / v->v_ratio[k] + - v->effective_detlb_lines_luma + * v->swath_width_yper_state[i][j][k] + * dcn_bw_ceil2( + v->byte_per_pixel_in_dety[k], + 1.0) + / (v->return_bw_per_state[i] + / v->no_of_dpp[i][j][k]), + v->effective_detlb_lines_chroma + * (v->htotal[k] + / v->pixel_clock[k]) + / (v->v_ratio[k] + / 2.0) + - v->effective_detlb_lines_chroma + * v->swath_width_yper_state[i][j][k] + / 2.0 + * dcn_bw_ceil2( + v->byte_per_pixel_in_detc[k], + 2.0) + / (v->return_bw_per_state[i] + / v->no_of_dpp[i][j][k])); + } + } + } + } + for (i = 0; i <= number_of_states_plus_one; i++) { + for (j = 0; j <= 1; j++) { + v->urgent_latency_support[i][j] = dcn_bw_yes; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->urgent_latency_support_us_per_state[i][j][k] + < v->urgent_latency / 1.0) { + v->urgent_latency_support[i][j] = dcn_bw_no; + } + } + } + } + /*prefetch check*/ + + for (i = 0; i <= number_of_states_plus_one; i++) { + for (j = 0; j <= 1; j++) { + v->total_number_of_dcc_active_dpp[i][j] = 0.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->dcc_enable[k] == dcn_bw_yes) { + v->total_number_of_dcc_active_dpp[i][j] = + v->total_number_of_dcc_active_dpp[i][j] + + v->no_of_dpp[i][j][k]; + } + } + } + } + for (i = 0; i <= number_of_states_plus_one; i++) { + for (j = 0; j <= 1; j++) { + v->projected_dcfclk_deep_sleep = 8.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + v->projected_dcfclk_deep_sleep = dcn_bw_max2( + v->projected_dcfclk_deep_sleep, + v->pixel_clock[k] / 16.0); + if (v->byte_per_pixel_in_detc[k] == 0.0) { + if (v->v_ratio[k] <= 1.0) { + v->projected_dcfclk_deep_sleep = + dcn_bw_max2( + v->projected_dcfclk_deep_sleep, + 1.1 + * dcn_bw_ceil2( + v->byte_per_pixel_in_dety[k], + 1.0) + / 64.0 + * v->h_ratio[k] + * v->pixel_clock[k] + / v->no_of_dpp[i][j][k]); + } else { + v->projected_dcfclk_deep_sleep = + dcn_bw_max2( + v->projected_dcfclk_deep_sleep, + 1.1 + * dcn_bw_ceil2( + v->byte_per_pixel_in_dety[k], + 1.0) + / 64.0 + * v->pscl_factor[k] + * v->required_dispclk[i][j] + / (1 + + j)); + } + } else { + if (v->v_ratio[k] <= 1.0) { + v->projected_dcfclk_deep_sleep = + dcn_bw_max2( + v->projected_dcfclk_deep_sleep, + 1.1 + * dcn_bw_ceil2( + v->byte_per_pixel_in_dety[k], + 1.0) + / 32.0 + * v->h_ratio[k] + * v->pixel_clock[k] + / v->no_of_dpp[i][j][k]); + } else { + v->projected_dcfclk_deep_sleep = + dcn_bw_max2( + v->projected_dcfclk_deep_sleep, + 1.1 + * dcn_bw_ceil2( + v->byte_per_pixel_in_dety[k], + 1.0) + / 32.0 + * v->pscl_factor[k] + * v->required_dispclk[i][j] + / (1 + + j)); + } + if (v->v_ratio[k] / 2.0 <= 1.0) { + v->projected_dcfclk_deep_sleep = + dcn_bw_max2( + v->projected_dcfclk_deep_sleep, + 1.1 + * dcn_bw_ceil2( + v->byte_per_pixel_in_detc[k], + 2.0) + / 32.0 + * v->h_ratio[k] + / 2.0 + * v->pixel_clock[k] + / v->no_of_dpp[i][j][k]); + } else { + v->projected_dcfclk_deep_sleep = + dcn_bw_max2( + v->projected_dcfclk_deep_sleep, + 1.1 + * dcn_bw_ceil2( + v->byte_per_pixel_in_detc[k], + 2.0) + / 32.0 + * v->pscl_factor_chroma[k] + * v->required_dispclk[i][j] + / (1 + + j)); + } + } + } + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->dcc_enable[k] == dcn_bw_yes) { + v->meta_req_height_y = 8.0 * v->read256_block_height_y[k]; + v->meta_req_width_y = + 64.0 * 256.0 + / dcn_bw_ceil2( + v->byte_per_pixel_in_dety[k], + 1.0) + / v->meta_req_height_y; + v->meta_surface_width_y = dcn_bw_ceil2( + v->viewport_width[k] / v->no_of_dpp[i][j][k] + - 1.0, + v->meta_req_width_y) + v->meta_req_width_y; + v->meta_surface_height_y = dcn_bw_ceil2( + v->viewport_height[k] - 1.0, + v->meta_req_height_y) + + v->meta_req_height_y; + if (v->pte_enable == dcn_bw_yes) { + v->meta_pte_bytes_per_frame_y = + (dcn_bw_ceil2( + (v->meta_surface_width_y + * v->meta_surface_height_y + * dcn_bw_ceil2( + v->byte_per_pixel_in_dety[k], + 1.0) + / 256.0 + - 4096.0) + / 8.0 + / 4096.0, + 1.0) + 1) * 64.0; + } else { + v->meta_pte_bytes_per_frame_y = 0.0; + } + if (v->source_scan[k] == dcn_bw_hor) { + v->meta_row_bytes_y = + v->meta_surface_width_y + * v->meta_req_height_y + * dcn_bw_ceil2( + v->byte_per_pixel_in_dety[k], + 1.0) + / 256.0; + } else { + v->meta_row_bytes_y = + v->meta_surface_height_y + * v->meta_req_width_y + * dcn_bw_ceil2( + v->byte_per_pixel_in_dety[k], + 1.0) + / 256.0; + } + } else { + v->meta_pte_bytes_per_frame_y = 0.0; + v->meta_row_bytes_y = 0.0; + } + if (v->pte_enable == dcn_bw_yes) { + if (v->source_surface_mode[k] == dcn_bw_sw_linear) { + v->macro_tile_block_size_bytes_y = 256.0; + v->macro_tile_block_height_y = 1.0; + } else if (v->source_surface_mode[k] == dcn_bw_sw_4_kb_s + || v->source_surface_mode[k] + == dcn_bw_sw_4_kb_s_x + || v->source_surface_mode[k] + == dcn_bw_sw_4_kb_d + || v->source_surface_mode[k] + == dcn_bw_sw_4_kb_d_x) { + v->macro_tile_block_size_bytes_y = 4096.0; + v->macro_tile_block_height_y = 4.0 + * v->read256_block_height_y[k]; + } else if (v->source_surface_mode[k] == dcn_bw_sw_64_kb_s + || v->source_surface_mode[k] + == dcn_bw_sw_64_kb_s_t + || v->source_surface_mode[k] + == dcn_bw_sw_64_kb_s_x + || v->source_surface_mode[k] + == dcn_bw_sw_64_kb_d + || v->source_surface_mode[k] + == dcn_bw_sw_64_kb_d_t + || v->source_surface_mode[k] + == dcn_bw_sw_64_kb_d_x) { + v->macro_tile_block_size_bytes_y = 64.0 * 1024; + v->macro_tile_block_height_y = 16.0 + * v->read256_block_height_y[k]; + } else { + v->macro_tile_block_size_bytes_y = 256.0 * 1024; + v->macro_tile_block_height_y = 32.0 + * v->read256_block_height_y[k]; + } + if (v->macro_tile_block_size_bytes_y <= 65536.0) { + v->data_pte_req_height_y = + v->macro_tile_block_height_y; + } else { + v->data_pte_req_height_y = 16.0 + * v->read256_block_height_y[k]; + } + v->data_pte_req_width_y = + 4096.0 + / dcn_bw_ceil2( + v->byte_per_pixel_in_dety[k], + 1.0) + / v->data_pte_req_height_y + * 8; + if (v->source_surface_mode[k] == dcn_bw_sw_linear) { + v->dpte_bytes_per_row_y = + 64.0 + * (dcn_bw_ceil2( + (v->viewport_width[k] + / v->no_of_dpp[i][j][k] + * dcn_bw_min2( + 128.0, + dcn_bw_pow( + 2.0, + dcn_bw_floor2( + dcn_bw_log( + v->pte_buffer_size_in_requests + * v->data_pte_req_width_y + / (v->viewport_width[k] + / v->no_of_dpp[i][j][k]), + 2.0), + 1.0))) + - 1.0) + / v->data_pte_req_width_y, + 1.0) + + 1); + } else if (v->source_scan[k] == dcn_bw_hor) { + v->dpte_bytes_per_row_y = + 64.0 + * (dcn_bw_ceil2( + (v->viewport_width[k] + / v->no_of_dpp[i][j][k] + - 1.0) + / v->data_pte_req_width_y, + 1.0) + + 1); + } else { + v->dpte_bytes_per_row_y = + 64.0 + * (dcn_bw_ceil2( + (v->viewport_height[k] + - 1.0) + / v->data_pte_req_height_y, + 1.0) + + 1); + } + } else { + v->dpte_bytes_per_row_y = 0.0; + } + if ((v->source_pixel_format[k] != dcn_bw_rgb_sub_64 + && v->source_pixel_format[k] != dcn_bw_rgb_sub_32 + && v->source_pixel_format[k] != dcn_bw_rgb_sub_16)) { + if (v->dcc_enable[k] == dcn_bw_yes) { + v->meta_req_height_c = 8.0 + * v->read256_block_height_c[k]; + v->meta_req_width_c = + 64.0 * 256.0 + / dcn_bw_ceil2( + v->byte_per_pixel_in_detc[k], + 2.0) + / v->meta_req_height_c; + v->meta_surface_width_c = + dcn_bw_ceil2( + v->viewport_width[k] + / v->no_of_dpp[i][j][k] + / 2.0 + - 1.0, + v->meta_req_width_c) + + v->meta_req_width_c; + v->meta_surface_height_c = dcn_bw_ceil2( + v->viewport_height[k] / 2.0 - 1.0, + v->meta_req_height_c) + + v->meta_req_height_c; + if (v->pte_enable == dcn_bw_yes) { + v->meta_pte_bytes_per_frame_c = + (dcn_bw_ceil2( + (v->meta_surface_width_c + * v->meta_surface_height_c + * dcn_bw_ceil2( + v->byte_per_pixel_in_detc[k], + 2.0) + / 256.0 + - 4096.0) + / 8.0 + / 4096.0, + 1.0) + 1) + * 64.0; + } else { + v->meta_pte_bytes_per_frame_c = 0.0; + } + if (v->source_scan[k] == dcn_bw_hor) { + v->meta_row_bytes_c = + v->meta_surface_width_c + * v->meta_req_height_c + * dcn_bw_ceil2( + v->byte_per_pixel_in_detc[k], + 2.0) + / 256.0; + } else { + v->meta_row_bytes_c = + v->meta_surface_height_c + * v->meta_req_width_c + * dcn_bw_ceil2( + v->byte_per_pixel_in_detc[k], + 2.0) + / 256.0; + } + } else { + v->meta_pte_bytes_per_frame_c = 0.0; + v->meta_row_bytes_c = 0.0; + } + if (v->pte_enable == dcn_bw_yes) { + if (v->source_surface_mode[k] == dcn_bw_sw_linear) { + v->macro_tile_block_size_bytes_c = 256.0; + v->macro_tile_block_height_c = 1.0; + } else if (v->source_surface_mode[k] + == dcn_bw_sw_4_kb_s + || v->source_surface_mode[k] + == dcn_bw_sw_4_kb_s_x + || v->source_surface_mode[k] + == dcn_bw_sw_4_kb_d + || v->source_surface_mode[k] + == dcn_bw_sw_4_kb_d_x) { + v->macro_tile_block_size_bytes_c = 4096.0; + v->macro_tile_block_height_c = + 4.0 + * v->read256_block_height_c[k]; + } else if (v->source_surface_mode[k] + == dcn_bw_sw_64_kb_s + || v->source_surface_mode[k] + == dcn_bw_sw_64_kb_s_t + || v->source_surface_mode[k] + == dcn_bw_sw_64_kb_s_x + || v->source_surface_mode[k] + == dcn_bw_sw_64_kb_d + || v->source_surface_mode[k] + == dcn_bw_sw_64_kb_d_t + || v->source_surface_mode[k] + == dcn_bw_sw_64_kb_d_x) { + v->macro_tile_block_size_bytes_c = 64.0 + * 1024; + v->macro_tile_block_height_c = + 16.0 + * v->read256_block_height_c[k]; + } else { + v->macro_tile_block_size_bytes_c = 256.0 + * 1024; + v->macro_tile_block_height_c = + 32.0 + * v->read256_block_height_c[k]; + } + v->macro_tile_block_width_c = + v->macro_tile_block_size_bytes_c + / dcn_bw_ceil2( + v->byte_per_pixel_in_detc[k], + 2.0) + / v->macro_tile_block_height_c; + if (v->macro_tile_block_size_bytes_c <= 65536.0) { + v->data_pte_req_height_c = + v->macro_tile_block_height_c; + } else { + v->data_pte_req_height_c = + 16.0 + * v->read256_block_height_c[k]; + } + v->data_pte_req_width_c = + 4096.0 + / dcn_bw_ceil2( + v->byte_per_pixel_in_detc[k], + 2.0) + / v->data_pte_req_height_c + * 8; + if (v->source_surface_mode[k] == dcn_bw_sw_linear) { + v->dpte_bytes_per_row_c = + 64.0 + * (dcn_bw_ceil2( + (v->viewport_width[k] + / v->no_of_dpp[i][j][k] + / 2.0 + * dcn_bw_min2( + 128.0, + dcn_bw_pow( + 2.0, + dcn_bw_floor2( + dcn_bw_log( + v->pte_buffer_size_in_requests + * v->data_pte_req_width_c + / (v->viewport_width[k] + / v->no_of_dpp[i][j][k] + / 2.0), + 2.0), + 1.0))) + - 1.0) + / v->data_pte_req_width_c, + 1.0) + + 1); + } else if (v->source_scan[k] == dcn_bw_hor) { + v->dpte_bytes_per_row_c = + 64.0 + * (dcn_bw_ceil2( + (v->viewport_width[k] + / v->no_of_dpp[i][j][k] + / 2.0 + - 1.0) + / v->data_pte_req_width_c, + 1.0) + + 1); + } else { + v->dpte_bytes_per_row_c = + 64.0 + * (dcn_bw_ceil2( + (v->viewport_height[k] + / 2.0 + - 1.0) + / v->data_pte_req_height_c, + 1.0) + + 1); + } + } else { + v->dpte_bytes_per_row_c = 0.0; + } + } else { + v->dpte_bytes_per_row_c = 0.0; + v->meta_pte_bytes_per_frame_c = 0.0; + v->meta_row_bytes_c = 0.0; + } + v->dpte_bytes_per_row[k] = v->dpte_bytes_per_row_y + + v->dpte_bytes_per_row_c; + v->meta_pte_bytes_per_frame[k] = v->meta_pte_bytes_per_frame_y + + v->meta_pte_bytes_per_frame_c; + v->meta_row_bytes[k] = v->meta_row_bytes_y + v->meta_row_bytes_c; + v->v_init_y = (v->v_ratio[k] + v->vtaps[k] + 1.0 + + v->interlace_output[k] * 0.5 * v->v_ratio[k]) + / 2.0; + v->prefill_y[k] = dcn_bw_floor2(v->v_init_y, 1.0); + v->max_num_sw_y[k] = + dcn_bw_ceil2( + (v->prefill_y[k] - 1.0) + / v->swath_height_yper_state[i][j][k], + 1.0) + 1; + if (v->prefill_y[k] > 1.0) { + v->max_partial_sw_y = dcn_bw_mod( + (v->prefill_y[k] - 2.0), + v->swath_height_yper_state[i][j][k]); + } else { + v->max_partial_sw_y = + dcn_bw_mod( + (v->prefill_y[k] + + v->swath_height_yper_state[i][j][k] + - 2.0), + v->swath_height_yper_state[i][j][k]); + } + v->max_partial_sw_y = dcn_bw_max2(1.0, v->max_partial_sw_y); + v->prefetch_lines_y[k] = v->max_num_sw_y[k] + * v->swath_height_yper_state[i][j][k] + + v->max_partial_sw_y; + if ((v->source_pixel_format[k] != dcn_bw_rgb_sub_64 + && v->source_pixel_format[k] != dcn_bw_rgb_sub_32 + && v->source_pixel_format[k] != dcn_bw_rgb_sub_16)) { + v->v_init_c = (v->v_ratio[k] / 2.0 + v->vtaps[k] + 1.0 + + v->interlace_output[k] * 0.5 + * v->v_ratio[k] / 2.0) + / 2.0; + v->prefill_c[k] = dcn_bw_floor2(v->v_init_c, 1.0); + v->max_num_sw_c[k] = + dcn_bw_ceil2( + (v->prefill_c[k] - 1.0) + / v->swath_height_cper_state[i][j][k], + 1.0) + 1; + if (v->prefill_c[k] > 1.0) { + v->max_partial_sw_c = + dcn_bw_mod( + (v->prefill_c[k] + - 2.0), + v->swath_height_cper_state[i][j][k]); + } else { + v->max_partial_sw_c = + dcn_bw_mod( + (v->prefill_c[k] + + v->swath_height_cper_state[i][j][k] + - 2.0), + v->swath_height_cper_state[i][j][k]); + } + v->max_partial_sw_c = dcn_bw_max2(1.0, v->max_partial_sw_c); + v->prefetch_lines_c[k] = v->max_num_sw_c[k] + * v->swath_height_cper_state[i][j][k] + + v->max_partial_sw_c; + } else { + v->prefetch_lines_c[k] = 0.0; + } + v->dst_x_after_scaler = 90.0 * v->pixel_clock[k] + / (v->required_dispclk[i][j] / (j + 1)) + + 42.0 * v->pixel_clock[k] + / v->required_dispclk[i][j]; + if (v->no_of_dpp[i][j][k] > 1.0) { + v->dst_x_after_scaler = v->dst_x_after_scaler + + v->scaler_rec_out_width[k] / 2.0; + } + if (v->output_format[k] == dcn_bw_420) { + v->dst_y_after_scaler = 1.0; + } else { + v->dst_y_after_scaler = 0.0; + } + v->time_calc = 24.0 / v->projected_dcfclk_deep_sleep; + v->v_update_offset[k] = dcn_bw_ceil2(v->htotal[k] / 4.0, 1.0); + v->total_repeater_delay = v->max_inter_dcn_tile_repeaters + * (2.0 / (v->required_dispclk[i][j] / (j + 1)) + + 3.0 / v->required_dispclk[i][j]); + v->v_update_width[k] = (14.0 / v->projected_dcfclk_deep_sleep + + 12.0 / (v->required_dispclk[i][j] / (j + 1)) + + v->total_repeater_delay) * v->pixel_clock[k]; + v->v_ready_offset[k] = + dcn_bw_max2( + 150.0 + / (v->required_dispclk[i][j] + / (j + + 1)), + v->total_repeater_delay + + 20.0 + / v->projected_dcfclk_deep_sleep + + 10.0 + / (v->required_dispclk[i][j] + / (j + + 1))) + * v->pixel_clock[k]; + v->time_setup = (v->v_update_offset[k] + v->v_update_width[k] + + v->v_ready_offset[k]) / v->pixel_clock[k]; + v->extra_latency = + v->urgent_round_trip_and_out_of_order_latency_per_state[i] + + (v->total_number_of_active_dpp[i][j] + * v->pixel_chunk_size_in_kbyte + + v->total_number_of_dcc_active_dpp[i][j] + * v->meta_chunk_size) + * 1024.0 + / v->return_bw_per_state[i]; + if (v->pte_enable == dcn_bw_yes) { + v->extra_latency = v->extra_latency + + v->total_number_of_active_dpp[i][j] + * v->pte_chunk_size * 1024.0 + / v->return_bw_per_state[i]; + } + if (v->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one + == dcn_bw_yes) { + v->maximum_vstartup = v->vtotal[k] - v->vactive[k] - 1.0; + } else { + v->maximum_vstartup = v->v_sync_plus_back_porch[k] - 1.0; + } + v->line_times_for_prefetch[k] = v->maximum_vstartup + - v->urgent_latency + / (v->htotal[k] / v->pixel_clock[k]) + - (v->time_calc + v->time_setup) + / (v->htotal[k] / v->pixel_clock[k]) + - (v->dst_y_after_scaler + + v->dst_x_after_scaler + / v->htotal[k]); + v->line_times_for_prefetch[k] = dcn_bw_floor2( + 4.0 * (v->line_times_for_prefetch[k] + 0.125), + 1.0) / 4; + v->prefetch_bw[k] = + (v->meta_pte_bytes_per_frame[k] + + 2.0 * v->meta_row_bytes[k] + + 2.0 * v->dpte_bytes_per_row[k] + + v->prefetch_lines_y[k] + * v->swath_width_yper_state[i][j][k] + * dcn_bw_ceil2( + v->byte_per_pixel_in_dety[k], + 1.0) + + v->prefetch_lines_c[k] + * v->swath_width_yper_state[i][j][k] + / 2.0 + * dcn_bw_ceil2( + v->byte_per_pixel_in_detc[k], + 2.0)) + / (v->line_times_for_prefetch[k] + * v->htotal[k] + / v->pixel_clock[k]); + } + v->bw_available_for_immediate_flip = v->return_bw_per_state[i]; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + v->bw_available_for_immediate_flip = + v->bw_available_for_immediate_flip + - dcn_bw_max2( + v->read_bandwidth[k], + v->prefetch_bw[k]); + } + v->total_immediate_flip_bytes[k] = 0.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if ((v->source_pixel_format[k] != dcn_bw_yuv420_sub_8 + && v->source_pixel_format[k] != dcn_bw_yuv420_sub_10)) { + v->total_immediate_flip_bytes[k] = + v->total_immediate_flip_bytes[k] + + v->meta_pte_bytes_per_frame[k] + + v->meta_row_bytes[k] + + v->dpte_bytes_per_row[k]; + } + } + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->pte_enable == dcn_bw_yes && v->dcc_enable[k] == dcn_bw_yes) { + v->time_for_meta_pte_with_immediate_flip = + dcn_bw_max5( + v->meta_pte_bytes_per_frame[k] + / v->prefetch_bw[k], + v->meta_pte_bytes_per_frame[k] + * v->total_immediate_flip_bytes[k] + / (v->bw_available_for_immediate_flip + * (v->meta_pte_bytes_per_frame[k] + + v->meta_row_bytes[k] + + v->dpte_bytes_per_row[k])), + v->extra_latency, + v->urgent_latency, + v->htotal[k] + / v->pixel_clock[k] + / 4.0); + v->time_for_meta_pte_without_immediate_flip = dcn_bw_max3( + v->meta_pte_bytes_per_frame[k] + / v->prefetch_bw[k], + v->extra_latency, + v->htotal[k] / v->pixel_clock[k] / 4.0); + } else { + v->time_for_meta_pte_with_immediate_flip = v->htotal[k] + / v->pixel_clock[k] / 4.0; + v->time_for_meta_pte_without_immediate_flip = v->htotal[k] + / v->pixel_clock[k] / 4.0; + } + if (v->pte_enable == dcn_bw_yes || v->dcc_enable[k] == dcn_bw_yes) { + v->time_for_meta_and_dpte_row_with_immediate_flip = + dcn_bw_max5( + (v->meta_row_bytes[k] + + v->dpte_bytes_per_row[k]) + / v->prefetch_bw[k], + (v->meta_row_bytes[k] + + v->dpte_bytes_per_row[k]) + * v->total_immediate_flip_bytes[k] + / (v->bw_available_for_immediate_flip + * (v->meta_pte_bytes_per_frame[k] + + v->meta_row_bytes[k] + + v->dpte_bytes_per_row[k])), + v->htotal[k] + / v->pixel_clock[k] + - v->time_for_meta_pte_with_immediate_flip, + v->extra_latency, + 2.0 * v->urgent_latency); + v->time_for_meta_and_dpte_row_without_immediate_flip = + dcn_bw_max3( + (v->meta_row_bytes[k] + + v->dpte_bytes_per_row[k]) + / v->prefetch_bw[k], + v->htotal[k] + / v->pixel_clock[k] + - v->time_for_meta_pte_without_immediate_flip, + v->extra_latency); + } else { + v->time_for_meta_and_dpte_row_with_immediate_flip = + dcn_bw_max2( + v->htotal[k] + / v->pixel_clock[k] + - v->time_for_meta_pte_with_immediate_flip, + v->extra_latency + - v->time_for_meta_pte_with_immediate_flip); + v->time_for_meta_and_dpte_row_without_immediate_flip = + dcn_bw_max2( + v->htotal[k] + / v->pixel_clock[k] + - v->time_for_meta_pte_without_immediate_flip, + v->extra_latency + - v->time_for_meta_pte_without_immediate_flip); + } + v->lines_for_meta_pte_with_immediate_flip[k] = + dcn_bw_floor2( + 4.0 + * (v->time_for_meta_pte_with_immediate_flip + / (v->htotal[k] + / v->pixel_clock[k]) + + 0.125), + 1.0) / 4; + v->lines_for_meta_pte_without_immediate_flip[k] = + dcn_bw_floor2( + 4.0 + * (v->time_for_meta_pte_without_immediate_flip + / (v->htotal[k] + / v->pixel_clock[k]) + + 0.125), + 1.0) / 4; + v->lines_for_meta_and_dpte_row_with_immediate_flip[k] = + dcn_bw_floor2( + 4.0 + * (v->time_for_meta_and_dpte_row_with_immediate_flip + / (v->htotal[k] + / v->pixel_clock[k]) + + 0.125), + 1.0) / 4; + v->lines_for_meta_and_dpte_row_without_immediate_flip[k] = + dcn_bw_floor2( + 4.0 + * (v->time_for_meta_and_dpte_row_without_immediate_flip + / (v->htotal[k] + / v->pixel_clock[k]) + + 0.125), + 1.0) / 4; + v->line_times_to_request_prefetch_pixel_data_with_immediate_flip = + v->line_times_for_prefetch[k] + - v->lines_for_meta_pte_with_immediate_flip[k] + - v->lines_for_meta_and_dpte_row_with_immediate_flip[k]; + v->line_times_to_request_prefetch_pixel_data_without_immediate_flip = + v->line_times_for_prefetch[k] + - v->lines_for_meta_pte_without_immediate_flip[k] + - v->lines_for_meta_and_dpte_row_without_immediate_flip[k]; + if (v->line_times_to_request_prefetch_pixel_data_with_immediate_flip + > 0.0) { + v->v_ratio_pre_ywith_immediate_flip[i][j][k] = + v->prefetch_lines_y[k] + / v->line_times_to_request_prefetch_pixel_data_with_immediate_flip; + if ((v->swath_height_yper_state[i][j][k] > 4.0)) { + if (v->line_times_to_request_prefetch_pixel_data_with_immediate_flip + - (v->prefill_y[k] - 3.0) / 2.0 + > 0.0) { + v->v_ratio_pre_ywith_immediate_flip[i][j][k] = + dcn_bw_max2( + v->v_ratio_pre_ywith_immediate_flip[i][j][k], + (v->max_num_sw_y[k] + * v->swath_height_yper_state[i][j][k]) + / (v->line_times_to_request_prefetch_pixel_data_with_immediate_flip + - (v->prefill_y[k] + - 3.0) + / 2.0)); + } else { + v->v_ratio_pre_ywith_immediate_flip[i][j][k] = + 999999.0; + } + } + v->v_ratio_pre_cwith_immediate_flip[i][j][k] = + v->prefetch_lines_c[k] + / v->line_times_to_request_prefetch_pixel_data_with_immediate_flip; + if ((v->swath_height_cper_state[i][j][k] > 4.0)) { + if (v->line_times_to_request_prefetch_pixel_data_with_immediate_flip + - (v->prefill_c[k] - 3.0) / 2.0 + > 0.0) { + v->v_ratio_pre_cwith_immediate_flip[i][j][k] = + dcn_bw_max2( + v->v_ratio_pre_cwith_immediate_flip[i][j][k], + (v->max_num_sw_c[k] + * v->swath_height_cper_state[i][j][k]) + / (v->line_times_to_request_prefetch_pixel_data_with_immediate_flip + - (v->prefill_c[k] + - 3.0) + / 2.0)); + } else { + v->v_ratio_pre_cwith_immediate_flip[i][j][k] = + 999999.0; + } + } + v->required_prefetch_pixel_data_bw_with_immediate_flip[i][j][k] = + v->no_of_dpp[i][j][k] + * (v->prefetch_lines_y[k] + / v->line_times_to_request_prefetch_pixel_data_with_immediate_flip + * dcn_bw_ceil2( + v->byte_per_pixel_in_dety[k], + 1.0) + + v->prefetch_lines_c[k] + / v->line_times_to_request_prefetch_pixel_data_with_immediate_flip + * dcn_bw_ceil2( + v->byte_per_pixel_in_detc[k], + 2.0) + / 2.0) + * v->swath_width_yper_state[i][j][k] + / (v->htotal[k] + / v->pixel_clock[k]); + } else { + v->v_ratio_pre_ywith_immediate_flip[i][j][k] = 999999.0; + v->v_ratio_pre_cwith_immediate_flip[i][j][k] = 999999.0; + v->required_prefetch_pixel_data_bw_with_immediate_flip[i][j][k] = + 999999.0; + } + if (v->line_times_to_request_prefetch_pixel_data_without_immediate_flip + > 0.0) { + v->v_ratio_pre_ywithout_immediate_flip[i][j][k] = + v->prefetch_lines_y[k] + / v->line_times_to_request_prefetch_pixel_data_without_immediate_flip; + if ((v->swath_height_yper_state[i][j][k] > 4.0)) { + if (v->line_times_to_request_prefetch_pixel_data_without_immediate_flip + - (v->prefill_y[k] - 3.0) / 2.0 + > 0.0) { + v->v_ratio_pre_ywithout_immediate_flip[i][j][k] = + dcn_bw_max2( + v->v_ratio_pre_ywithout_immediate_flip[i][j][k], + (v->max_num_sw_y[k] + * v->swath_height_yper_state[i][j][k]) + / (v->line_times_to_request_prefetch_pixel_data_without_immediate_flip + - (v->prefill_y[k] + - 3.0) + / 2.0)); + } else { + v->v_ratio_pre_ywithout_immediate_flip[i][j][k] = + 999999.0; + } + } + v->v_ratio_pre_cwithout_immediate_flip[i][j][k] = + v->prefetch_lines_c[k] + / v->line_times_to_request_prefetch_pixel_data_without_immediate_flip; + if ((v->swath_height_cper_state[i][j][k] > 4.0)) { + if (v->line_times_to_request_prefetch_pixel_data_without_immediate_flip + - (v->prefill_c[k] - 3.0) / 2.0 + > 0.0) { + v->v_ratio_pre_cwithout_immediate_flip[i][j][k] = + dcn_bw_max2( + v->v_ratio_pre_cwithout_immediate_flip[i][j][k], + (v->max_num_sw_c[k] + * v->swath_height_cper_state[i][j][k]) + / (v->line_times_to_request_prefetch_pixel_data_without_immediate_flip + - (v->prefill_c[k] + - 3.0) + / 2.0)); + } else { + v->v_ratio_pre_cwithout_immediate_flip[i][j][k] = + 999999.0; + } + } + v->required_prefetch_pixel_data_bw_without_immediate_flip[i][j][k] = + v->no_of_dpp[i][j][k] + * (v->prefetch_lines_y[k] + / v->line_times_to_request_prefetch_pixel_data_without_immediate_flip + * dcn_bw_ceil2( + v->byte_per_pixel_in_dety[k], + 1.0) + + v->prefetch_lines_c[k] + / v->line_times_to_request_prefetch_pixel_data_without_immediate_flip + * dcn_bw_ceil2( + v->byte_per_pixel_in_detc[k], + 2.0) + / 2.0) + * v->swath_width_yper_state[i][j][k] + / (v->htotal[k] + / v->pixel_clock[k]); + } else { + v->v_ratio_pre_ywithout_immediate_flip[i][j][k] = 999999.0; + v->v_ratio_pre_cwithout_immediate_flip[i][j][k] = 999999.0; + v->required_prefetch_pixel_data_bw_without_immediate_flip[i][j][k] = + 999999.0; + } + } + v->maximum_read_bandwidth_with_prefetch_with_immediate_flip = 0.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if ((v->source_pixel_format[k] != dcn_bw_yuv420_sub_8 + && v->source_pixel_format[k] != dcn_bw_yuv420_sub_10)) { + v->maximum_read_bandwidth_with_prefetch_with_immediate_flip = + v->maximum_read_bandwidth_with_prefetch_with_immediate_flip + + dcn_bw_max2( + v->read_bandwidth[k], + v->required_prefetch_pixel_data_bw_with_immediate_flip[i][j][k]) + + dcn_bw_max2( + v->meta_pte_bytes_per_frame[k] + / (v->lines_for_meta_pte_with_immediate_flip[k] + * v->htotal[k] + / v->pixel_clock[k]), + (v->meta_row_bytes[k] + + v->dpte_bytes_per_row[k]) + / (v->lines_for_meta_and_dpte_row_with_immediate_flip[k] + * v->htotal[k] + / v->pixel_clock[k])); + } else { + v->maximum_read_bandwidth_with_prefetch_with_immediate_flip = + v->maximum_read_bandwidth_with_prefetch_with_immediate_flip + + dcn_bw_max2( + v->read_bandwidth[k], + v->required_prefetch_pixel_data_bw_without_immediate_flip[i][j][k]); + } + } + v->maximum_read_bandwidth_with_prefetch_without_immediate_flip = 0.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + v->maximum_read_bandwidth_with_prefetch_without_immediate_flip = + v->maximum_read_bandwidth_with_prefetch_without_immediate_flip + + dcn_bw_max2( + v->read_bandwidth[k], + v->required_prefetch_pixel_data_bw_without_immediate_flip[i][j][k]); + } + v->prefetch_supported_with_immediate_flip[i][j] = dcn_bw_yes; + if (v->maximum_read_bandwidth_with_prefetch_with_immediate_flip + > v->return_bw_per_state[i]) { + v->prefetch_supported_with_immediate_flip[i][j] = dcn_bw_no; + } + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->line_times_for_prefetch[k] < 2.0 + || v->lines_for_meta_pte_with_immediate_flip[k] + >= 8.0 + || v->lines_for_meta_and_dpte_row_with_immediate_flip[k] + >= 16.0) { + v->prefetch_supported_with_immediate_flip[i][j] = dcn_bw_no; + } + } + v->prefetch_supported_without_immediate_flip[i][j] = dcn_bw_yes; + if (v->maximum_read_bandwidth_with_prefetch_without_immediate_flip + > v->return_bw_per_state[i]) { + v->prefetch_supported_without_immediate_flip[i][j] = dcn_bw_no; + } + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->line_times_for_prefetch[k] < 2.0 + || v->lines_for_meta_pte_without_immediate_flip[k] + >= 8.0 + || v->lines_for_meta_and_dpte_row_without_immediate_flip[k] + >= 16.0) { + v->prefetch_supported_without_immediate_flip[i][j] = + dcn_bw_no; + } + } + } + } + for (i = 0; i <= number_of_states_plus_one; i++) { + for (j = 0; j <= 1; j++) { + v->v_ratio_in_prefetch_supported_with_immediate_flip[i][j] = dcn_bw_yes; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if ((((v->source_pixel_format[k] != dcn_bw_yuv420_sub_8 + && v->source_pixel_format[k] != dcn_bw_yuv420_sub_10) + && (v->v_ratio_pre_ywith_immediate_flip[i][j][k] + > 4.0 + || v->v_ratio_pre_cwith_immediate_flip[i][j][k] + > 4.0)) + || ((v->source_pixel_format[k] + == dcn_bw_yuv420_sub_8 + || v->source_pixel_format[k] + == dcn_bw_yuv420_sub_10) + && (v->v_ratio_pre_ywithout_immediate_flip[i][j][k] + > 4.0 + || v->v_ratio_pre_cwithout_immediate_flip[i][j][k] + > 4.0)))) { + v->v_ratio_in_prefetch_supported_with_immediate_flip[i][j] = + dcn_bw_no; + } + } + v->v_ratio_in_prefetch_supported_without_immediate_flip[i][j] = dcn_bw_yes; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if ((v->v_ratio_pre_ywithout_immediate_flip[i][j][k] > 4.0 + || v->v_ratio_pre_cwithout_immediate_flip[i][j][k] + > 4.0)) { + v->v_ratio_in_prefetch_supported_without_immediate_flip[i][j] = + dcn_bw_no; + } + } + } + } + /*mode support, voltage state and soc configuration*/ + + for (i = number_of_states_plus_one; i >= 0; i--) { + for (j = 0; j <= 1; j++) { + if (v->scale_ratio_support == dcn_bw_yes + && v->source_format_pixel_and_scan_support == dcn_bw_yes + && v->viewport_size_support == dcn_bw_yes + && v->bandwidth_support[i] == dcn_bw_yes + && v->dio_support[i] == dcn_bw_yes + && v->urgent_latency_support[i][j] == dcn_bw_yes + && v->rob_support[i] == dcn_bw_yes + && v->dispclk_dppclk_support[i][j] == dcn_bw_yes + && v->total_available_pipes_support[i][j] == dcn_bw_yes + && v->total_available_writeback_support == dcn_bw_yes + && v->writeback_latency_support == dcn_bw_yes) { + if (v->prefetch_supported_with_immediate_flip[i][j] == dcn_bw_yes + && v->v_ratio_in_prefetch_supported_with_immediate_flip[i][j] + == dcn_bw_yes) { + v->mode_support_with_immediate_flip[i][j] = dcn_bw_yes; + } else { + v->mode_support_with_immediate_flip[i][j] = dcn_bw_no; + } + if (v->prefetch_supported_without_immediate_flip[i][j] == dcn_bw_yes + && v->v_ratio_in_prefetch_supported_without_immediate_flip[i][j] + == dcn_bw_yes) { + v->mode_support_without_immediate_flip[i][j] = dcn_bw_yes; + } else { + v->mode_support_without_immediate_flip[i][j] = dcn_bw_no; + } + } else { + v->mode_support_with_immediate_flip[i][j] = dcn_bw_no; + v->mode_support_without_immediate_flip[i][j] = dcn_bw_no; + } + } + } + for (i = number_of_states_plus_one; i >= 0; i--) { + if ((i == number_of_states_plus_one + || v->mode_support_with_immediate_flip[i][1] == dcn_bw_yes + || v->mode_support_with_immediate_flip[i][0] == dcn_bw_yes) + && i >= v->voltage_override_level) { + v->voltage_level_with_immediate_flip = i; + } + } + for (i = number_of_states_plus_one; i >= 0; i--) { + if ((i == number_of_states_plus_one + || v->mode_support_without_immediate_flip[i][1] == dcn_bw_yes + || v->mode_support_without_immediate_flip[i][0] == dcn_bw_yes) + && i >= v->voltage_override_level) { + v->voltage_level_without_immediate_flip = i; + } + } + if (v->voltage_level_with_immediate_flip == number_of_states_plus_one) { + v->immediate_flip_supported = dcn_bw_no; + v->voltage_level = v->voltage_level_without_immediate_flip; + } else { + v->immediate_flip_supported = dcn_bw_yes; + v->voltage_level = v->voltage_level_with_immediate_flip; + } + v->dcfclk = v->dcfclk_per_state[v->voltage_level]; + v->fabric_and_dram_bandwidth = v->fabric_and_dram_bandwidth_per_state[v->voltage_level]; + for (j = 0; j <= 1; j++) { + v->required_dispclk_per_ratio[j] = v->required_dispclk[v->voltage_level][j]; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + v->dpp_per_plane_per_ratio[j][k] = v->no_of_dpp[v->voltage_level][j][k]; + } + v->dispclk_dppclk_support_per_ratio[j] = + v->dispclk_dppclk_support[v->voltage_level][j]; + } + v->max_phyclk = v->phyclk_per_state[v->voltage_level]; +} +void display_pipe_configuration(struct dcn_bw_internal_vars *v) +{ + int j, k; + /*display pipe configuration*/ + + for (j = 0; j <= 1; j++) { + v->total_number_of_active_dpp_per_ratio[j] = 0.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + v->total_number_of_active_dpp_per_ratio[j] = + v->total_number_of_active_dpp_per_ratio[j] + + v->dpp_per_plane_per_ratio[j][k]; + } + } + if ((v->dispclk_dppclk_support_per_ratio[0] == dcn_bw_yes + && v->dispclk_dppclk_support_per_ratio[1] == dcn_bw_no) + || (v->dispclk_dppclk_support_per_ratio[0] + == v->dispclk_dppclk_support_per_ratio[1] + && (v->total_number_of_active_dpp_per_ratio[0] + < v->total_number_of_active_dpp_per_ratio[1] + || (((v->total_number_of_active_dpp_per_ratio[0] + == v->total_number_of_active_dpp_per_ratio[1]) + && v->required_dispclk_per_ratio[0] + <= 0.5 + * v->required_dispclk_per_ratio[1]))))) { + v->dispclk_dppclk_ratio = 1; + v->final_error_message = v->error_message[0]; + } else { + v->dispclk_dppclk_ratio = 2; + v->final_error_message = v->error_message[1]; + } + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + v->dpp_per_plane[k] = v->dpp_per_plane_per_ratio[v->dispclk_dppclk_ratio - 1][k]; + } + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->source_pixel_format[k] == dcn_bw_rgb_sub_64) { + v->byte_per_pix_dety = 8.0; + v->byte_per_pix_detc = 0.0; + } else if (v->source_pixel_format[k] == dcn_bw_rgb_sub_32) { + v->byte_per_pix_dety = 4.0; + v->byte_per_pix_detc = 0.0; + } else if (v->source_pixel_format[k] == dcn_bw_rgb_sub_16) { + v->byte_per_pix_dety = 2.0; + v->byte_per_pix_detc = 0.0; + } else if (v->source_pixel_format[k] == dcn_bw_yuv420_sub_8) { + v->byte_per_pix_dety = 1.0; + v->byte_per_pix_detc = 2.0; + } else { + v->byte_per_pix_dety = 4.0f / 3; + v->byte_per_pix_detc = 8.0f / 3; + } + if ((v->source_pixel_format[k] == dcn_bw_rgb_sub_64 + || v->source_pixel_format[k] == dcn_bw_rgb_sub_32 + || v->source_pixel_format[k] == dcn_bw_rgb_sub_16)) { + if (v->source_surface_mode[k] == dcn_bw_sw_linear) { + v->read256_bytes_block_height_y = 1.0; + } else if (v->source_pixel_format[k] == dcn_bw_rgb_sub_64) { + v->read256_bytes_block_height_y = 4.0; + } else { + v->read256_bytes_block_height_y = 8.0; + } + v->read256_bytes_block_width_y = 256.0 / dcn_bw_ceil2(v->byte_per_pix_dety, 1.0) + / v->read256_bytes_block_height_y; + v->read256_bytes_block_height_c = 0.0; + v->read256_bytes_block_width_c = 0.0; + } else { + if (v->source_surface_mode[k] == dcn_bw_sw_linear) { + v->read256_bytes_block_height_y = 1.0; + v->read256_bytes_block_height_c = 1.0; + } else if (v->source_pixel_format[k] == dcn_bw_yuv420_sub_8) { + v->read256_bytes_block_height_y = 16.0; + v->read256_bytes_block_height_c = 8.0; + } else { + v->read256_bytes_block_height_y = 8.0; + v->read256_bytes_block_height_c = 8.0; + } + v->read256_bytes_block_width_y = 256.0 / dcn_bw_ceil2(v->byte_per_pix_dety, 1.0) + / v->read256_bytes_block_height_y; + v->read256_bytes_block_width_c = 256.0 / dcn_bw_ceil2(v->byte_per_pix_detc, 2.0) + / v->read256_bytes_block_height_c; + } + if (v->source_scan[k] == dcn_bw_hor) { + v->maximum_swath_height_y = v->read256_bytes_block_height_y; + v->maximum_swath_height_c = v->read256_bytes_block_height_c; + } else { + v->maximum_swath_height_y = v->read256_bytes_block_width_y; + v->maximum_swath_height_c = v->read256_bytes_block_width_c; + } + if ((v->source_pixel_format[k] == dcn_bw_rgb_sub_64 + || v->source_pixel_format[k] == dcn_bw_rgb_sub_32 + || v->source_pixel_format[k] == dcn_bw_rgb_sub_16)) { + if (v->source_surface_mode[k] == dcn_bw_sw_linear + || (v->source_pixel_format[k] == dcn_bw_rgb_sub_64 + && (v->source_surface_mode[k] + == dcn_bw_sw_4_kb_s + || v->source_surface_mode[k] + == dcn_bw_sw_4_kb_s_x + || v->source_surface_mode[k] + == dcn_bw_sw_64_kb_s + || v->source_surface_mode[k] + == dcn_bw_sw_64_kb_s_t + || v->source_surface_mode[k] + == dcn_bw_sw_64_kb_s_x + || v->source_surface_mode[k] + == dcn_bw_sw_var_s + || v->source_surface_mode[k] + == dcn_bw_sw_var_s_x) + && v->source_scan[k] == dcn_bw_hor)) { + v->minimum_swath_height_y = v->maximum_swath_height_y; + } else { + v->minimum_swath_height_y = v->maximum_swath_height_y / 2.0; + } + v->minimum_swath_height_c = v->maximum_swath_height_c; + } else { + if (v->source_surface_mode[k] == dcn_bw_sw_linear) { + v->minimum_swath_height_y = v->maximum_swath_height_y; + v->minimum_swath_height_c = v->maximum_swath_height_c; + } else if (v->source_pixel_format[k] == dcn_bw_yuv420_sub_8 + && v->source_scan[k] == dcn_bw_hor) { + v->minimum_swath_height_y = v->maximum_swath_height_y / 2.0; + if (v->bug_forcing_luma_and_chroma_request_to_same_size_fixed + == dcn_bw_yes) { + v->minimum_swath_height_c = v->maximum_swath_height_c; + } else { + v->minimum_swath_height_c = v->maximum_swath_height_c / 2.0; + } + } else if (v->source_pixel_format[k] == dcn_bw_yuv420_sub_10 + && v->source_scan[k] == dcn_bw_hor) { + v->minimum_swath_height_c = v->maximum_swath_height_c / 2.0; + if (v->bug_forcing_luma_and_chroma_request_to_same_size_fixed + == dcn_bw_yes) { + v->minimum_swath_height_y = v->maximum_swath_height_y; + } else { + v->minimum_swath_height_y = v->maximum_swath_height_y / 2.0; + } + } else { + v->minimum_swath_height_y = v->maximum_swath_height_y; + v->minimum_swath_height_c = v->maximum_swath_height_c; + } + } + if (v->source_scan[k] == dcn_bw_hor) { + v->swath_width = v->viewport_width[k] / v->dpp_per_plane[k]; + } else { + v->swath_width = v->viewport_height[k] / v->dpp_per_plane[k]; + } + v->swath_width_granularity_y = 256.0 / dcn_bw_ceil2(v->byte_per_pix_dety, 1.0) + / v->maximum_swath_height_y; + v->rounded_up_max_swath_size_bytes_y = (dcn_bw_ceil2( + v->swath_width - 1.0, + v->swath_width_granularity_y) + v->swath_width_granularity_y) + * v->byte_per_pix_dety * v->maximum_swath_height_y; + if (v->source_pixel_format[k] == dcn_bw_yuv420_sub_10) { + v->rounded_up_max_swath_size_bytes_y = dcn_bw_ceil2( + v->rounded_up_max_swath_size_bytes_y, + 256.0) + 256; + } + if (v->maximum_swath_height_c > 0.0) { + v->swath_width_granularity_c = 256.0 / dcn_bw_ceil2(v->byte_per_pix_detc, 2.0) + / v->maximum_swath_height_c; + } + v->rounded_up_max_swath_size_bytes_c = (dcn_bw_ceil2( + v->swath_width / 2.0 - 1.0, + v->swath_width_granularity_c) + v->swath_width_granularity_c) + * v->byte_per_pix_detc * v->maximum_swath_height_c; + if (v->source_pixel_format[k] == dcn_bw_yuv420_sub_10) { + v->rounded_up_max_swath_size_bytes_c = dcn_bw_ceil2( + v->rounded_up_max_swath_size_bytes_c, + 256.0) + 256; + } + if (v->rounded_up_max_swath_size_bytes_y + v->rounded_up_max_swath_size_bytes_c + <= v->det_buffer_size_in_kbyte * 1024.0 / 2.0) { + v->swath_height_y[k] = v->maximum_swath_height_y; + v->swath_height_c[k] = v->maximum_swath_height_c; + } else { + v->swath_height_y[k] = v->minimum_swath_height_y; + v->swath_height_c[k] = v->minimum_swath_height_c; + } + if (v->swath_height_c[k] == 0.0) { + v->det_buffer_size_y[k] = v->det_buffer_size_in_kbyte * 1024.0; + v->det_buffer_size_c[k] = 0.0; + } else if (v->swath_height_y[k] <= v->swath_height_c[k]) { + v->det_buffer_size_y[k] = v->det_buffer_size_in_kbyte * 1024.0 / 2.0; + v->det_buffer_size_c[k] = v->det_buffer_size_in_kbyte * 1024.0 / 2.0; + } else { + v->det_buffer_size_y[k] = v->det_buffer_size_in_kbyte * 1024.0 * 2.0 / 3.0; + v->det_buffer_size_c[k] = v->det_buffer_size_in_kbyte * 1024.0 / 3.0; + } + } +} +void dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation( + struct dcn_bw_internal_vars *v) +{ + int k; + /*dispclk and dppclk calculation*/ + + v->dispclk_with_ramping = 0.0; + v->dispclk_without_ramping = 0.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->h_ratio[k] > 1.0) { + v->pscl_throughput[k] = dcn_bw_min2( + v->max_dchub_topscl_throughput, + v->max_pscl_tolb_throughput * v->h_ratio[k] + / dcn_bw_ceil2(v->htaps[k] / 6.0, 1.0)); + } else { + v->pscl_throughput[k] = dcn_bw_min2( + v->max_dchub_topscl_throughput, + v->max_pscl_tolb_throughput); + } + v->dppclk_using_single_dpp_luma = v->pixel_clock[k] + * dcn_bw_max3( + v->vtaps[k] / 6.0 * dcn_bw_min2(1.0, v->h_ratio[k]), + v->h_ratio[k] * v->v_ratio[k] + / v->pscl_throughput[k], + 1.0); + if ((v->source_pixel_format[k] != dcn_bw_yuv420_sub_8 + && v->source_pixel_format[k] != dcn_bw_yuv420_sub_10)) { + v->pscl_throughput_chroma[k] = 0.0; + v->dppclk_using_single_dpp = v->dppclk_using_single_dpp_luma; + } else { + if (v->h_ratio[k] > 1.0) { + v->pscl_throughput_chroma[k] = + dcn_bw_min2( + v->max_dchub_topscl_throughput, + v->max_pscl_tolb_throughput + * v->h_ratio[k] + / 2.0 + / dcn_bw_ceil2( + v->hta_pschroma[k] + / 6.0, + 1.0)); + } else { + v->pscl_throughput_chroma[k] = dcn_bw_min2( + v->max_dchub_topscl_throughput, + v->max_pscl_tolb_throughput); + } + v->dppclk_using_single_dpp_chroma = + v->pixel_clock[k] + * dcn_bw_max3( + v->vta_pschroma[k] / 6.0 + * dcn_bw_min2( + 1.0, + v->h_ratio[k] + / 2.0), + v->h_ratio[k] + * v->v_ratio[k] + / 4.0 + / v->pscl_throughput_chroma[k], + 1.0); + v->dppclk_using_single_dpp = dcn_bw_max2( + v->dppclk_using_single_dpp_luma, + v->dppclk_using_single_dpp_chroma); + } + if (v->odm_capable == dcn_bw_yes) { + v->dispclk_with_ramping = + dcn_bw_max2( + v->dispclk_with_ramping, + dcn_bw_max2( + v->dppclk_using_single_dpp + / v->dpp_per_plane[k] + * v->dispclk_dppclk_ratio, + v->pixel_clock[k] + / v->dpp_per_plane[k]) + * (1.0 + + v->downspreading + / 100.0) + * (1.0 + + v->dispclk_ramping_margin + / 100.0)); + v->dispclk_without_ramping = dcn_bw_max2( + v->dispclk_without_ramping, + dcn_bw_max2( + v->dppclk_using_single_dpp + / v->dpp_per_plane[k] + * v->dispclk_dppclk_ratio, + v->pixel_clock[k] / v->dpp_per_plane[k]) + * (1.0 + v->downspreading / 100.0)); + } else { + v->dispclk_with_ramping = + dcn_bw_max2( + v->dispclk_with_ramping, + dcn_bw_max2( + v->dppclk_using_single_dpp + / v->dpp_per_plane[k] + * v->dispclk_dppclk_ratio, + v->pixel_clock[k]) + * (1.0 + + v->downspreading + / 100.0) + * (1.0 + + v->dispclk_ramping_margin + / 100.0)); + v->dispclk_without_ramping = dcn_bw_max2( + v->dispclk_without_ramping, + dcn_bw_max2( + v->dppclk_using_single_dpp + / v->dpp_per_plane[k] + * v->dispclk_dppclk_ratio, + v->pixel_clock[k]) + * (1.0 + v->downspreading / 100.0)); + } + } + if (v->dispclk_without_ramping > v->max_dispclk[number_of_states]) { + v->dispclk = v->dispclk_without_ramping; + } else if (v->dispclk_with_ramping > v->max_dispclk[number_of_states]) { + v->dispclk = v->max_dispclk[number_of_states]; + } else { + v->dispclk = v->dispclk_with_ramping; + } + v->dppclk = v->dispclk / v->dispclk_dppclk_ratio; + /*urgent watermark*/ + + v->return_bandwidth_to_dcn = dcn_bw_min2( + v->return_bus_width * v->dcfclk, + v->fabric_and_dram_bandwidth * 1000.0 + * v->percent_of_ideal_drambw_received_after_urg_latency + / 100.0); + v->dcc_enabled_any_plane = dcn_bw_no; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->dcc_enable[k] == dcn_bw_yes) { + v->dcc_enabled_any_plane = dcn_bw_yes; + } + } + v->return_bw = v->return_bandwidth_to_dcn; + if (v->dcc_enabled_any_plane == dcn_bw_yes + && v->return_bandwidth_to_dcn > v->dcfclk * v->return_bus_width / 4.0) { + v->return_bw = + dcn_bw_min2( + v->return_bw, + v->return_bandwidth_to_dcn * 4.0 + * (1.0 + - v->urgent_latency + / ((v->rob_buffer_size_in_kbyte + - v->pixel_chunk_size_in_kbyte) + * 1024.0 + / (v->return_bandwidth_to_dcn + - v->dcfclk + * v->return_bus_width + / 4.0) + + v->urgent_latency))); + } + v->critical_compression = 2.0 * v->return_bus_width * v->dcfclk * v->urgent_latency + / (v->return_bandwidth_to_dcn * v->urgent_latency + + (v->rob_buffer_size_in_kbyte + - v->pixel_chunk_size_in_kbyte) * 1024.0); + if (v->dcc_enabled_any_plane == dcn_bw_yes && v->critical_compression > 1.0 + && v->critical_compression < 4.0) { + v->return_bw = + dcn_bw_min2( + v->return_bw, + dcn_bw_pow( + 4.0 * v->return_bandwidth_to_dcn + * (v->rob_buffer_size_in_kbyte + - v->pixel_chunk_size_in_kbyte) + * 1024.0 + * v->return_bus_width + * v->dcfclk + * v->urgent_latency + / (v->return_bandwidth_to_dcn + * v->urgent_latency + + (v->rob_buffer_size_in_kbyte + - v->pixel_chunk_size_in_kbyte) + * 1024.0), + 2)); + } + v->return_bandwidth_to_dcn = dcn_bw_min2( + v->return_bus_width * v->dcfclk, + v->fabric_and_dram_bandwidth * 1000.0); + if (v->dcc_enabled_any_plane == dcn_bw_yes + && v->return_bandwidth_to_dcn > v->dcfclk * v->return_bus_width / 4.0) { + v->return_bw = + dcn_bw_min2( + v->return_bw, + v->return_bandwidth_to_dcn * 4.0 + * (1.0 + - v->urgent_latency + / ((v->rob_buffer_size_in_kbyte + - v->pixel_chunk_size_in_kbyte) + * 1024.0 + / (v->return_bandwidth_to_dcn + - v->dcfclk + * v->return_bus_width + / 4.0) + + v->urgent_latency))); + } + v->critical_compression = 2.0 * v->return_bus_width * v->dcfclk * v->urgent_latency + / (v->return_bandwidth_to_dcn * v->urgent_latency + + (v->rob_buffer_size_in_kbyte + - v->pixel_chunk_size_in_kbyte) * 1024.0); + if (v->dcc_enabled_any_plane == dcn_bw_yes && v->critical_compression > 1.0 + && v->critical_compression < 4.0) { + v->return_bw = + dcn_bw_min2( + v->return_bw, + dcn_bw_pow( + 4.0 * v->return_bandwidth_to_dcn + * (v->rob_buffer_size_in_kbyte + - v->pixel_chunk_size_in_kbyte) + * 1024.0 + * v->return_bus_width + * v->dcfclk + * v->urgent_latency + / (v->return_bandwidth_to_dcn + * v->urgent_latency + + (v->rob_buffer_size_in_kbyte + - v->pixel_chunk_size_in_kbyte) + * 1024.0), + 2)); + } + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->source_scan[k] == dcn_bw_hor) { + v->swath_width_y[k] = v->viewport_width[k] / v->dpp_per_plane[k]; + } else { + v->swath_width_y[k] = v->viewport_height[k] / v->dpp_per_plane[k]; + } + } + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->source_pixel_format[k] == dcn_bw_rgb_sub_64) { + v->byte_per_pixel_dety[k] = 8.0; + v->byte_per_pixel_detc[k] = 0.0; + } else if (v->source_pixel_format[k] == dcn_bw_rgb_sub_32) { + v->byte_per_pixel_dety[k] = 4.0; + v->byte_per_pixel_detc[k] = 0.0; + } else if (v->source_pixel_format[k] == dcn_bw_rgb_sub_16) { + v->byte_per_pixel_dety[k] = 2.0; + v->byte_per_pixel_detc[k] = 0.0; + } else if (v->source_pixel_format[k] == dcn_bw_yuv420_sub_8) { + v->byte_per_pixel_dety[k] = 1.0; + v->byte_per_pixel_detc[k] = 2.0; + } else { + v->byte_per_pixel_dety[k] = 4.0f / 3; + v->byte_per_pixel_detc[k] = 8.0f / 3; + } + } + v->total_data_read_bandwidth = 0.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + v->read_bandwidth_plane_luma[k] = v->swath_width_y[k] * v->dpp_per_plane[k] + * dcn_bw_ceil2(v->byte_per_pixel_dety[k], 1.0) + / (v->htotal[k] / v->pixel_clock[k]) * v->v_ratio[k]; + v->read_bandwidth_plane_chroma[k] = v->swath_width_y[k] / 2.0 * v->dpp_per_plane[k] + * dcn_bw_ceil2(v->byte_per_pixel_detc[k], 2.0) + / (v->htotal[k] / v->pixel_clock[k]) * v->v_ratio[k] / 2.0; + v->total_data_read_bandwidth = v->total_data_read_bandwidth + + v->read_bandwidth_plane_luma[k] + + v->read_bandwidth_plane_chroma[k]; + } + v->total_active_dpp = 0.0; + v->total_dcc_active_dpp = 0.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + v->total_active_dpp = v->total_active_dpp + v->dpp_per_plane[k]; + if (v->dcc_enable[k] == dcn_bw_yes) { + v->total_dcc_active_dpp = v->total_dcc_active_dpp + v->dpp_per_plane[k]; + } + } + v->urgent_round_trip_and_out_of_order_latency = (v->round_trip_ping_latency_cycles + 32.0) + / v->dcfclk + + v->urgent_out_of_order_return_per_channel * v->number_of_channels + / v->return_bw; + v->last_pixel_of_line_extra_watermark = 0.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->v_ratio[k] <= 1.0) { + v->display_pipe_line_delivery_time_luma[k] = v->swath_width_y[k] + * v->dpp_per_plane[k] / v->h_ratio[k] / v->pixel_clock[k]; + } else { + v->display_pipe_line_delivery_time_luma[k] = v->swath_width_y[k] + / v->pscl_throughput[k] / v->dppclk; + } + v->data_fabric_line_delivery_time_luma = + v->swath_width_y[k] * v->swath_height_y[k] + * dcn_bw_ceil2(v->byte_per_pixel_dety[k], 1.0) + / (v->return_bw * v->read_bandwidth_plane_luma[k] + / v->dpp_per_plane[k] + / v->total_data_read_bandwidth); + v->last_pixel_of_line_extra_watermark = dcn_bw_max2( + v->last_pixel_of_line_extra_watermark, + v->data_fabric_line_delivery_time_luma + - v->display_pipe_line_delivery_time_luma[k]); + if (v->byte_per_pixel_detc[k] == 0.0) { + v->display_pipe_line_delivery_time_chroma[k] = 0.0; + } else { + if (v->v_ratio[k] / 2.0 <= 1.0) { + v->display_pipe_line_delivery_time_chroma[k] = v->swath_width_y[k] + / 2.0 * v->dpp_per_plane[k] / (v->h_ratio[k] / 2.0) + / v->pixel_clock[k]; + } else { + v->display_pipe_line_delivery_time_chroma[k] = v->swath_width_y[k] + / 2.0 / v->pscl_throughput_chroma[k] / v->dppclk; + } + v->data_fabric_line_delivery_time_chroma = v->swath_width_y[k] / 2.0 + * v->swath_height_c[k] + * dcn_bw_ceil2(v->byte_per_pixel_detc[k], 2.0) + / (v->return_bw * v->read_bandwidth_plane_chroma[k] + / v->dpp_per_plane[k] + / v->total_data_read_bandwidth); + v->last_pixel_of_line_extra_watermark = + dcn_bw_max2( + v->last_pixel_of_line_extra_watermark, + v->data_fabric_line_delivery_time_chroma + - v->display_pipe_line_delivery_time_chroma[k]); + } + } + v->urgent_extra_latency = v->urgent_round_trip_and_out_of_order_latency + + (v->total_active_dpp * v->pixel_chunk_size_in_kbyte + + v->total_dcc_active_dpp * v->meta_chunk_size) * 1024.0 + / v->return_bw; + if (v->pte_enable == dcn_bw_yes) { + v->urgent_extra_latency = v->urgent_extra_latency + + v->total_active_dpp * v->pte_chunk_size * 1024.0 / v->return_bw; + } + v->urgent_watermark = v->urgent_latency + v->last_pixel_of_line_extra_watermark + + v->urgent_extra_latency; + v->ptemeta_urgent_watermark = v->urgent_watermark + 2.0 * v->urgent_latency; + /*nb p-state/dram clock change watermark*/ + + v->dram_clock_change_watermark = v->dram_clock_change_latency + v->urgent_watermark; + v->total_active_writeback = 0.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->output[k] == dcn_bw_writeback) { + v->total_active_writeback = v->total_active_writeback + 1.0; + } + } + if (v->total_active_writeback <= 1.0) { + v->writeback_dram_clock_change_watermark = v->dram_clock_change_latency + + v->write_back_latency; + } else { + v->writeback_dram_clock_change_watermark = v->dram_clock_change_latency + + v->write_back_latency + + v->writeback_chunk_size * 1024.0 / 32.0 / v->socclk; + } + /*stutter efficiency*/ + + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + v->lines_in_dety[k] = v->det_buffer_size_y[k] / v->byte_per_pixel_dety[k] + / v->swath_width_y[k]; + v->lines_in_dety_rounded_down_to_swath[k] = dcn_bw_floor2( + v->lines_in_dety[k], + v->swath_height_y[k]); + v->full_det_buffering_time_y[k] = v->lines_in_dety_rounded_down_to_swath[k] + * (v->htotal[k] / v->pixel_clock[k]) / v->v_ratio[k]; + if (v->byte_per_pixel_detc[k] > 0.0) { + v->lines_in_detc[k] = v->det_buffer_size_c[k] / v->byte_per_pixel_detc[k] + / (v->swath_width_y[k] / 2.0); + v->lines_in_detc_rounded_down_to_swath[k] = dcn_bw_floor2( + v->lines_in_detc[k], + v->swath_height_c[k]); + v->full_det_buffering_time_c[k] = v->lines_in_detc_rounded_down_to_swath[k] + * (v->htotal[k] / v->pixel_clock[k]) + / (v->v_ratio[k] / 2.0); + } else { + v->lines_in_detc[k] = 0.0; + v->lines_in_detc_rounded_down_to_swath[k] = 0.0; + v->full_det_buffering_time_c[k] = 999999.0; + } + } + v->min_full_det_buffering_time = 999999.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->full_det_buffering_time_y[k] < v->min_full_det_buffering_time) { + v->min_full_det_buffering_time = v->full_det_buffering_time_y[k]; + v->frame_time_for_min_full_det_buffering_time = v->vtotal[k] * v->htotal[k] + / v->pixel_clock[k]; + } + if (v->full_det_buffering_time_c[k] < v->min_full_det_buffering_time) { + v->min_full_det_buffering_time = v->full_det_buffering_time_c[k]; + v->frame_time_for_min_full_det_buffering_time = v->vtotal[k] * v->htotal[k] + / v->pixel_clock[k]; + } + } + v->average_read_bandwidth_gbyte_per_second = 0.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->dcc_enable[k] == dcn_bw_yes) { + v->average_read_bandwidth_gbyte_per_second = + v->average_read_bandwidth_gbyte_per_second + + v->read_bandwidth_plane_luma[k] + / v->dcc_rate[k] / 1000.0 + + v->read_bandwidth_plane_chroma[k] + / v->dcc_rate[k] / 1000.0; + } else { + v->average_read_bandwidth_gbyte_per_second = + v->average_read_bandwidth_gbyte_per_second + + v->read_bandwidth_plane_luma[k] / 1000.0 + + v->read_bandwidth_plane_chroma[k] + / 1000.0; + } + if (v->dcc_enable[k] == dcn_bw_yes) { + v->average_read_bandwidth_gbyte_per_second = + v->average_read_bandwidth_gbyte_per_second + + v->read_bandwidth_plane_luma[k] / 1000.0 + / 256.0 + + v->read_bandwidth_plane_chroma[k] / 1000.0 + / 256.0; + } + if (v->pte_enable == dcn_bw_yes) { + v->average_read_bandwidth_gbyte_per_second = + v->average_read_bandwidth_gbyte_per_second + + v->read_bandwidth_plane_luma[k] / 1000.0 + / 512.0 + + v->read_bandwidth_plane_chroma[k] / 1000.0 + / 512.0; + } + } + v->part_of_burst_that_fits_in_rob = dcn_bw_min2( + v->min_full_det_buffering_time * v->total_data_read_bandwidth, + v->rob_buffer_size_in_kbyte * 1024.0 * v->total_data_read_bandwidth + / (v->average_read_bandwidth_gbyte_per_second * 1000.0)); + v->stutter_burst_time = v->part_of_burst_that_fits_in_rob + * (v->average_read_bandwidth_gbyte_per_second * 1000.0) + / v->total_data_read_bandwidth / v->return_bw + + (v->min_full_det_buffering_time * v->total_data_read_bandwidth + - v->part_of_burst_that_fits_in_rob) / (v->dcfclk * 64.0); + if (v->total_active_writeback == 0.0) { + v->stutter_efficiency_not_including_vblank = (1.0 + - (v->sr_exit_time + v->stutter_burst_time) + / v->min_full_det_buffering_time) * 100.0; + } else { + v->stutter_efficiency_not_including_vblank = 0.0; + } + v->smallest_vblank = 999999.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->synchronized_vblank == dcn_bw_yes || v->number_of_active_planes == 1) { + v->v_blank_time = (v->vtotal[k] - v->vactive[k]) * v->htotal[k] + / v->pixel_clock[k]; + } else { + v->v_blank_time = 0.0; + } + v->smallest_vblank = dcn_bw_min2(v->smallest_vblank, v->v_blank_time); + } + v->stutter_efficiency = (v->stutter_efficiency_not_including_vblank / 100.0 + * (v->frame_time_for_min_full_det_buffering_time - v->smallest_vblank) + + v->smallest_vblank) / v->frame_time_for_min_full_det_buffering_time + * 100.0; + /*dcfclk deep sleep*/ + + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->byte_per_pixel_detc[k] > 0.0) { + v->dcfclk_deep_sleep_per_plane[k] = + dcn_bw_max2( + 1.1 * v->swath_width_y[k] + * dcn_bw_ceil2( + v->byte_per_pixel_dety[k], + 1.0) / 32.0 + / v->display_pipe_line_delivery_time_luma[k], + 1.1 * v->swath_width_y[k] / 2.0 + * dcn_bw_ceil2( + v->byte_per_pixel_detc[k], + 2.0) / 32.0 + / v->display_pipe_line_delivery_time_chroma[k]); + } else { + v->dcfclk_deep_sleep_per_plane[k] = 1.1 * v->swath_width_y[k] + * dcn_bw_ceil2(v->byte_per_pixel_dety[k], 1.0) / 64.0 + / v->display_pipe_line_delivery_time_luma[k]; + } + v->dcfclk_deep_sleep_per_plane[k] = dcn_bw_max2( + v->dcfclk_deep_sleep_per_plane[k], + v->pixel_clock[k] / 16.0); + } + v->dcf_clk_deep_sleep = 8.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + v->dcf_clk_deep_sleep = dcn_bw_max2( + v->dcf_clk_deep_sleep, + v->dcfclk_deep_sleep_per_plane[k]); + } + /*stutter watermark*/ + + v->stutter_exit_watermark = v->sr_exit_time + v->last_pixel_of_line_extra_watermark + + v->urgent_extra_latency + 10.0 / v->dcf_clk_deep_sleep; + v->stutter_enter_plus_exit_watermark = v->sr_enter_plus_exit_time + + v->last_pixel_of_line_extra_watermark + v->urgent_extra_latency; + /*urgent latency supported*/ + + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + v->effective_det_plus_lb_lines_luma = + dcn_bw_floor2( + v->lines_in_dety[k] + + dcn_bw_min2( + v->lines_in_dety[k] + * v->dppclk + * v->byte_per_pixel_dety[k] + * v->pscl_throughput[k] + / (v->return_bw + / v->dpp_per_plane[k]), + v->effective_lb_latency_hiding_source_lines_luma), + v->swath_height_y[k]); + v->urgent_latency_support_us_luma = v->effective_det_plus_lb_lines_luma + * (v->htotal[k] / v->pixel_clock[k]) / v->v_ratio[k] + - v->effective_det_plus_lb_lines_luma * v->swath_width_y[k] + * v->byte_per_pixel_dety[k] + / (v->return_bw / v->dpp_per_plane[k]); + if (v->byte_per_pixel_detc[k] > 0.0) { + v->effective_det_plus_lb_lines_chroma = + dcn_bw_floor2( + v->lines_in_detc[k] + + dcn_bw_min2( + v->lines_in_detc[k] + * v->dppclk + * v->byte_per_pixel_detc[k] + * v->pscl_throughput_chroma[k] + / (v->return_bw + / v->dpp_per_plane[k]), + v->effective_lb_latency_hiding_source_lines_chroma), + v->swath_height_c[k]); + v->urgent_latency_support_us_chroma = v->effective_det_plus_lb_lines_chroma + * (v->htotal[k] / v->pixel_clock[k]) / (v->v_ratio[k] / 2.0) + - v->effective_det_plus_lb_lines_chroma + * (v->swath_width_y[k] / 2.0) + * v->byte_per_pixel_detc[k] + / (v->return_bw / v->dpp_per_plane[k]); + v->urgent_latency_support_us[k] = dcn_bw_min2( + v->urgent_latency_support_us_luma, + v->urgent_latency_support_us_chroma); + } else { + v->urgent_latency_support_us[k] = v->urgent_latency_support_us_luma; + } + } + v->min_urgent_latency_support_us = 999999.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + v->min_urgent_latency_support_us = dcn_bw_min2( + v->min_urgent_latency_support_us, + v->urgent_latency_support_us[k]); + } + /*non-urgent latency tolerance*/ + + v->non_urgent_latency_tolerance = v->min_urgent_latency_support_us - v->urgent_watermark; + /*prefetch*/ + + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if ((v->source_pixel_format[k] == dcn_bw_rgb_sub_64 + || v->source_pixel_format[k] == dcn_bw_rgb_sub_32 + || v->source_pixel_format[k] == dcn_bw_rgb_sub_16)) { + if (v->source_surface_mode[k] == dcn_bw_sw_linear) { + v->block_height256_bytes_y = 1.0; + } else if (v->source_pixel_format[k] == dcn_bw_rgb_sub_64) { + v->block_height256_bytes_y = 4.0; + } else { + v->block_height256_bytes_y = 8.0; + } + v->block_height256_bytes_c = 0.0; + } else { + if (v->source_surface_mode[k] == dcn_bw_sw_linear) { + v->block_height256_bytes_y = 1.0; + v->block_height256_bytes_c = 1.0; + } else if (v->source_pixel_format[k] == dcn_bw_yuv420_sub_8) { + v->block_height256_bytes_y = 16.0; + v->block_height256_bytes_c = 8.0; + } else { + v->block_height256_bytes_y = 8.0; + v->block_height256_bytes_c = 8.0; + } + } + if (v->dcc_enable[k] == dcn_bw_yes) { + v->meta_request_width_y = 64.0 * 256.0 + / dcn_bw_ceil2(v->byte_per_pixel_dety[k], 1.0) + / (8.0 * v->block_height256_bytes_y); + v->meta_surf_width_y = dcn_bw_ceil2( + v->swath_width_y[k] - 1.0, + v->meta_request_width_y) + v->meta_request_width_y; + v->meta_surf_height_y = dcn_bw_ceil2( + v->viewport_height[k] - 1.0, + 8.0 * v->block_height256_bytes_y) + + 8.0 * v->block_height256_bytes_y; + if (v->pte_enable == dcn_bw_yes) { + v->meta_pte_bytes_frame_y = + (dcn_bw_ceil2( + (v->meta_surf_width_y + * v->meta_surf_height_y + * dcn_bw_ceil2( + v->byte_per_pixel_dety[k], + 1.0) + / 256.0 - 4096.0) + / 8.0 / 4096.0, + 1.0) + 1) * 64.0; + } else { + v->meta_pte_bytes_frame_y = 0.0; + } + if (v->source_scan[k] == dcn_bw_hor) { + v->meta_row_byte_y = v->meta_surf_width_y * 8.0 + * v->block_height256_bytes_y + * dcn_bw_ceil2(v->byte_per_pixel_dety[k], 1.0) / 256.0; + } else { + v->meta_row_byte_y = v->meta_surf_height_y * v->meta_request_width_y + * dcn_bw_ceil2(v->byte_per_pixel_dety[k], 1.0) / 256.0; + } + } else { + v->meta_pte_bytes_frame_y = 0.0; + v->meta_row_byte_y = 0.0; + } + if (v->pte_enable == dcn_bw_yes) { + if (v->source_surface_mode[k] == dcn_bw_sw_linear) { + v->macro_tile_size_byte_y = 256.0; + v->macro_tile_height_y = 1.0; + } else if (v->source_surface_mode[k] == dcn_bw_sw_4_kb_s + || v->source_surface_mode[k] == dcn_bw_sw_4_kb_s_x + || v->source_surface_mode[k] == dcn_bw_sw_4_kb_d + || v->source_surface_mode[k] == dcn_bw_sw_4_kb_d_x) { + v->macro_tile_size_byte_y = 4096.0; + v->macro_tile_height_y = 4.0 * v->block_height256_bytes_y; + } else if (v->source_surface_mode[k] == dcn_bw_sw_64_kb_s + || v->source_surface_mode[k] == dcn_bw_sw_64_kb_s_t + || v->source_surface_mode[k] == dcn_bw_sw_64_kb_s_x + || v->source_surface_mode[k] == dcn_bw_sw_64_kb_d + || v->source_surface_mode[k] == dcn_bw_sw_64_kb_d_t + || v->source_surface_mode[k] == dcn_bw_sw_64_kb_d_x) { + v->macro_tile_size_byte_y = 64.0 * 1024; + v->macro_tile_height_y = 16.0 * v->block_height256_bytes_y; + } else { + v->macro_tile_size_byte_y = 256.0 * 1024; + v->macro_tile_height_y = 32.0 * v->block_height256_bytes_y; + } + if (v->macro_tile_size_byte_y <= 65536.0) { + v->pixel_pte_req_height_y = v->macro_tile_height_y; + } else { + v->pixel_pte_req_height_y = 16.0 * v->block_height256_bytes_y; + } + v->pixel_pte_req_width_y = 4096.0 / dcn_bw_ceil2(v->byte_per_pixel_dety[k], 1.0) + / v->pixel_pte_req_height_y * 8; + if (v->source_surface_mode[k] == dcn_bw_sw_linear) { + v->pixel_pte_bytes_per_row_y = + 64.0 + * (dcn_bw_ceil2( + (v->swath_width_y[k] + * dcn_bw_min2( + 128.0, + dcn_bw_pow( + 2.0, + dcn_bw_floor2( + dcn_bw_log( + v->pte_buffer_size_in_requests + * v->pixel_pte_req_width_y + / v->swath_width_y[k], + 2.0), + 1.0))) + - 1.0) + / v->pixel_pte_req_width_y, + 1.0) + 1); + } else if (v->source_scan[k] == dcn_bw_hor) { + v->pixel_pte_bytes_per_row_y = + 64.0 + * (dcn_bw_ceil2( + (v->swath_width_y[k] + - 1.0) + / v->pixel_pte_req_width_y, + 1.0) + 1); + } else { + v->pixel_pte_bytes_per_row_y = + 64.0 + * (dcn_bw_ceil2( + (v->viewport_height[k] + - 1.0) + / v->pixel_pte_req_height_y, + 1.0) + 1); + } + } else { + v->pixel_pte_bytes_per_row_y = 0.0; + } + if ((v->source_pixel_format[k] != dcn_bw_rgb_sub_64 + && v->source_pixel_format[k] != dcn_bw_rgb_sub_32 + && v->source_pixel_format[k] != dcn_bw_rgb_sub_16)) { + if (v->dcc_enable[k] == dcn_bw_yes) { + v->meta_request_width_c = 64.0 * 256.0 + / dcn_bw_ceil2(v->byte_per_pixel_detc[k], 2.0) + / (8.0 * v->block_height256_bytes_c); + v->meta_surf_width_c = dcn_bw_ceil2( + v->swath_width_y[k] / 2.0 - 1.0, + v->meta_request_width_c) + v->meta_request_width_c; + v->meta_surf_height_c = dcn_bw_ceil2( + v->viewport_height[k] / 2.0 - 1.0, + 8.0 * v->block_height256_bytes_c) + + 8.0 * v->block_height256_bytes_c; + if (v->pte_enable == dcn_bw_yes) { + v->meta_pte_bytes_frame_c = + (dcn_bw_ceil2( + (v->meta_surf_width_c + * v->meta_surf_height_c + * dcn_bw_ceil2( + v->byte_per_pixel_detc[k], + 2.0) + / 256.0 + - 4096.0) + / 8.0 + / 4096.0, + 1.0) + 1) * 64.0; + } else { + v->meta_pte_bytes_frame_c = 0.0; + } + if (v->source_scan[k] == dcn_bw_hor) { + v->meta_row_byte_c = v->meta_surf_width_c * 8.0 + * v->block_height256_bytes_c + * dcn_bw_ceil2(v->byte_per_pixel_detc[k], 2.0) + / 256.0; + } else { + v->meta_row_byte_c = v->meta_surf_height_c + * v->meta_request_width_c + * dcn_bw_ceil2(v->byte_per_pixel_detc[k], 2.0) + / 256.0; + } + } else { + v->meta_pte_bytes_frame_c = 0.0; + v->meta_row_byte_c = 0.0; + } + if (v->pte_enable == dcn_bw_yes) { + if (v->source_surface_mode[k] == dcn_bw_sw_linear) { + v->macro_tile_size_bytes_c = 256.0; + v->macro_tile_height_c = 1.0; + } else if (v->source_surface_mode[k] == dcn_bw_sw_4_kb_s + || v->source_surface_mode[k] == dcn_bw_sw_4_kb_s_x + || v->source_surface_mode[k] == dcn_bw_sw_4_kb_d + || v->source_surface_mode[k] + == dcn_bw_sw_4_kb_d_x) { + v->macro_tile_size_bytes_c = 4096.0; + v->macro_tile_height_c = 4.0 * v->block_height256_bytes_c; + } else if (v->source_surface_mode[k] == dcn_bw_sw_64_kb_s + || v->source_surface_mode[k] == dcn_bw_sw_64_kb_s_t + || v->source_surface_mode[k] == dcn_bw_sw_64_kb_s_x + || v->source_surface_mode[k] == dcn_bw_sw_64_kb_d + || v->source_surface_mode[k] == dcn_bw_sw_64_kb_d_t + || v->source_surface_mode[k] + == dcn_bw_sw_64_kb_d_x) { + v->macro_tile_size_bytes_c = 64.0 * 1024; + v->macro_tile_height_c = 16.0 * v->block_height256_bytes_c; + } else { + v->macro_tile_size_bytes_c = 256.0 * 1024; + v->macro_tile_height_c = 32.0 * v->block_height256_bytes_c; + } + if (v->macro_tile_size_bytes_c <= 65536.0) { + v->pixel_pte_req_height_c = v->macro_tile_height_c; + } else { + v->pixel_pte_req_height_c = 16.0 + * v->block_height256_bytes_c; + } + v->pixel_pte_req_width_c = 4096.0 + / dcn_bw_ceil2(v->byte_per_pixel_detc[k], 2.0) + / v->pixel_pte_req_height_c * 8; + if (v->source_surface_mode[k] == dcn_bw_sw_linear) { + v->pixel_pte_bytes_per_row_c = + 64.0 + * (dcn_bw_ceil2( + (v->swath_width_y[k] + / 2.0 + * dcn_bw_min2( + 128.0, + dcn_bw_pow( + 2.0, + dcn_bw_floor2( + dcn_bw_log( + v->pte_buffer_size_in_requests + * v->pixel_pte_req_width_c + / (v->swath_width_y[k] + / 2.0), + 2.0), + 1.0))) + - 1.0) + / v->pixel_pte_req_width_c, + 1.0) + 1); + } else if (v->source_scan[k] == dcn_bw_hor) { + v->pixel_pte_bytes_per_row_c = + 64.0 + * (dcn_bw_ceil2( + (v->swath_width_y[k] + / 2.0 + - 1.0) + / v->pixel_pte_req_width_c, + 1.0) + 1); + } else { + v->pixel_pte_bytes_per_row_c = + 64.0 + * (dcn_bw_ceil2( + (v->viewport_height[k] + / 2.0 + - 1.0) + / v->pixel_pte_req_height_c, + 1.0) + 1); + } + } else { + v->pixel_pte_bytes_per_row_c = 0.0; + } + } else { + v->pixel_pte_bytes_per_row_c = 0.0; + v->meta_pte_bytes_frame_c = 0.0; + v->meta_row_byte_c = 0.0; + } + v->pixel_pte_bytes_per_row[k] = v->pixel_pte_bytes_per_row_y + + v->pixel_pte_bytes_per_row_c; + v->meta_pte_bytes_frame[k] = v->meta_pte_bytes_frame_y + v->meta_pte_bytes_frame_c; + v->meta_row_byte[k] = v->meta_row_byte_y + v->meta_row_byte_c; + v->v_init_pre_fill_y[k] = dcn_bw_floor2( + (v->v_ratio[k] + v->vtaps[k] + 1.0 + + v->interlace_output[k] * 0.5 * v->v_ratio[k]) + / 2.0, + 1.0); + v->max_num_swath_y[k] = dcn_bw_ceil2( + (v->v_init_pre_fill_y[k] - 1.0) / v->swath_height_y[k], + 1.0) + 1; + if (v->v_init_pre_fill_y[k] > 1.0) { + v->max_partial_swath_y = dcn_bw_mod( + (v->v_init_pre_fill_y[k] - 2.0), + v->swath_height_y[k]); + } else { + v->max_partial_swath_y = dcn_bw_mod( + (v->v_init_pre_fill_y[k] + v->swath_height_y[k] - 2.0), + v->swath_height_y[k]); + } + v->max_partial_swath_y = dcn_bw_max2(1.0, v->max_partial_swath_y); + v->prefetch_source_lines_y[k] = v->max_num_swath_y[k] * v->swath_height_y[k] + + v->max_partial_swath_y; + if ((v->source_pixel_format[k] != dcn_bw_rgb_sub_64 + && v->source_pixel_format[k] != dcn_bw_rgb_sub_32 + && v->source_pixel_format[k] != dcn_bw_rgb_sub_16)) { + v->v_init_pre_fill_c[k] = dcn_bw_floor2( + (v->v_ratio[k] / 2.0 + v->vtaps[k] + 1.0 + + v->interlace_output[k] * 0.5 + * v->v_ratio[k] / 2.0) + / 2.0, + 1.0); + v->max_num_swath_c[k] = dcn_bw_ceil2( + (v->v_init_pre_fill_c[k] - 1.0) / v->swath_height_c[k], + 1.0) + 1; + if (v->v_init_pre_fill_c[k] > 1.0) { + v->max_partial_swath_c = dcn_bw_mod( + (v->v_init_pre_fill_c[k] - 2.0), + v->swath_height_c[k]); + } else { + v->max_partial_swath_c = dcn_bw_mod( + (v->v_init_pre_fill_c[k] + v->swath_height_c[k] + - 2.0), + v->swath_height_c[k]); + } + v->max_partial_swath_c = dcn_bw_max2(1.0, v->max_partial_swath_c); + } else { + v->max_num_swath_c[k] = 0.0; + v->max_partial_swath_c = 0.0; + } + v->prefetch_source_lines_c[k] = v->max_num_swath_c[k] * v->swath_height_c[k] + + v->max_partial_swath_c; + } + v->t_calc = 24.0 / v->dcf_clk_deep_sleep; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one + == dcn_bw_yes) { + v->max_vstartup_lines[k] = v->vtotal[k] - v->vactive[k] - 1.0; + } else { + v->max_vstartup_lines[k] = v->v_sync_plus_back_porch[k] - 1.0; + } + } + v->next_prefetch_mode = 0.0; + do { + v->v_startup_lines = 13.0; + do { + v->planes_with_room_to_increase_vstartup_prefetch_bw_less_than_active_bw = + dcn_bw_yes; + v->planes_with_room_to_increase_vstartup_vratio_prefetch_more_than4 = + dcn_bw_no; + v->planes_with_room_to_increase_vstartup_destination_line_times_for_prefetch_less_than2 = + dcn_bw_no; + v->v_ratio_prefetch_more_than4 = dcn_bw_no; + v->destination_line_times_for_prefetch_less_than2 = dcn_bw_no; + v->prefetch_mode = v->next_prefetch_mode; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + v->dstx_after_scaler = 90.0 * v->pixel_clock[k] / v->dppclk + + 42.0 * v->pixel_clock[k] / v->dispclk; + if (v->dpp_per_plane[k] > 1.0) { + v->dstx_after_scaler = v->dstx_after_scaler + + v->scaler_rec_out_width[k] / 2.0; + } + if (v->output_format[k] == dcn_bw_420) { + v->dsty_after_scaler = 1.0; + } else { + v->dsty_after_scaler = 0.0; + } + v->v_update_offset_pix = dcn_bw_ceil2(v->htotal[k] / 4.0, 1.0); + v->total_repeater_delay_time = v->max_inter_dcn_tile_repeaters + * (2.0 / v->dppclk + 3.0 / v->dispclk); + v->v_update_width_pix = (14.0 / v->dcf_clk_deep_sleep + + 12.0 / v->dppclk + v->total_repeater_delay_time) + * v->pixel_clock[k]; + v->v_ready_offset_pix = dcn_bw_max2( + 150.0 / v->dppclk, + v->total_repeater_delay_time + + 20.0 / v->dcf_clk_deep_sleep + + 10.0 / v->dppclk) + * v->pixel_clock[k]; + v->t_setup = (v->v_update_offset_pix + v->v_update_width_pix + + v->v_ready_offset_pix) / v->pixel_clock[k]; + v->v_startup[k] = dcn_bw_min2( + v->v_startup_lines, + v->max_vstartup_lines[k]); + if (v->prefetch_mode == 0.0) { + v->t_wait = dcn_bw_max3( + v->dram_clock_change_latency + + v->urgent_latency, + v->sr_enter_plus_exit_time, + v->urgent_latency); + } else if (v->prefetch_mode == 1.0) { + v->t_wait = dcn_bw_max2( + v->sr_enter_plus_exit_time, + v->urgent_latency); + } else { + v->t_wait = v->urgent_latency; + } + v->destination_lines_for_prefetch[k] = + dcn_bw_floor2( + 4.0 + * (v->v_startup[k] + - v->t_wait + / (v->htotal[k] + / v->pixel_clock[k]) + - (v->t_calc + + v->t_setup) + / (v->htotal[k] + / v->pixel_clock[k]) + - (v->dsty_after_scaler + + v->dstx_after_scaler + / v->htotal[k]) + + 0.125), + 1.0) / 4; + if (v->destination_lines_for_prefetch[k] > 0.0) { + v->prefetch_bandwidth[k] = + (v->meta_pte_bytes_frame[k] + + 2.0 * v->meta_row_byte[k] + + 2.0 + * v->pixel_pte_bytes_per_row[k] + + v->prefetch_source_lines_y[k] + * v->swath_width_y[k] + * dcn_bw_ceil2( + v->byte_per_pixel_dety[k], + 1.0) + + v->prefetch_source_lines_c[k] + * v->swath_width_y[k] + / 2.0 + * dcn_bw_ceil2( + v->byte_per_pixel_detc[k], + 2.0)) + / (v->destination_lines_for_prefetch[k] + * v->htotal[k] + / v->pixel_clock[k]); + } else { + v->prefetch_bandwidth[k] = 999999.0; + } + } + v->bandwidth_available_for_immediate_flip = v->return_bw; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + v->bandwidth_available_for_immediate_flip = + v->bandwidth_available_for_immediate_flip + - dcn_bw_max2( + v->read_bandwidth_plane_luma[k] + + v->read_bandwidth_plane_chroma[k], + v->prefetch_bandwidth[k]); + } + v->tot_immediate_flip_bytes = 0.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->immediate_flip_supported == dcn_bw_yes + && (v->source_pixel_format[k] != dcn_bw_yuv420_sub_8 + && v->source_pixel_format[k] + != dcn_bw_yuv420_sub_10)) { + v->tot_immediate_flip_bytes = v->tot_immediate_flip_bytes + + v->meta_pte_bytes_frame[k] + + v->meta_row_byte[k] + + v->pixel_pte_bytes_per_row[k]; + } + } + v->max_rd_bandwidth = 0.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->pte_enable == dcn_bw_yes && v->dcc_enable[k] == dcn_bw_yes) { + if (v->immediate_flip_supported == dcn_bw_yes + && (v->source_pixel_format[k] + != dcn_bw_yuv420_sub_8 + && v->source_pixel_format[k] + != dcn_bw_yuv420_sub_10)) { + v->time_for_fetching_meta_pte = + dcn_bw_max5( + v->meta_pte_bytes_frame[k] + / v->prefetch_bandwidth[k], + v->meta_pte_bytes_frame[k] + * v->tot_immediate_flip_bytes + / (v->bandwidth_available_for_immediate_flip + * (v->meta_pte_bytes_frame[k] + + v->meta_row_byte[k] + + v->pixel_pte_bytes_per_row[k])), + v->urgent_extra_latency, + v->urgent_latency, + v->htotal[k] + / v->pixel_clock[k] + / 4.0); + } else { + v->time_for_fetching_meta_pte = + dcn_bw_max3( + v->meta_pte_bytes_frame[k] + / v->prefetch_bandwidth[k], + v->urgent_extra_latency, + v->htotal[k] + / v->pixel_clock[k] + / 4.0); + } + } else { + v->time_for_fetching_meta_pte = v->htotal[k] + / v->pixel_clock[k] / 4.0; + } + v->destination_lines_to_request_vm_inv_blank[k] = + dcn_bw_floor2( + 4.0 + * (v->time_for_fetching_meta_pte + / (v->htotal[k] + / v->pixel_clock[k]) + + 0.125), + 1.0) / 4; + if ((v->pte_enable == dcn_bw_yes || v->dcc_enable[k] == dcn_bw_yes)) { + if (v->immediate_flip_supported == dcn_bw_yes + && (v->source_pixel_format[k] + != dcn_bw_yuv420_sub_8 + && v->source_pixel_format[k] + != dcn_bw_yuv420_sub_10)) { + v->time_for_fetching_row_in_vblank = + dcn_bw_max5( + (v->meta_row_byte[k] + + v->pixel_pte_bytes_per_row[k]) + / v->prefetch_bandwidth[k], + (v->meta_row_byte[k] + + v->pixel_pte_bytes_per_row[k]) + * v->tot_immediate_flip_bytes + / (v->bandwidth_available_for_immediate_flip + * (v->meta_pte_bytes_frame[k] + + v->meta_row_byte[k] + + v->pixel_pte_bytes_per_row[k])), + v->urgent_extra_latency, + 2.0 + * v->urgent_latency, + v->htotal[k] + / v->pixel_clock[k] + - v->time_for_fetching_meta_pte); + } else { + v->time_for_fetching_row_in_vblank = + dcn_bw_max3( + (v->meta_row_byte[k] + + v->pixel_pte_bytes_per_row[k]) + / v->prefetch_bandwidth[k], + v->urgent_extra_latency, + v->htotal[k] + / v->pixel_clock[k] + - v->time_for_fetching_meta_pte); + } + } else { + v->time_for_fetching_row_in_vblank = + dcn_bw_max2( + v->urgent_extra_latency + - v->time_for_fetching_meta_pte, + v->htotal[k] + / v->pixel_clock[k] + - v->time_for_fetching_meta_pte); + } + v->destination_lines_to_request_row_in_vblank[k] = + dcn_bw_floor2( + 4.0 + * (v->time_for_fetching_row_in_vblank + / (v->htotal[k] + / v->pixel_clock[k]) + + 0.125), + 1.0) / 4; + v->lines_to_request_prefetch_pixel_data = + v->destination_lines_for_prefetch[k] + - v->destination_lines_to_request_vm_inv_blank[k] + - v->destination_lines_to_request_row_in_vblank[k]; + if (v->lines_to_request_prefetch_pixel_data > 0.0) { + v->v_ratio_prefetch_y[k] = v->prefetch_source_lines_y[k] + / v->lines_to_request_prefetch_pixel_data; + if ((v->swath_height_y[k] > 4.0)) { + if (v->lines_to_request_prefetch_pixel_data + > (v->v_init_pre_fill_y[k] - 3.0) + / 2.0) { + v->v_ratio_prefetch_y[k] = + dcn_bw_max2( + v->v_ratio_prefetch_y[k], + v->max_num_swath_y[k] + * v->swath_height_y[k] + / (v->lines_to_request_prefetch_pixel_data + - (v->v_init_pre_fill_y[k] + - 3.0) + / 2.0)); + } else { + v->v_ratio_prefetch_y[k] = 999999.0; + } + } + } else { + v->v_ratio_prefetch_y[k] = 999999.0; + } + v->v_ratio_prefetch_y[k] = dcn_bw_max2(v->v_ratio_prefetch_y[k], 1.0); + if (v->lines_to_request_prefetch_pixel_data > 0.0) { + v->v_ratio_prefetch_c[k] = v->prefetch_source_lines_c[k] + / v->lines_to_request_prefetch_pixel_data; + if ((v->swath_height_c[k] > 4.0)) { + if (v->lines_to_request_prefetch_pixel_data + > (v->v_init_pre_fill_c[k] - 3.0) + / 2.0) { + v->v_ratio_prefetch_c[k] = + dcn_bw_max2( + v->v_ratio_prefetch_c[k], + v->max_num_swath_c[k] + * v->swath_height_c[k] + / (v->lines_to_request_prefetch_pixel_data + - (v->v_init_pre_fill_c[k] + - 3.0) + / 2.0)); + } else { + v->v_ratio_prefetch_c[k] = 999999.0; + } + } + } else { + v->v_ratio_prefetch_c[k] = 999999.0; + } + v->v_ratio_prefetch_c[k] = dcn_bw_max2(v->v_ratio_prefetch_c[k], 1.0); + if (v->lines_to_request_prefetch_pixel_data > 0.0) { + v->required_prefetch_pix_data_bw = + v->dpp_per_plane[k] + * (v->prefetch_source_lines_y[k] + / v->lines_to_request_prefetch_pixel_data + * dcn_bw_ceil2( + v->byte_per_pixel_dety[k], + 1.0) + + v->prefetch_source_lines_c[k] + / v->lines_to_request_prefetch_pixel_data + * dcn_bw_ceil2( + v->byte_per_pixel_detc[k], + 2.0) + / 2.0) + * v->swath_width_y[k] + / (v->htotal[k] + / v->pixel_clock[k]); + } else { + v->required_prefetch_pix_data_bw = 999999.0; + } + v->max_rd_bandwidth = + v->max_rd_bandwidth + + dcn_bw_max2( + v->read_bandwidth_plane_luma[k] + + v->read_bandwidth_plane_chroma[k], + v->required_prefetch_pix_data_bw); + if (v->immediate_flip_supported == dcn_bw_yes + && (v->source_pixel_format[k] != dcn_bw_yuv420_sub_8 + && v->source_pixel_format[k] + != dcn_bw_yuv420_sub_10)) { + v->max_rd_bandwidth = + v->max_rd_bandwidth + + dcn_bw_max2( + v->meta_pte_bytes_frame[k] + / (v->destination_lines_to_request_vm_inv_blank[k] + * v->htotal[k] + / v->pixel_clock[k]), + (v->meta_row_byte[k] + + v->pixel_pte_bytes_per_row[k]) + / (v->destination_lines_to_request_row_in_vblank[k] + * v->htotal[k] + / v->pixel_clock[k])); + } + if (v->v_ratio_prefetch_y[k] > 4.0 + || v->v_ratio_prefetch_c[k] > 4.0) { + v->v_ratio_prefetch_more_than4 = dcn_bw_yes; + } + if (v->destination_lines_for_prefetch[k] < 2.0) { + v->destination_line_times_for_prefetch_less_than2 = + dcn_bw_yes; + } + if (v->max_vstartup_lines[k] > v->v_startup_lines) { + if (v->required_prefetch_pix_data_bw + > (v->read_bandwidth_plane_luma[k] + + v->read_bandwidth_plane_chroma[k])) { + v->planes_with_room_to_increase_vstartup_prefetch_bw_less_than_active_bw = + dcn_bw_no; + } + if (v->v_ratio_prefetch_y[k] > 4.0 + || v->v_ratio_prefetch_c[k] > 4.0) { + v->planes_with_room_to_increase_vstartup_vratio_prefetch_more_than4 = + dcn_bw_yes; + } + if (v->destination_lines_for_prefetch[k] < 2.0) { + v->planes_with_room_to_increase_vstartup_destination_line_times_for_prefetch_less_than2 = + dcn_bw_yes; + } + } + } + if (v->max_rd_bandwidth <= v->return_bw + && v->v_ratio_prefetch_more_than4 == dcn_bw_no + && v->destination_line_times_for_prefetch_less_than2 + == dcn_bw_no) { + v->prefetch_mode_supported = dcn_bw_yes; + } else { + v->prefetch_mode_supported = dcn_bw_no; + } + v->v_startup_lines = v->v_startup_lines + 1.0; + } while (!(v->prefetch_mode_supported == dcn_bw_yes + || (v->planes_with_room_to_increase_vstartup_prefetch_bw_less_than_active_bw + == dcn_bw_yes + && v->planes_with_room_to_increase_vstartup_vratio_prefetch_more_than4 + == dcn_bw_no + && v->planes_with_room_to_increase_vstartup_destination_line_times_for_prefetch_less_than2 + == dcn_bw_no))); + v->next_prefetch_mode = v->next_prefetch_mode + 1.0; + } while (!(v->prefetch_mode_supported == dcn_bw_yes || v->prefetch_mode == 2.0)); + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->v_ratio_prefetch_y[k] <= 1.0) { + v->display_pipe_line_delivery_time_luma_prefetch[k] = v->swath_width_y[k] + * v->dpp_per_plane[k] / v->h_ratio[k] / v->pixel_clock[k]; + } else { + v->display_pipe_line_delivery_time_luma_prefetch[k] = v->swath_width_y[k] + / v->pscl_throughput[k] / v->dppclk; + } + if (v->byte_per_pixel_detc[k] == 0.0) { + v->display_pipe_line_delivery_time_chroma_prefetch[k] = 0.0; + } else { + if (v->v_ratio_prefetch_c[k] <= 1.0) { + v->display_pipe_line_delivery_time_chroma_prefetch[k] = + v->swath_width_y[k] * v->dpp_per_plane[k] + / v->h_ratio[k] / v->pixel_clock[k]; + } else { + v->display_pipe_line_delivery_time_chroma_prefetch[k] = + v->swath_width_y[k] / v->pscl_throughput[k] + / v->dppclk; + } + } + } + /*min ttuv_blank*/ + + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->prefetch_mode == 0.0) { + v->allow_dram_clock_change_during_vblank[k] = dcn_bw_yes; + v->allow_dram_self_refresh_during_vblank[k] = dcn_bw_yes; + v->min_ttuv_blank[k] = v->t_calc + + dcn_bw_max3( + v->dram_clock_change_watermark, + v->stutter_enter_plus_exit_watermark, + v->urgent_watermark); + } else if (v->prefetch_mode == 1.0) { + v->allow_dram_clock_change_during_vblank[k] = dcn_bw_no; + v->allow_dram_self_refresh_during_vblank[k] = dcn_bw_yes; + v->min_ttuv_blank[k] = v->t_calc + + dcn_bw_max2( + v->stutter_enter_plus_exit_watermark, + v->urgent_watermark); + } else { + v->allow_dram_clock_change_during_vblank[k] = dcn_bw_no; + v->allow_dram_self_refresh_during_vblank[k] = dcn_bw_no; + v->min_ttuv_blank[k] = v->t_calc + v->urgent_watermark; + } + } + /*nb p-state/dram clock change support*/ + + v->active_dp_ps = 0.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + v->active_dp_ps = v->active_dp_ps + v->dpp_per_plane[k]; + } + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + v->lb_latency_hiding_source_lines_y = + dcn_bw_min2( + v->max_line_buffer_lines, + dcn_bw_floor2( + v->line_buffer_size + / v->lb_bit_per_pixel[k] + / (v->swath_width_y[k] + / dcn_bw_max2( + v->h_ratio[k], + 1.0)), + 1.0)) - (v->vtaps[k] - 1.0); + v->lb_latency_hiding_source_lines_c = + dcn_bw_min2( + v->max_line_buffer_lines, + dcn_bw_floor2( + v->line_buffer_size + / v->lb_bit_per_pixel[k] + / (v->swath_width_y[k] + / 2.0 + / dcn_bw_max2( + v->h_ratio[k] + / 2.0, + 1.0)), + 1.0)) - (v->vta_pschroma[k] - 1.0); + v->effective_lb_latency_hiding_y = v->lb_latency_hiding_source_lines_y + / v->v_ratio[k] * (v->htotal[k] / v->pixel_clock[k]); + v->effective_lb_latency_hiding_c = v->lb_latency_hiding_source_lines_c + / (v->v_ratio[k] / 2.0) * (v->htotal[k] / v->pixel_clock[k]); + if (v->swath_width_y[k] > 2.0 * v->dpp_output_buffer_pixels) { + v->dpp_output_buffer_lines_y = v->dpp_output_buffer_pixels + / v->swath_width_y[k]; + } else if (v->swath_width_y[k] > v->dpp_output_buffer_pixels) { + v->dpp_output_buffer_lines_y = 0.5; + } else { + v->dpp_output_buffer_lines_y = 1.0; + } + if (v->swath_width_y[k] / 2.0 > 2.0 * v->dpp_output_buffer_pixels) { + v->dpp_output_buffer_lines_c = v->dpp_output_buffer_pixels + / (v->swath_width_y[k] / 2.0); + } else if (v->swath_width_y[k] / 2.0 > v->dpp_output_buffer_pixels) { + v->dpp_output_buffer_lines_c = 0.5; + } else { + v->dpp_output_buffer_lines_c = 1.0; + } + v->dppopp_buffering_y = (v->htotal[k] / v->pixel_clock[k]) + * (v->dpp_output_buffer_lines_y + v->opp_output_buffer_lines); + v->max_det_buffering_time_y = v->full_det_buffering_time_y[k] + + (v->lines_in_dety[k] - v->lines_in_dety_rounded_down_to_swath[k]) + / v->swath_height_y[k] + * (v->htotal[k] / v->pixel_clock[k]); + v->active_dram_clock_change_latency_margin_y = v->dppopp_buffering_y + + v->effective_lb_latency_hiding_y + v->max_det_buffering_time_y + - v->dram_clock_change_watermark; + if (v->active_dp_ps > 1.0) { + v->active_dram_clock_change_latency_margin_y = + v->active_dram_clock_change_latency_margin_y + - (1.0 - 1.0 / (v->active_dp_ps - 1.0)) + * v->swath_height_y[k] + * (v->htotal[k] + / v->pixel_clock[k]); + } + if (v->byte_per_pixel_detc[k] > 0.0) { + v->dppopp_buffering_c = + (v->htotal[k] / v->pixel_clock[k]) + * (v->dpp_output_buffer_lines_c + + v->opp_output_buffer_lines); + v->max_det_buffering_time_c = v->full_det_buffering_time_c[k] + + (v->lines_in_detc[k] + - v->lines_in_detc_rounded_down_to_swath[k]) + / v->swath_height_c[k] + * (v->htotal[k] / v->pixel_clock[k]); + v->active_dram_clock_change_latency_margin_c = v->dppopp_buffering_c + + v->effective_lb_latency_hiding_c + + v->max_det_buffering_time_c + - v->dram_clock_change_watermark; + if (v->active_dp_ps > 1.0) { + v->active_dram_clock_change_latency_margin_c = + v->active_dram_clock_change_latency_margin_c + - (1.0 + - 1.0 + / (v->active_dp_ps + - 1.0)) + * v->swath_height_c[k] + * (v->htotal[k] + / v->pixel_clock[k]); + } + v->active_dram_clock_change_latency_margin[k] = dcn_bw_min2( + v->active_dram_clock_change_latency_margin_y, + v->active_dram_clock_change_latency_margin_c); + } else { + v->active_dram_clock_change_latency_margin[k] = + v->active_dram_clock_change_latency_margin_y; + } + if (v->output_format[k] == dcn_bw_444) { + v->writeback_dram_clock_change_latency_margin = + (v->writeback_luma_buffer_size + + v->writeback_chroma_buffer_size) * 1024.0 + / (v->scaler_rec_out_width[k] + / (v->htotal[k] + / v->pixel_clock[k]) + * 4.0) + - v->writeback_dram_clock_change_watermark; + } else { + v->writeback_dram_clock_change_latency_margin = dcn_bw_min2( + v->writeback_luma_buffer_size, + 2.0 * v->writeback_chroma_buffer_size) * 1024.0 + / (v->scaler_rec_out_width[k] + / (v->htotal[k] / v->pixel_clock[k])) + - v->writeback_dram_clock_change_watermark; + } + if (v->output[k] == dcn_bw_writeback) { + v->active_dram_clock_change_latency_margin[k] = dcn_bw_min2( + v->active_dram_clock_change_latency_margin[k], + v->writeback_dram_clock_change_latency_margin); + } + } + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->allow_dram_clock_change_during_vblank[k] == dcn_bw_yes) { + v->v_blank_dram_clock_change_latency_margin[k] = (v->vtotal[k] + - v->scaler_recout_height[k]) + * (v->htotal[k] / v->pixel_clock[k]) + - dcn_bw_max2( + v->dram_clock_change_watermark, + v->writeback_dram_clock_change_watermark); + } else { + v->v_blank_dram_clock_change_latency_margin[k] = 0.0; + } + } + v->min_active_dram_clock_change_margin = 999999.0; + v->v_blank_of_min_active_dram_clock_change_margin = 999999.0; + v->second_min_active_dram_clock_change_margin = 999999.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->active_dram_clock_change_latency_margin[k] + < v->min_active_dram_clock_change_margin) { + v->second_min_active_dram_clock_change_margin = + v->min_active_dram_clock_change_margin; + v->min_active_dram_clock_change_margin = + v->active_dram_clock_change_latency_margin[k]; + v->v_blank_of_min_active_dram_clock_change_margin = + v->v_blank_dram_clock_change_latency_margin[k]; + } else if (v->active_dram_clock_change_latency_margin[k] + < v->second_min_active_dram_clock_change_margin) { + v->second_min_active_dram_clock_change_margin = + v->active_dram_clock_change_latency_margin[k]; + } + } + v->min_vblank_dram_clock_change_margin = 999999.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->min_vblank_dram_clock_change_margin + > v->v_blank_dram_clock_change_latency_margin[k]) { + v->min_vblank_dram_clock_change_margin = + v->v_blank_dram_clock_change_latency_margin[k]; + } + } + if (v->synchronized_vblank == dcn_bw_yes || v->number_of_active_planes == 1) { + v->dram_clock_change_margin = dcn_bw_max2( + v->min_active_dram_clock_change_margin, + v->min_vblank_dram_clock_change_margin); + } else if (v->v_blank_of_min_active_dram_clock_change_margin + > v->min_active_dram_clock_change_margin) { + v->dram_clock_change_margin = dcn_bw_min2( + v->second_min_active_dram_clock_change_margin, + v->v_blank_of_min_active_dram_clock_change_margin); + } else { + v->dram_clock_change_margin = v->min_active_dram_clock_change_margin; + } + if (v->min_active_dram_clock_change_margin > 0.0) { + v->dram_clock_change_support = dcn_bw_supported_in_v_active; + } else if (v->dram_clock_change_margin > 0.0) { + v->dram_clock_change_support = dcn_bw_supported_in_v_blank; + } else { + v->dram_clock_change_support = dcn_bw_not_supported; + } + /*maximum bandwidth used*/ + + v->wr_bandwidth = 0.0; + for (k = 0; k <= v->number_of_active_planes - 1; k++) { + if (v->output[k] == dcn_bw_writeback && v->output_format[k] == dcn_bw_444) { + v->wr_bandwidth = v->wr_bandwidth + + v->scaler_rec_out_width[k] + / (v->htotal[k] / v->pixel_clock[k]) * 4.0; + } else if (v->output[k] == dcn_bw_writeback) { + v->wr_bandwidth = v->wr_bandwidth + + v->scaler_rec_out_width[k] + / (v->htotal[k] / v->pixel_clock[k]) * 1.5; + } + } + v->max_used_bw = v->max_rd_bandwidth + v->wr_bandwidth; +} diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.h b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.h new file mode 100644 index 000000000000..03f06f682ead --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_auto.h @@ -0,0 +1,37 @@ +/* + * 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 _DCN_CALC_AUTO_H_ +#define _DCN_CALC_AUTO_H_ + +#include "dcn_calcs.h" + +void scaler_settings_calculation(struct dcn_bw_internal_vars *v); +void mode_support_and_system_configuration(struct dcn_bw_internal_vars *v); +void display_pipe_configuration(struct dcn_bw_internal_vars *v); +void dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation( + struct dcn_bw_internal_vars *v); + +#endif /* _DCN_CALC_AUTO_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c new file mode 100644 index 000000000000..a18474437990 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.c @@ -0,0 +1,104 @@ +/* + * 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 "dcn_calc_math.h" + +float dcn_bw_mod(const float arg1, const float arg2) +{ + return arg1 - arg1 * ((int) (arg1 / arg2)); +} + +float dcn_bw_min2(const float arg1, const float arg2) +{ + return arg1 < arg2 ? arg1 : arg2; +} + +unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2) +{ + return arg1 > arg2 ? arg1 : arg2; +} +float dcn_bw_max2(const float arg1, const float arg2) +{ + return arg1 > arg2 ? arg1 : arg2; +} + +float dcn_bw_floor2(const float arg, const float significance) +{ + if (significance == 0) + return 0; + return ((int) (arg / significance)) * significance; +} + +float dcn_bw_ceil2(const float arg, const float significance) +{ + float flr = dcn_bw_floor2(arg, significance); + if (significance == 0) + return 0; + return flr + 0.00001 >= arg ? arg : flr + significance; +} + +float dcn_bw_max3(float v1, float v2, float v3) +{ + return v3 > dcn_bw_max2(v1, v2) ? v3 : dcn_bw_max2(v1, v2); +} + +float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5) +{ + return dcn_bw_max3(v1, v2, v3) > dcn_bw_max2(v4, v5) ? dcn_bw_max3(v1, v2, v3) : dcn_bw_max2(v4, v5); +} + +float dcn_bw_pow(float a, float exp) +{ + float temp; + /*ASSERT(exp == (int)exp);*/ + if ((int)exp == 0) + return 1; + temp = dcn_bw_pow(a, (int)(exp / 2)); + if (((int)exp % 2) == 0) { + return temp * temp; + } else { + if ((int)exp > 0) + return a * temp * temp; + else + return (temp * temp) / a; + } +} + +float dcn_bw_log(float a, float b) +{ + int * const exp_ptr = (int *)(&a); + int x = *exp_ptr; + const int log_2 = ((x >> 23) & 255) - 128; + x &= ~(255 << 23); + x += 127 << 23; + *exp_ptr = x; + + a = ((-1.0f / 3) * a + 2) * a - 2.0f / 3; + + if (b > 2.00001 || b < 1.99999) + return (a + log_2) / dcn_bw_log(b, 2); + else + return (a + log_2); +} diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h new file mode 100644 index 000000000000..f46ab0e24ca1 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calc_math.h @@ -0,0 +1,40 @@ +/* + * 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 _DCN_CALC_MATH_H_ +#define _DCN_CALC_MATH_H_ + +float dcn_bw_mod(const float arg1, const float arg2); +float dcn_bw_min2(const float arg1, const float arg2); +unsigned int dcn_bw_max(const unsigned int arg1, const unsigned int arg2); +float dcn_bw_max2(const float arg1, const float arg2); +float dcn_bw_floor2(const float arg, const float significance); +float dcn_bw_ceil2(const float arg, const float significance); +float dcn_bw_max3(float v1, float v2, float v3); +float dcn_bw_max5(float v1, float v2, float v3, float v4, float v5); +float dcn_bw_pow(float a, float exp); +float dcn_bw_log(float a, float b); + +#endif /* _DCN_CALC_MATH_H_ */ diff --git a/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c new file mode 100644 index 000000000000..eb81edf3afa9 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/calcs/dcn_calcs.c @@ -0,0 +1,1366 @@ +/* + * 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 "dm_services.h" +#include "dcn_calcs.h" +#include "dcn_calc_auto.h" +#include "dc.h" +#include "core_dc.h" +#include "dal_asic_id.h" + +#include "resource.h" +#include "dcn10/dcn10_resource.h" +#include "dcn_calc_math.h" + +/* Defaults from spreadsheet rev#247 */ +const struct dcn_soc_bounding_box dcn10_soc_defaults = { + .sr_exit_time = 17, /*us*/ /*update based on HW Request for 118773*/ + .sr_enter_plus_exit_time = 19, /*us*/ + .urgent_latency = 4, /*us*/ + .write_back_latency = 12, /*us*/ + .percent_of_ideal_drambw_received_after_urg_latency = 80, /*%*/ + .max_request_size = 256, /*bytes*/ + .dcfclkv_max0p9 = 600, /*MHz*/ + .dcfclkv_nom0p8 = 600, /*MHz*/ + .dcfclkv_mid0p72 = 300, /*MHz*/ + .dcfclkv_min0p65 = 300, /*MHz*/ + .max_dispclk_vmax0p9 = 1086, /*MHz*/ + .max_dispclk_vnom0p8 = 661, /*MHz*/ + .max_dispclk_vmid0p72 = 608, /*MHz*/ + .max_dispclk_vmin0p65 = 608, /*MHz*/ + .max_dppclk_vmax0p9 = 661, /*MHz*/ + .max_dppclk_vnom0p8 = 661, /*MHz*/ + .max_dppclk_vmid0p72 = 435, /*MHz*/ + .max_dppclk_vmin0p65 = 435, /*MHz*/ + .socclk = 208, /*MHz*/ + .fabric_and_dram_bandwidth_vmax0p9 = 38.4f, /*GB/s*/ + .fabric_and_dram_bandwidth_vnom0p8 = 34.1f, /*GB/s*/ + .fabric_and_dram_bandwidth_vmid0p72 = 29.8f, /*GB/s*/ + .fabric_and_dram_bandwidth_vmin0p65 = 12.8f, /*GB/s*/ + .phyclkv_max0p9 = 810, /*MHz*/ + .phyclkv_nom0p8 = 810, /*MHz*/ + .phyclkv_mid0p72 = 540, /*MHz*/ + .phyclkv_min0p65 = 540, /*MHz*/ + .downspreading = 0.5f, /*%*/ + .round_trip_ping_latency_cycles = 128, /*DCFCLK Cycles*/ + .urgent_out_of_order_return_per_channel = 256, /*bytes*/ + .number_of_channels = 2, + .vmm_page_size = 4096, /*bytes*/ + .dram_clock_change_latency = 17, /*us*/ + .return_bus_width = 64, /*bytes*/ +}; + +const struct dcn_ip_params dcn10_ip_defaults = { + .rob_buffer_size_in_kbyte = 64, + .det_buffer_size_in_kbyte = 164, + .dpp_output_buffer_pixels = 2560, + .opp_output_buffer_lines = 1, + .pixel_chunk_size_in_kbyte = 8, + .pte_enable = dcn_bw_yes, + .pte_chunk_size = 2, /*kbytes*/ + .meta_chunk_size = 2, /*kbytes*/ + .writeback_chunk_size = 2, /*kbytes*/ + .odm_capability = dcn_bw_no, + .dsc_capability = dcn_bw_no, + .line_buffer_size = 589824, /*bit*/ + .max_line_buffer_lines = 12, + .is_line_buffer_bpp_fixed = dcn_bw_no, + .line_buffer_fixed_bpp = dcn_bw_na, + .writeback_luma_buffer_size = 12, /*kbytes*/ + .writeback_chroma_buffer_size = 8, /*kbytes*/ + .max_num_dpp = 4, + .max_num_writeback = 2, + .max_dchub_topscl_throughput = 4, /*pixels/dppclk*/ + .max_pscl_tolb_throughput = 2, /*pixels/dppclk*/ + .max_lb_tovscl_throughput = 4, /*pixels/dppclk*/ + .max_vscl_tohscl_throughput = 4, /*pixels/dppclk*/ + .max_hscl_ratio = 4, + .max_vscl_ratio = 4, + .max_hscl_taps = 8, + .max_vscl_taps = 8, + .pte_buffer_size_in_requests = 42, + .dispclk_ramping_margin = 1, /*%*/ + .under_scan_factor = 1.11f, + .max_inter_dcn_tile_repeaters = 8, + .can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one = dcn_bw_no, + .bug_forcing_luma_and_chroma_request_to_same_size_fixed = dcn_bw_no, + .dcfclk_cstate_latency = 10 /*TODO clone of something else? sr_enter_plus_exit_time?*/ +}; + +static enum dcn_bw_defs tl_sw_mode_to_bw_defs(enum swizzle_mode_values sw_mode) +{ + switch (sw_mode) { + case DC_SW_LINEAR: + return dcn_bw_sw_linear; + case DC_SW_4KB_S: + return dcn_bw_sw_4_kb_s; + case DC_SW_4KB_D: + return dcn_bw_sw_4_kb_d; + case DC_SW_64KB_S: + return dcn_bw_sw_64_kb_s; + case DC_SW_64KB_D: + return dcn_bw_sw_64_kb_d; + case DC_SW_VAR_S: + return dcn_bw_sw_var_s; + case DC_SW_VAR_D: + return dcn_bw_sw_var_d; + case DC_SW_64KB_S_T: + return dcn_bw_sw_64_kb_s_t; + case DC_SW_64KB_D_T: + return dcn_bw_sw_64_kb_d_t; + case DC_SW_4KB_S_X: + return dcn_bw_sw_4_kb_s_x; + case DC_SW_4KB_D_X: + return dcn_bw_sw_4_kb_d_x; + case DC_SW_64KB_S_X: + return dcn_bw_sw_64_kb_s_x; + case DC_SW_64KB_D_X: + return dcn_bw_sw_64_kb_d_x; + case DC_SW_VAR_S_X: + return dcn_bw_sw_var_s_x; + case DC_SW_VAR_D_X: + return dcn_bw_sw_var_d_x; + case DC_SW_256B_S: + case DC_SW_256_D: + case DC_SW_256_R: + case DC_SW_4KB_R: + case DC_SW_64KB_R: + case DC_SW_VAR_R: + case DC_SW_4KB_R_X: + case DC_SW_64KB_R_X: + case DC_SW_VAR_R_X: + default: + BREAK_TO_DEBUGGER(); /*not in formula*/ + return dcn_bw_sw_4_kb_s; + } +} + +static int tl_lb_bpp_to_int(enum lb_pixel_depth depth) +{ + switch (depth) { + case LB_PIXEL_DEPTH_18BPP: + return 18; + case LB_PIXEL_DEPTH_24BPP: + return 24; + case LB_PIXEL_DEPTH_30BPP: + return 30; + case LB_PIXEL_DEPTH_36BPP: + return 36; + default: + return 30; + } +} + +static enum dcn_bw_defs tl_pixel_format_to_bw_defs(enum surface_pixel_format format) +{ + switch (format) { + case SURFACE_PIXEL_FORMAT_GRPH_ARGB1555: + case SURFACE_PIXEL_FORMAT_GRPH_RGB565: + return dcn_bw_rgb_sub_16; + case SURFACE_PIXEL_FORMAT_GRPH_ARGB8888: + case SURFACE_PIXEL_FORMAT_GRPH_ABGR8888: + case SURFACE_PIXEL_FORMAT_GRPH_ARGB2101010: + case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010: + case SURFACE_PIXEL_FORMAT_GRPH_ABGR2101010_XR_BIAS: + return dcn_bw_rgb_sub_32; + case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: + case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: + case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: + return dcn_bw_rgb_sub_64; + case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr: + case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb: + return dcn_bw_yuv420_sub_8; + case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr: + case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb: + return dcn_bw_yuv420_sub_10; + default: + return dcn_bw_rgb_sub_32; + } +} + +static void pipe_ctx_to_e2e_pipe_params ( + const struct pipe_ctx *pipe, + struct _vcs_dpi_display_pipe_params_st *input) +{ + input->src.is_hsplit = false; + if (pipe->top_pipe != NULL && pipe->top_pipe->surface == pipe->surface) + input->src.is_hsplit = true; + else if (pipe->bottom_pipe != NULL && pipe->bottom_pipe->surface == pipe->surface) + input->src.is_hsplit = true; + + input->src.dcc = pipe->surface->public.dcc.enable; + input->src.dcc_rate = 1; + input->src.meta_pitch = pipe->surface->public.dcc.grph.meta_pitch; + input->src.source_scan = dm_horz; + input->src.sw_mode = pipe->surface->public.tiling_info.gfx9.swizzle; + + input->src.viewport_width = pipe->scl_data.viewport.width; + input->src.viewport_height = pipe->scl_data.viewport.height; + input->src.data_pitch = pipe->scl_data.viewport.width; + input->src.data_pitch_c = pipe->scl_data.viewport.width; + input->src.cur0_src_width = 128; /* TODO: Cursor calcs, not curently stored */ + input->src.cur0_bpp = 32; + + switch (pipe->surface->public.tiling_info.gfx9.swizzle) { + /* for 4/8/16 high tiles */ + case DC_SW_LINEAR: + input->src.is_display_sw = 1; + input->src.macro_tile_size = dm_4k_tile; + break; + case DC_SW_4KB_S: + case DC_SW_4KB_S_X: + input->src.is_display_sw = 0; + input->src.macro_tile_size = dm_4k_tile; + break; + case DC_SW_64KB_S: + case DC_SW_64KB_S_X: + input->src.is_display_sw = 0; + input->src.macro_tile_size = dm_64k_tile; + break; + case DC_SW_VAR_S: + case DC_SW_VAR_S_X: + input->src.is_display_sw = 0; + input->src.macro_tile_size = dm_256k_tile; + break; + + /* For 64bpp 2 high tiles */ + case DC_SW_4KB_D: + case DC_SW_4KB_D_X: + input->src.is_display_sw = 1; + input->src.macro_tile_size = dm_4k_tile; + break; + case DC_SW_64KB_D: + case DC_SW_64KB_D_X: + input->src.is_display_sw = 1; + input->src.macro_tile_size = dm_64k_tile; + break; + case DC_SW_VAR_D: + case DC_SW_VAR_D_X: + input->src.is_display_sw = 1; + input->src.macro_tile_size = dm_256k_tile; + break; + + /* Unsupported swizzle modes for dcn */ + case DC_SW_256B_S: + default: + ASSERT(0); /* Not supported */ + break; + } + + switch (pipe->surface->public.rotation) { + case ROTATION_ANGLE_0: + case ROTATION_ANGLE_180: + input->src.source_scan = dm_horz; + break; + case ROTATION_ANGLE_90: + case ROTATION_ANGLE_270: + input->src.source_scan = dm_vert; + break; + default: + ASSERT(0); /* Not supported */ + break; + } + + /* TODO: Fix pixel format mappings */ + switch (pipe->surface->public.format) { + case SURFACE_PIXEL_FORMAT_VIDEO_420_YCbCr: + case SURFACE_PIXEL_FORMAT_VIDEO_420_YCrCb: + input->src.source_format = dm_420_8; + input->src.viewport_width_c = input->src.viewport_width / 2; + input->src.viewport_height_c = input->src.viewport_height / 2; + break; + case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCbCr: + case SURFACE_PIXEL_FORMAT_VIDEO_420_10bpc_YCrCb: + input->src.source_format = dm_420_10; + input->src.viewport_width_c = input->src.viewport_width / 2; + input->src.viewport_height_c = input->src.viewport_height / 2; + break; + case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616: + case SURFACE_PIXEL_FORMAT_GRPH_ARGB16161616F: + case SURFACE_PIXEL_FORMAT_GRPH_ABGR16161616F: + input->src.source_format = dm_444_64; + input->src.viewport_width_c = input->src.viewport_width; + input->src.viewport_height_c = input->src.viewport_height; + break; + default: + input->src.source_format = dm_444_32; + input->src.viewport_width_c = input->src.viewport_width; + input->src.viewport_height_c = input->src.viewport_height; + break; + } + + input->scale_taps.htaps = pipe->scl_data.taps.h_taps; + input->scale_ratio_depth.hscl_ratio = pipe->scl_data.ratios.horz.value/4294967296.0; + input->scale_ratio_depth.vscl_ratio = pipe->scl_data.ratios.vert.value/4294967296.0; + input->scale_ratio_depth.vinit = pipe->scl_data.inits.v.value/4294967296.0; + if (input->scale_ratio_depth.vinit < 1.0) + input->scale_ratio_depth.vinit = 1; + input->scale_taps.vtaps = pipe->scl_data.taps.v_taps; + input->scale_taps.vtaps_c = pipe->scl_data.taps.v_taps_c; + input->scale_taps.htaps_c = pipe->scl_data.taps.h_taps_c; + input->scale_ratio_depth.hscl_ratio_c = pipe->scl_data.ratios.horz_c.value/4294967296.0; + input->scale_ratio_depth.vscl_ratio_c = pipe->scl_data.ratios.vert_c.value/4294967296.0; + input->scale_ratio_depth.vinit_c = pipe->scl_data.inits.v_c.value/4294967296.0; + if (input->scale_ratio_depth.vinit_c < 1.0) + input->scale_ratio_depth.vinit_c = 1; + switch (pipe->scl_data.lb_params.depth) { + case LB_PIXEL_DEPTH_30BPP: + input->scale_ratio_depth.lb_depth = 30; break; + case LB_PIXEL_DEPTH_36BPP: + input->scale_ratio_depth.lb_depth = 36; break; + default: + input->scale_ratio_depth.lb_depth = 24; break; + } + + + input->dest.vactive = pipe->stream->public.timing.v_addressable; + + input->dest.recout_width = pipe->scl_data.recout.width; + input->dest.recout_height = pipe->scl_data.recout.height; + + input->dest.full_recout_width = pipe->scl_data.recout.width; + input->dest.full_recout_height = pipe->scl_data.recout.height; + + input->dest.htotal = pipe->stream->public.timing.h_total; + input->dest.hblank_start = input->dest.htotal - pipe->stream->public.timing.h_front_porch; + input->dest.hblank_end = input->dest.hblank_start + - pipe->stream->public.timing.h_addressable + - pipe->stream->public.timing.h_border_left + - pipe->stream->public.timing.h_border_right; + + input->dest.vtotal = pipe->stream->public.timing.v_total; + input->dest.vblank_start = input->dest.vtotal - pipe->stream->public.timing.v_front_porch; + input->dest.vblank_end = input->dest.vblank_start + - pipe->stream->public.timing.v_addressable + - pipe->stream->public.timing.v_border_bottom + - pipe->stream->public.timing.v_border_top; + + input->dest.vsync_plus_back_porch = pipe->stream->public.timing.v_total + - pipe->stream->public.timing.v_addressable + - pipe->stream->public.timing.v_front_porch; + input->dest.pixel_rate_mhz = pipe->stream->public.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; + input->dest.vupdate_offset = pipe->pipe_dlg_param.vupdate_offset; + input->dest.vupdate_width = pipe->pipe_dlg_param.vupdate_width; + +} + +static void dcn_bw_calc_rq_dlg_ttu( + const struct core_dc *dc, + const struct dcn_bw_internal_vars *v, + struct pipe_ctx *pipe) +{ + struct display_mode_lib *dml = (struct display_mode_lib *)(&dc->dml); + struct _vcs_dpi_display_dlg_regs_st *dlg_regs = &pipe->dlg_regs; + struct _vcs_dpi_display_ttu_regs_st *ttu_regs = &pipe->ttu_regs; + struct _vcs_dpi_display_rq_regs_st *rq_regs = &pipe->rq_regs; + struct _vcs_dpi_display_rq_params_st rq_param = {0}; + struct _vcs_dpi_display_dlg_sys_params_st dlg_sys_param = {0}; + struct _vcs_dpi_display_e2e_pipe_params_st input = { { { 0 } } }; + float total_active_bw = 0; + float total_prefetch_bw = 0; + int total_flip_bytes = 0; + int i; + + for (i = 0; i < number_of_planes; i++) { + total_active_bw += v->read_bandwidth[i]; + total_prefetch_bw += v->prefetch_bandwidth[i]; + total_flip_bytes += v->total_immediate_flip_bytes[i]; + } + dlg_sys_param.total_flip_bw = v->return_bw - dcn_bw_max2(total_active_bw, total_prefetch_bw); + if (dlg_sys_param.total_flip_bw < 0.0) + dlg_sys_param.total_flip_bw = 0; + + dlg_sys_param.t_mclk_wm_us = v->dram_clock_change_watermark; + dlg_sys_param.t_sr_wm_us = v->stutter_enter_plus_exit_watermark; + dlg_sys_param.t_urg_wm_us = v->urgent_watermark; + dlg_sys_param.t_extra_us = v->urgent_extra_latency; + dlg_sys_param.deepsleep_dcfclk_mhz = v->dcf_clk_deep_sleep; + dlg_sys_param.total_flip_bytes = total_flip_bytes; + + pipe_ctx_to_e2e_pipe_params(pipe, &input.pipe); + input.clks_cfg.dcfclk_mhz = v->dcfclk; + input.clks_cfg.dispclk_mhz = v->dispclk; + input.clks_cfg.dppclk_mhz = v->dppclk; + input.clks_cfg.refclk_mhz = dc->res_pool->ref_clock_inKhz/1000; + input.clks_cfg.socclk_mhz = v->socclk; + input.clks_cfg.voltage = v->voltage_level; +// dc->dml.logger = pool->base.logger; + + /*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( + dml, + dlg_regs, + ttu_regs, + rq_param.dlg, + dlg_sys_param, + input, + true, + true, + v->pte_enable == dcn_bw_yes, + pipe->surface->public.flip_immediate); +} + +static void dcn_dml_wm_override( + const struct dcn_bw_internal_vars *v, + struct display_mode_lib *dml, + struct validate_context *context, + const struct resource_pool *pool) +{ + int i, in_idx, active_count; + + struct _vcs_dpi_display_e2e_pipe_params_st *input = dm_alloc(pool->pipe_count * + sizeof(struct _vcs_dpi_display_e2e_pipe_params_st)); + 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->surface) + 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; + 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->watermarks.a.cstate_pstate.cstate_exit_ns = + a.cpstate.cstate_exit_us * 1000; + context->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = + a.cpstate.cstate_enter_plus_exit_us * 1000; + context->watermarks.a.cstate_pstate.pstate_change_ns = + a.cpstate.pstate_change_us * 1000; + context->watermarks.a.pte_meta_urgent_ns = a.pte_meta_urgent * 1000; + context->watermarks.a.urgent_ns = a.urgent * 1000; + context->watermarks.b = context->watermarks.a; + context->watermarks.c = context->watermarks.a; + context->watermarks.d = context->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->surface) + 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->surface->public.flip_immediate); + in_idx++; + } + dm_free(input); +} + +static void split_stream_across_pipes( + struct resource_context *res_ctx, + const struct resource_pool *pool, + struct pipe_ctx *primary_pipe, + struct pipe_ctx *secondary_pipe) +{ + if (!primary_pipe->surface) + return; + + secondary_pipe->stream = primary_pipe->stream; + secondary_pipe->tg = primary_pipe->tg; + + secondary_pipe->mi = pool->mis[secondary_pipe->pipe_idx]; + secondary_pipe->ipp = pool->ipps[secondary_pipe->pipe_idx]; + secondary_pipe->xfm = pool->transforms[secondary_pipe->pipe_idx]; + secondary_pipe->opp = pool->opps[secondary_pipe->pipe_idx]; + if (primary_pipe->bottom_pipe) { + secondary_pipe->bottom_pipe = primary_pipe->bottom_pipe; + secondary_pipe->bottom_pipe->top_pipe = secondary_pipe; + } + primary_pipe->bottom_pipe = secondary_pipe; + secondary_pipe->top_pipe = primary_pipe; + secondary_pipe->surface = primary_pipe->surface; + secondary_pipe->pipe_dlg_param = primary_pipe->pipe_dlg_param; + + resource_build_scaling_params(primary_pipe); + resource_build_scaling_params(secondary_pipe); +} + +static void calc_wm_sets_and_perf_params( + struct validate_context *context, + struct dcn_bw_internal_vars *v) +{ + /* Calculate set A last to keep internal var state consistent for required config */ + if (v->voltage_level < 2) { + v->fabric_and_dram_bandwidth_per_state[1] = v->fabric_and_dram_bandwidth_vnom0p8; + v->fabric_and_dram_bandwidth_per_state[0] = v->fabric_and_dram_bandwidth_vnom0p8; + v->fabric_and_dram_bandwidth = v->fabric_and_dram_bandwidth_vnom0p8; + dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v); + + context->watermarks.b.cstate_pstate.cstate_exit_ns = + v->stutter_exit_watermark * 1000; + context->watermarks.b.cstate_pstate.cstate_enter_plus_exit_ns = + v->stutter_enter_plus_exit_watermark * 1000; + context->watermarks.b.cstate_pstate.pstate_change_ns = + v->dram_clock_change_watermark * 1000; + context->watermarks.b.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; + context->watermarks.b.urgent_ns = v->urgent_watermark * 1000; + + v->dcfclk_per_state[1] = v->dcfclkv_nom0p8; + v->dcfclk_per_state[0] = v->dcfclkv_nom0p8; + v->dcfclk = v->dcfclkv_nom0p8; + dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v); + + context->watermarks.c.cstate_pstate.cstate_exit_ns = + v->stutter_exit_watermark * 1000; + context->watermarks.c.cstate_pstate.cstate_enter_plus_exit_ns = + v->stutter_enter_plus_exit_watermark * 1000; + context->watermarks.c.cstate_pstate.pstate_change_ns = + v->dram_clock_change_watermark * 1000; + context->watermarks.c.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; + context->watermarks.c.urgent_ns = v->urgent_watermark * 1000; + } + + if (v->voltage_level < 3) { + v->fabric_and_dram_bandwidth_per_state[2] = v->fabric_and_dram_bandwidth_vmax0p9; + v->fabric_and_dram_bandwidth_per_state[1] = v->fabric_and_dram_bandwidth_vmax0p9; + v->fabric_and_dram_bandwidth_per_state[0] = v->fabric_and_dram_bandwidth_vmax0p9; + v->fabric_and_dram_bandwidth = v->fabric_and_dram_bandwidth_vmax0p9; + v->dcfclk_per_state[2] = v->dcfclkv_max0p9; + v->dcfclk_per_state[1] = v->dcfclkv_max0p9; + v->dcfclk_per_state[0] = v->dcfclkv_max0p9; + v->dcfclk = v->dcfclkv_max0p9; + dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v); + + context->watermarks.d.cstate_pstate.cstate_exit_ns = + v->stutter_exit_watermark * 1000; + context->watermarks.d.cstate_pstate.cstate_enter_plus_exit_ns = + v->stutter_enter_plus_exit_watermark * 1000; + context->watermarks.d.cstate_pstate.pstate_change_ns = + v->dram_clock_change_watermark * 1000; + context->watermarks.d.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; + context->watermarks.d.urgent_ns = v->urgent_watermark * 1000; + } + + v->fabric_and_dram_bandwidth_per_state[2] = v->fabric_and_dram_bandwidth_vnom0p8; + v->fabric_and_dram_bandwidth_per_state[1] = v->fabric_and_dram_bandwidth_vmid0p72; + v->fabric_and_dram_bandwidth_per_state[0] = v->fabric_and_dram_bandwidth_vmin0p65; + v->fabric_and_dram_bandwidth = v->fabric_and_dram_bandwidth_per_state[v->voltage_level]; + v->dcfclk_per_state[2] = v->dcfclkv_nom0p8; + v->dcfclk_per_state[1] = v->dcfclkv_mid0p72; + v->dcfclk_per_state[0] = v->dcfclkv_min0p65; + v->dcfclk = v->dcfclk_per_state[v->voltage_level]; + dispclkdppclkdcfclk_deep_sleep_prefetch_parameters_watermarks_and_performance_calculation(v); + + context->watermarks.a.cstate_pstate.cstate_exit_ns = + v->stutter_exit_watermark * 1000; + context->watermarks.a.cstate_pstate.cstate_enter_plus_exit_ns = + v->stutter_enter_plus_exit_watermark * 1000; + context->watermarks.a.cstate_pstate.pstate_change_ns = + v->dram_clock_change_watermark * 1000; + context->watermarks.a.pte_meta_urgent_ns = v->ptemeta_urgent_watermark * 1000; + context->watermarks.a.urgent_ns = v->urgent_watermark * 1000; + if (v->voltage_level >= 2) { + context->watermarks.b = context->watermarks.a; + context->watermarks.c = context->watermarks.a; + } + if (v->voltage_level >= 3) + context->watermarks.d = context->watermarks.a; +} + +static void dcn_bw_apply_registry_override(struct core_dc *dc) +{ + kernel_fpu_begin(); + if (dc->public.debug.sr_exit_time_ns) + dc->dcn_soc.sr_exit_time = dc->public.debug.sr_exit_time_ns / 1000.0; + if (dc->public.debug.sr_enter_plus_exit_time_ns) + dc->dcn_soc.sr_enter_plus_exit_time = + dc->public.debug.sr_enter_plus_exit_time_ns / 1000.0; + if (dc->public.debug.urgent_latency_ns) + dc->dcn_soc.urgent_latency = dc->public.debug.urgent_latency_ns / 1000.0; + if (dc->public.debug.percent_of_ideal_drambw) + dc->dcn_soc.percent_of_ideal_drambw_received_after_urg_latency = + dc->public.debug.percent_of_ideal_drambw; + if (dc->public.debug.dram_clock_change_latency_ns) + dc->dcn_soc.dram_clock_change_latency = + dc->public.debug.dram_clock_change_latency_ns / 1000.0; + kernel_fpu_end(); +} + +bool dcn_validate_bandwidth( + const struct core_dc *dc, + struct validate_context *context) +{ + const struct resource_pool *pool = dc->res_pool; + struct dcn_bw_internal_vars *v = &context->dcn_bw_vars; + int i, input_idx; + int vesa_sync_start, asic_blank_end, asic_blank_start; + + dcn_bw_apply_registry_override(DC_TO_CORE(&dc->public)); + + memset(v, 0, sizeof(*v)); + kernel_fpu_begin(); + v->sr_exit_time = dc->dcn_soc.sr_exit_time; + v->sr_enter_plus_exit_time = dc->dcn_soc.sr_enter_plus_exit_time; + v->urgent_latency = dc->dcn_soc.urgent_latency; + v->write_back_latency = dc->dcn_soc.write_back_latency; + v->percent_of_ideal_drambw_received_after_urg_latency = + dc->dcn_soc.percent_of_ideal_drambw_received_after_urg_latency; + + v->dcfclkv_min0p65 = dc->dcn_soc.dcfclkv_min0p65; + v->dcfclkv_mid0p72 = dc->dcn_soc.dcfclkv_mid0p72; + v->dcfclkv_nom0p8 = dc->dcn_soc.dcfclkv_nom0p8; + v->dcfclkv_max0p9 = dc->dcn_soc.dcfclkv_max0p9; + + v->max_dispclk_vmin0p65 = dc->dcn_soc.max_dispclk_vmin0p65; + v->max_dispclk_vmid0p72 = dc->dcn_soc.max_dispclk_vmid0p72; + v->max_dispclk_vnom0p8 = dc->dcn_soc.max_dispclk_vnom0p8; + v->max_dispclk_vmax0p9 = dc->dcn_soc.max_dispclk_vmax0p9; + + v->max_dppclk_vmin0p65 = dc->dcn_soc.max_dppclk_vmin0p65; + v->max_dppclk_vmid0p72 = dc->dcn_soc.max_dppclk_vmid0p72; + v->max_dppclk_vnom0p8 = dc->dcn_soc.max_dppclk_vnom0p8; + v->max_dppclk_vmax0p9 = dc->dcn_soc.max_dppclk_vmax0p9; + + v->socclk = dc->dcn_soc.socclk; + + v->fabric_and_dram_bandwidth_vmin0p65 = dc->dcn_soc.fabric_and_dram_bandwidth_vmin0p65; + v->fabric_and_dram_bandwidth_vmid0p72 = dc->dcn_soc.fabric_and_dram_bandwidth_vmid0p72; + v->fabric_and_dram_bandwidth_vnom0p8 = dc->dcn_soc.fabric_and_dram_bandwidth_vnom0p8; + v->fabric_and_dram_bandwidth_vmax0p9 = dc->dcn_soc.fabric_and_dram_bandwidth_vmax0p9; + + v->phyclkv_min0p65 = dc->dcn_soc.phyclkv_min0p65; + v->phyclkv_mid0p72 = dc->dcn_soc.phyclkv_mid0p72; + v->phyclkv_nom0p8 = dc->dcn_soc.phyclkv_nom0p8; + v->phyclkv_max0p9 = dc->dcn_soc.phyclkv_max0p9; + + v->downspreading = dc->dcn_soc.downspreading; + v->round_trip_ping_latency_cycles = dc->dcn_soc.round_trip_ping_latency_cycles; + v->urgent_out_of_order_return_per_channel = dc->dcn_soc.urgent_out_of_order_return_per_channel; + v->number_of_channels = dc->dcn_soc.number_of_channels; + v->vmm_page_size = dc->dcn_soc.vmm_page_size; + v->dram_clock_change_latency = dc->dcn_soc.dram_clock_change_latency; + v->return_bus_width = dc->dcn_soc.return_bus_width; + + v->rob_buffer_size_in_kbyte = dc->dcn_ip.rob_buffer_size_in_kbyte; + v->det_buffer_size_in_kbyte = dc->dcn_ip.det_buffer_size_in_kbyte; + v->dpp_output_buffer_pixels = dc->dcn_ip.dpp_output_buffer_pixels; + v->opp_output_buffer_lines = dc->dcn_ip.opp_output_buffer_lines; + v->pixel_chunk_size_in_kbyte = dc->dcn_ip.pixel_chunk_size_in_kbyte; + v->pte_enable = dc->dcn_ip.pte_enable; + v->pte_chunk_size = dc->dcn_ip.pte_chunk_size; + v->meta_chunk_size = dc->dcn_ip.meta_chunk_size; + v->writeback_chunk_size = dc->dcn_ip.writeback_chunk_size; + v->odm_capability = dc->dcn_ip.odm_capability; + v->dsc_capability = dc->dcn_ip.dsc_capability; + v->line_buffer_size = dc->dcn_ip.line_buffer_size; + v->is_line_buffer_bpp_fixed = dc->dcn_ip.is_line_buffer_bpp_fixed; + v->line_buffer_fixed_bpp = dc->dcn_ip.line_buffer_fixed_bpp; + v->max_line_buffer_lines = dc->dcn_ip.max_line_buffer_lines; + v->writeback_luma_buffer_size = dc->dcn_ip.writeback_luma_buffer_size; + v->writeback_chroma_buffer_size = dc->dcn_ip.writeback_chroma_buffer_size; + v->max_num_dpp = dc->dcn_ip.max_num_dpp; + v->max_num_writeback = dc->dcn_ip.max_num_writeback; + v->max_dchub_topscl_throughput = dc->dcn_ip.max_dchub_topscl_throughput; + v->max_pscl_tolb_throughput = dc->dcn_ip.max_pscl_tolb_throughput; + v->max_lb_tovscl_throughput = dc->dcn_ip.max_lb_tovscl_throughput; + v->max_vscl_tohscl_throughput = dc->dcn_ip.max_vscl_tohscl_throughput; + v->max_hscl_ratio = dc->dcn_ip.max_hscl_ratio; + v->max_vscl_ratio = dc->dcn_ip.max_vscl_ratio; + v->max_hscl_taps = dc->dcn_ip.max_hscl_taps; + v->max_vscl_taps = dc->dcn_ip.max_vscl_taps; + v->under_scan_factor = dc->dcn_ip.under_scan_factor; + v->pte_buffer_size_in_requests = dc->dcn_ip.pte_buffer_size_in_requests; + v->dispclk_ramping_margin = dc->dcn_ip.dispclk_ramping_margin; + v->max_inter_dcn_tile_repeaters = dc->dcn_ip.max_inter_dcn_tile_repeaters; + v->can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one = + dc->dcn_ip.can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one; + v->bug_forcing_luma_and_chroma_request_to_same_size_fixed = + dc->dcn_ip.bug_forcing_luma_and_chroma_request_to_same_size_fixed; + + v->voltage[5] = dcn_bw_no_support; + v->voltage[4] = dcn_bw_v_max0p9; + v->voltage[3] = dcn_bw_v_max0p9; + v->voltage[2] = dcn_bw_v_nom0p8; + v->voltage[1] = dcn_bw_v_mid0p72; + v->voltage[0] = dcn_bw_v_min0p65; + v->fabric_and_dram_bandwidth_per_state[5] = v->fabric_and_dram_bandwidth_vmax0p9; + v->fabric_and_dram_bandwidth_per_state[4] = v->fabric_and_dram_bandwidth_vmax0p9; + v->fabric_and_dram_bandwidth_per_state[3] = v->fabric_and_dram_bandwidth_vmax0p9; + v->fabric_and_dram_bandwidth_per_state[2] = v->fabric_and_dram_bandwidth_vnom0p8; + v->fabric_and_dram_bandwidth_per_state[1] = v->fabric_and_dram_bandwidth_vmid0p72; + v->fabric_and_dram_bandwidth_per_state[0] = v->fabric_and_dram_bandwidth_vmin0p65; + v->dcfclk_per_state[5] = v->dcfclkv_max0p9; + v->dcfclk_per_state[4] = v->dcfclkv_max0p9; + v->dcfclk_per_state[3] = v->dcfclkv_max0p9; + v->dcfclk_per_state[2] = v->dcfclkv_nom0p8; + v->dcfclk_per_state[1] = v->dcfclkv_mid0p72; + v->dcfclk_per_state[0] = v->dcfclkv_min0p65; + v->max_dispclk[5] = v->max_dispclk_vmax0p9; + v->max_dispclk[4] = v->max_dispclk_vmax0p9; + v->max_dispclk[3] = v->max_dispclk_vmax0p9; + v->max_dispclk[2] = v->max_dispclk_vnom0p8; + v->max_dispclk[1] = v->max_dispclk_vmid0p72; + v->max_dispclk[0] = v->max_dispclk_vmin0p65; + v->max_dppclk[5] = v->max_dppclk_vmax0p9; + v->max_dppclk[4] = v->max_dppclk_vmax0p9; + v->max_dppclk[3] = v->max_dppclk_vmax0p9; + v->max_dppclk[2] = v->max_dppclk_vnom0p8; + v->max_dppclk[1] = v->max_dppclk_vmid0p72; + v->max_dppclk[0] = v->max_dppclk_vmin0p65; + v->phyclk_per_state[5] = v->phyclkv_max0p9; + v->phyclk_per_state[4] = v->phyclkv_max0p9; + v->phyclk_per_state[3] = v->phyclkv_max0p9; + v->phyclk_per_state[2] = v->phyclkv_nom0p8; + v->phyclk_per_state[1] = v->phyclkv_mid0p72; + v->phyclk_per_state[0] = v->phyclkv_min0p65; + + if (dc->public.debug.use_max_voltage) { + v->max_dppclk[1] = v->max_dppclk_vnom0p8; + v->max_dppclk[0] = v->max_dppclk_vnom0p8; + } + + if (v->voltage_override == dcn_bw_v_max0p9) { + v->voltage_override_level = number_of_states - 1; + } else if (v->voltage_override == dcn_bw_v_nom0p8) { + v->voltage_override_level = number_of_states - 2; + } else if (v->voltage_override == dcn_bw_v_mid0p72) { + v->voltage_override_level = number_of_states - 3; + } else { + v->voltage_override_level = 0; + } + v->synchronized_vblank = dcn_bw_no; + v->ta_pscalculation = dcn_bw_override; + v->allow_different_hratio_vratio = dcn_bw_yes; + + + for (i = 0, input_idx = 0; i < pool->pipe_count; i++) { + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + + if (!pipe->stream) + continue; + /* skip all but first of split pipes */ + if (pipe->top_pipe && pipe->top_pipe->surface == pipe->surface) + continue; + + v->underscan_output[input_idx] = false; /* taken care of in recout already*/ + v->interlace_output[input_idx] = false; + + v->htotal[input_idx] = pipe->stream->public.timing.h_total; + v->vtotal[input_idx] = pipe->stream->public.timing.v_total; + v->v_sync_plus_back_porch[input_idx] = pipe->stream->public.timing.v_total + - pipe->stream->public.timing.v_addressable + - pipe->stream->public.timing.v_front_porch; + v->vactive[input_idx] = pipe->stream->public.timing.v_addressable; + v->pixel_clock[input_idx] = pipe->stream->public.timing.pix_clk_khz / 1000.0f; + + + if (!pipe->surface){ + v->dcc_enable[input_idx] = dcn_bw_yes; + v->source_pixel_format[input_idx] = dcn_bw_rgb_sub_32; + v->source_surface_mode[input_idx] = dcn_bw_sw_4_kb_s; + v->lb_bit_per_pixel[input_idx] = 30; + v->viewport_width[input_idx] = pipe->stream->public.timing.h_addressable; + v->viewport_height[input_idx] = pipe->stream->public.timing.v_addressable; + v->scaler_rec_out_width[input_idx] = pipe->stream->public.timing.h_addressable; + v->scaler_recout_height[input_idx] = pipe->stream->public.timing.v_addressable; + v->override_hta_ps[input_idx] = 1; + v->override_vta_ps[input_idx] = 1; + v->override_hta_pschroma[input_idx] = 1; + v->override_vta_pschroma[input_idx] = 1; + v->source_scan[input_idx] = dcn_bw_hor; + + } else { + v->viewport_height[input_idx] = pipe->scl_data.viewport.height; + v->viewport_width[input_idx] = pipe->scl_data.viewport.width; + v->scaler_rec_out_width[input_idx] = pipe->scl_data.recout.width; + v->scaler_recout_height[input_idx] = pipe->scl_data.recout.height; + if (pipe->bottom_pipe && pipe->bottom_pipe->surface == pipe->surface) { + if (pipe->surface->public.rotation % 2 == 0) { + int viewport_end = pipe->scl_data.viewport.width + + pipe->scl_data.viewport.x; + int viewport_b_end = pipe->bottom_pipe->scl_data.viewport.width + + pipe->bottom_pipe->scl_data.viewport.x; + + if (viewport_end > viewport_b_end) + v->viewport_width[input_idx] = viewport_end + - pipe->bottom_pipe->scl_data.viewport.x; + else + v->viewport_width[input_idx] = viewport_b_end + - pipe->scl_data.viewport.x; + } else { + int viewport_end = pipe->scl_data.viewport.height + + pipe->scl_data.viewport.y; + int viewport_b_end = pipe->bottom_pipe->scl_data.viewport.height + + pipe->bottom_pipe->scl_data.viewport.y; + + if (viewport_end > viewport_b_end) + v->viewport_height[input_idx] = viewport_end + - pipe->bottom_pipe->scl_data.viewport.y; + else + v->viewport_height[input_idx] = viewport_b_end + - pipe->scl_data.viewport.y; + } + v->scaler_rec_out_width[input_idx] = pipe->scl_data.recout.width + + pipe->bottom_pipe->scl_data.recout.width; + } + + v->dcc_enable[input_idx] = pipe->surface->public.dcc.enable ? dcn_bw_yes : dcn_bw_no; + v->source_pixel_format[input_idx] = tl_pixel_format_to_bw_defs( + pipe->surface->public.format); + v->source_surface_mode[input_idx] = tl_sw_mode_to_bw_defs( + pipe->surface->public.tiling_info.gfx9.swizzle); + v->lb_bit_per_pixel[input_idx] = tl_lb_bpp_to_int(pipe->scl_data.lb_params.depth); + v->override_hta_ps[input_idx] = pipe->scl_data.taps.h_taps; + v->override_vta_ps[input_idx] = pipe->scl_data.taps.v_taps; + v->override_hta_pschroma[input_idx] = pipe->scl_data.taps.h_taps_c; + v->override_vta_pschroma[input_idx] = pipe->scl_data.taps.v_taps_c; + v->source_scan[input_idx] = (pipe->surface->public.rotation % 2) ? dcn_bw_vert : dcn_bw_hor; + } + if (v->is_line_buffer_bpp_fixed == dcn_bw_yes) + v->lb_bit_per_pixel[input_idx] = v->line_buffer_fixed_bpp; + v->dcc_rate[input_idx] = 1; /*TODO: Worst case? does this change?*/ + v->output_format[input_idx] = dcn_bw_444; + v->output[input_idx] = dcn_bw_dp; + + input_idx++; + } + v->number_of_active_planes = input_idx; + + scaler_settings_calculation(v); + mode_support_and_system_configuration(v); + + if (v->voltage_level != 5) { + float bw_consumed = v->total_bandwidth_consumed_gbyte_per_second; + if (bw_consumed < v->fabric_and_dram_bandwidth_vmin0p65) + bw_consumed = v->fabric_and_dram_bandwidth_vmin0p65; + else if (bw_consumed < v->fabric_and_dram_bandwidth_vmid0p72) + bw_consumed = v->fabric_and_dram_bandwidth_vmid0p72; + else if (bw_consumed < v->fabric_and_dram_bandwidth_vnom0p8) + bw_consumed = v->fabric_and_dram_bandwidth_vnom0p8; + else + bw_consumed = v->fabric_and_dram_bandwidth_vmax0p9; + + display_pipe_configuration(v); + calc_wm_sets_and_perf_params(context, v); + context->fclk_khz = (int)(bw_consumed * 1000000 / + (ddr4_dram_factor_single_Channel * v->number_of_channels)); + context->dram_ccm_us = (int)(v->dram_clock_change_margin); + context->min_active_dram_ccm_us = (int)(v->min_active_dram_clock_change_margin); + context->dcfclk_deep_sleep_khz = (int)(v->dcf_clk_deep_sleep * 1000); + context->dcfclk_khz = (int)(v->dcfclk * 1000); + context->dispclk_khz = (int)(v->dispclk * 1000); + if (dc->public.debug.max_disp_clk == true) + context->dispclk_khz = (int)(dc->dcn_soc.max_dispclk_vmax0p9 * 1000); + context->dppclk_khz = (int)(v->dppclk * 1000); + context->dppclk_div = (int)(v->dispclk_dppclk_ratio) == 2; + + for (i = 0, input_idx = 0; i < pool->pipe_count; i++) { + struct pipe_ctx *pipe = &context->res_ctx.pipe_ctx[i]; + + /* skip inactive pipe */ + if (!pipe->stream) + continue; + /* skip all but first of split pipes */ + if (pipe->top_pipe && pipe->top_pipe->surface == pipe->surface) + continue; + + pipe->pipe_dlg_param.vupdate_width = v->v_update_width[input_idx]; + pipe->pipe_dlg_param.vupdate_offset = v->v_update_offset[input_idx]; + pipe->pipe_dlg_param.vready_offset = v->v_ready_offset[input_idx]; + pipe->pipe_dlg_param.vstartup_start = v->v_startup[input_idx]; + + pipe->pipe_dlg_param.htotal = pipe->stream->public.timing.h_total; + pipe->pipe_dlg_param.vtotal = pipe->stream->public.timing.v_total; + vesa_sync_start = pipe->stream->public.timing.v_addressable + + pipe->stream->public.timing.v_border_bottom + + pipe->stream->public.timing.v_front_porch; + + asic_blank_end = (pipe->stream->public.timing.v_total - + vesa_sync_start - + pipe->stream->public.timing.v_border_top) + * (pipe->stream->public.timing.flags.INTERLACE ? 1 : 0); + + asic_blank_start = asic_blank_end + + (pipe->stream->public.timing.v_border_top + + pipe->stream->public.timing.v_addressable + + pipe->stream->public.timing.v_border_bottom) + * (pipe->stream->public.timing.flags.INTERLACE ? 1 : 0); + + pipe->pipe_dlg_param.vblank_start = asic_blank_start; + pipe->pipe_dlg_param.vblank_end = asic_blank_end; + + if (pipe->surface) { + struct pipe_ctx *hsplit_pipe = pipe->bottom_pipe; + + if (v->dpp_per_plane[input_idx] == 2 || + (pipe->stream->public.timing.timing_3d_format == TIMING_3D_FORMAT_TOP_AND_BOTTOM || + pipe->stream->public.timing.timing_3d_format == TIMING_3D_FORMAT_SIDE_BY_SIDE)) { + if (hsplit_pipe && hsplit_pipe->surface == pipe->surface) { + /* update previously split pipe */ + hsplit_pipe->pipe_dlg_param.vupdate_width = v->v_update_width[input_idx]; + hsplit_pipe->pipe_dlg_param.vupdate_offset = v->v_update_offset[input_idx]; + hsplit_pipe->pipe_dlg_param.vready_offset = v->v_ready_offset[input_idx]; + hsplit_pipe->pipe_dlg_param.vstartup_start = v->v_startup[input_idx]; + + hsplit_pipe->pipe_dlg_param.htotal = pipe->stream->public.timing.h_total; + hsplit_pipe->pipe_dlg_param.vtotal = pipe->stream->public.timing.v_total; + hsplit_pipe->pipe_dlg_param.vblank_start = pipe->pipe_dlg_param.vblank_start; + hsplit_pipe->pipe_dlg_param.vblank_end = pipe->pipe_dlg_param.vblank_end; + } else { + /* pipe not split previously needs split */ + hsplit_pipe = find_idle_secondary_pipe(&context->res_ctx, pool); + ASSERT(hsplit_pipe); + split_stream_across_pipes( + &context->res_ctx, pool, + pipe, hsplit_pipe); + } + + dcn_bw_calc_rq_dlg_ttu(dc, v, hsplit_pipe); + } else if (hsplit_pipe && hsplit_pipe->surface == pipe->surface) { + /* merge previously split pipe */ + if (pipe->bottom_pipe->bottom_pipe) + pipe->bottom_pipe->bottom_pipe->top_pipe = pipe; + memset(pipe->bottom_pipe, 0, sizeof(*pipe->bottom_pipe)); + pipe->bottom_pipe = pipe->bottom_pipe->bottom_pipe; + resource_build_scaling_params(pipe); + } + /* for now important to do this after pipe split for building e2e params */ + dcn_bw_calc_rq_dlg_ttu(dc, v, pipe); + } + + input_idx++; + } + if (dc->public.debug.use_dml_wm) + dcn_dml_wm_override(v, (struct display_mode_lib *) + &dc->dml, context, pool); + } + + kernel_fpu_end(); + return v->voltage_level != 5; +} + +unsigned int dcn_find_normalized_clock_vdd_Level( + const struct core_dc *dc, + enum dm_pp_clock_type clocks_type, + int clocks_in_khz) +{ + int vdd_level = dcn_bw_v_min0p65; + + if (clocks_in_khz == 0)/*todo some clock not in the considerations*/ + return vdd_level; + + switch (clocks_type) { + case DM_PP_CLOCK_TYPE_DISPLAY_CLK: + if (clocks_in_khz > dc->dcn_soc.max_dispclk_vmax0p9*1000) { + vdd_level = dcn_bw_v_max0p91; + BREAK_TO_DEBUGGER(); + } else if (clocks_in_khz > dc->dcn_soc.max_dispclk_vnom0p8*1000) { + vdd_level = dcn_bw_v_max0p9; + } else if (clocks_in_khz > dc->dcn_soc.max_dispclk_vmid0p72*1000) { + vdd_level = dcn_bw_v_nom0p8; + } else if (clocks_in_khz > dc->dcn_soc.max_dispclk_vmin0p65*1000) { + vdd_level = dcn_bw_v_mid0p72; + } else + vdd_level = dcn_bw_v_min0p65; + break; + case DM_PP_CLOCK_TYPE_DISPLAYPHYCLK: + if (clocks_in_khz > dc->dcn_soc.phyclkv_max0p9*1000) { + vdd_level = dcn_bw_v_max0p91; + BREAK_TO_DEBUGGER(); + } else if (clocks_in_khz > dc->dcn_soc.phyclkv_nom0p8*1000) { + vdd_level = dcn_bw_v_max0p9; + } else if (clocks_in_khz > dc->dcn_soc.phyclkv_mid0p72*1000) { + vdd_level = dcn_bw_v_nom0p8; + } else if (clocks_in_khz > dc->dcn_soc.phyclkv_min0p65*1000) { + vdd_level = dcn_bw_v_mid0p72; + } else + vdd_level = dcn_bw_v_min0p65; + break; + + case DM_PP_CLOCK_TYPE_DPPCLK: + if (clocks_in_khz > dc->dcn_soc.max_dppclk_vmax0p9*1000) { + vdd_level = dcn_bw_v_max0p91; + BREAK_TO_DEBUGGER(); + } else if (clocks_in_khz > dc->dcn_soc.max_dppclk_vnom0p8*1000) { + vdd_level = dcn_bw_v_max0p9; + } else if (clocks_in_khz > dc->dcn_soc.max_dppclk_vmid0p72*1000) { + vdd_level = dcn_bw_v_nom0p8; + } else if (clocks_in_khz > dc->dcn_soc.max_dppclk_vmin0p65*1000) { + vdd_level = dcn_bw_v_mid0p72; + } else + vdd_level = dcn_bw_v_min0p65; + break; + + case DM_PP_CLOCK_TYPE_MEMORY_CLK: + { + unsigned factor = (ddr4_dram_factor_single_Channel * dc->dcn_soc.number_of_channels); + if (clocks_in_khz > dc->dcn_soc.fabric_and_dram_bandwidth_vmax0p9*1000000/factor) { + vdd_level = dcn_bw_v_max0p91; + BREAK_TO_DEBUGGER(); + } else if (clocks_in_khz > dc->dcn_soc.fabric_and_dram_bandwidth_vnom0p8*1000000/factor) { + vdd_level = dcn_bw_v_max0p9; + } else if (clocks_in_khz > dc->dcn_soc.fabric_and_dram_bandwidth_vmid0p72*1000000/factor) { + vdd_level = dcn_bw_v_nom0p8; + } else if (clocks_in_khz > dc->dcn_soc.fabric_and_dram_bandwidth_vmin0p65*1000000/factor) { + vdd_level = dcn_bw_v_mid0p72; + } else + vdd_level = dcn_bw_v_min0p65; + } + break; + + case DM_PP_CLOCK_TYPE_DCFCLK: + if (clocks_in_khz > dc->dcn_soc.dcfclkv_max0p9*1000) { + vdd_level = dcn_bw_v_max0p91; + BREAK_TO_DEBUGGER(); + } else if (clocks_in_khz > dc->dcn_soc.dcfclkv_nom0p8*1000) { + vdd_level = dcn_bw_v_max0p9; + } else if (clocks_in_khz > dc->dcn_soc.dcfclkv_mid0p72*1000) { + vdd_level = dcn_bw_v_nom0p8; + } else if (clocks_in_khz > dc->dcn_soc.dcfclkv_min0p65*1000) { + vdd_level = dcn_bw_v_mid0p72; + } else + vdd_level = dcn_bw_v_min0p65; + break; + + default: + break; + } + return vdd_level; +} + +unsigned int dcn_find_dcfclk_suits_all( + const struct core_dc *dc, + struct clocks_value *clocks) +{ + unsigned vdd_level, vdd_level_temp; + unsigned dcf_clk; + + /*find a common supported voltage level*/ + vdd_level = dcn_find_normalized_clock_vdd_Level( + dc, DM_PP_CLOCK_TYPE_DISPLAY_CLK, clocks->dispclk_in_khz); + vdd_level_temp = dcn_find_normalized_clock_vdd_Level( + dc, DM_PP_CLOCK_TYPE_DISPLAYPHYCLK, clocks->phyclk_in_khz); + + vdd_level = dcn_bw_max(vdd_level, vdd_level_temp); + vdd_level_temp = dcn_find_normalized_clock_vdd_Level( + dc, DM_PP_CLOCK_TYPE_DPPCLK, clocks->dppclk_in_khz); + vdd_level = dcn_bw_max(vdd_level, vdd_level_temp); + + vdd_level_temp = dcn_find_normalized_clock_vdd_Level( + dc, DM_PP_CLOCK_TYPE_MEMORY_CLK, clocks->dcfclock_in_khz); + vdd_level = dcn_bw_max(vdd_level, vdd_level_temp); + vdd_level_temp = dcn_find_normalized_clock_vdd_Level( + dc, DM_PP_CLOCK_TYPE_DCFCLK, clocks->dcfclock_in_khz); + + /*find that level conresponding dcfclk*/ + vdd_level = dcn_bw_max(vdd_level, vdd_level_temp); + if (vdd_level == dcn_bw_v_max0p91) { + BREAK_TO_DEBUGGER(); + dcf_clk = dc->dcn_soc.dcfclkv_max0p9*1000; + } else if (vdd_level == dcn_bw_v_max0p9) + dcf_clk = dc->dcn_soc.dcfclkv_max0p9*1000; + else if (vdd_level == dcn_bw_v_nom0p8) + dcf_clk = dc->dcn_soc.dcfclkv_nom0p8*1000; + else if (vdd_level == dcn_bw_v_mid0p72) + dcf_clk = dc->dcn_soc.dcfclkv_mid0p72*1000; + else + dcf_clk = dc->dcn_soc.dcfclkv_min0p65*1000; + + dm_logger_write(dc->ctx->logger, LOG_HW_MARKS, + "\tdcf_clk for voltage = %d\n", dcf_clk); + return dcf_clk; +} + +void dcn_bw_update_from_pplib(struct core_dc *dc) +{ + struct dc_context *ctx = dc->ctx; + struct dm_pp_clock_levels_with_latency clks = {0}; + struct dm_pp_clock_levels_with_voltage clks2 = {0}; + + kernel_fpu_begin(); + dc->dcn_soc.number_of_channels = dc->ctx->asic_id.vram_width / ddr4_dram_width; + ASSERT(dc->dcn_soc.number_of_channels && dc->dcn_soc.number_of_channels < 3); + if (dc->dcn_soc.number_of_channels == 0)/*old sbios bug*/ + dc->dcn_soc.number_of_channels = 2; + + if (dm_pp_get_clock_levels_by_type_with_voltage( + ctx, DM_PP_CLOCK_TYPE_DISPLAY_CLK, &clks2) && + clks2.num_levels >= 3) { + dc->dcn_soc.max_dispclk_vmin0p65 = clks2.data[0].clocks_in_khz / 1000.0; + dc->dcn_soc.max_dispclk_vmid0p72 = clks2.data[clks2.num_levels - 3].clocks_in_khz / 1000.0; + dc->dcn_soc.max_dispclk_vnom0p8 = clks2.data[clks2.num_levels - 2].clocks_in_khz / 1000.0; + dc->dcn_soc.max_dispclk_vmax0p9 = clks2.data[clks2.num_levels - 1].clocks_in_khz / 1000.0; + } else + BREAK_TO_DEBUGGER(); +/* + if (dm_pp_get_clock_levels_by_type_with_latency( + ctx, DM_PP_CLOCK_TYPE_MEMORY_CLK, &clks) && + clks.num_levels != 0) { + //this is to get DRAM data_rate + //FabricAndDRAMBandwidth = min(64*FCLK , Data rate * single_Channel_Width * number of channels); + }*/ + if (dm_pp_get_clock_levels_by_type_with_latency( + ctx, DM_PP_CLOCK_TYPE_FCLK, &clks) && + clks.num_levels != 0) { + ASSERT(clks.num_levels >= 3); + dc->dcn_soc.fabric_and_dram_bandwidth_vmin0p65 = dc->dcn_soc.number_of_channels * + (clks.data[0].clocks_in_khz / 1000.0) * ddr4_dram_factor_single_Channel / 1000.0; + if (clks.num_levels > 2) { + dc->dcn_soc.fabric_and_dram_bandwidth_vmid0p72 = dc->dcn_soc.number_of_channels * + (clks.data[clks.num_levels - 3].clocks_in_khz / 1000.0) * ddr4_dram_factor_single_Channel / 1000.0; + } else { + dc->dcn_soc.fabric_and_dram_bandwidth_vmid0p72 = dc->dcn_soc.number_of_channels * + (clks.data[clks.num_levels - 2].clocks_in_khz / 1000.0) * ddr4_dram_factor_single_Channel / 1000.0; + } + dc->dcn_soc.fabric_and_dram_bandwidth_vnom0p8 = dc->dcn_soc.number_of_channels * + (clks.data[clks.num_levels - 2].clocks_in_khz / 1000.0) * ddr4_dram_factor_single_Channel / 1000.0; + dc->dcn_soc.fabric_and_dram_bandwidth_vmax0p9 = dc->dcn_soc.number_of_channels * + (clks.data[clks.num_levels - 1].clocks_in_khz / 1000.0) * ddr4_dram_factor_single_Channel / 1000.0; + } else + BREAK_TO_DEBUGGER(); + if (dm_pp_get_clock_levels_by_type_with_latency( + ctx, DM_PP_CLOCK_TYPE_DCFCLK, &clks) && + clks.num_levels >= 3) { + dc->dcn_soc.dcfclkv_min0p65 = clks.data[0].clocks_in_khz / 1000.0; + dc->dcn_soc.dcfclkv_mid0p72 = clks.data[clks.num_levels - 3].clocks_in_khz / 1000.0; + dc->dcn_soc.dcfclkv_nom0p8 = clks.data[clks.num_levels - 2].clocks_in_khz / 1000.0; + dc->dcn_soc.dcfclkv_max0p9 = clks.data[clks.num_levels - 1].clocks_in_khz / 1000.0; + } else + BREAK_TO_DEBUGGER(); + if (dm_pp_get_clock_levels_by_type_with_voltage( + ctx, DM_PP_CLOCK_TYPE_DISPLAYPHYCLK, &clks2) && + clks2.num_levels >= 3) { + dc->dcn_soc.phyclkv_min0p65 = clks2.data[0].clocks_in_khz / 1000.0; + dc->dcn_soc.phyclkv_mid0p72 = clks2.data[clks2.num_levels - 3].clocks_in_khz / 1000.0; + dc->dcn_soc.phyclkv_nom0p8 = clks2.data[clks2.num_levels - 2].clocks_in_khz / 1000.0; + dc->dcn_soc.phyclkv_max0p9 = clks2.data[clks2.num_levels - 1].clocks_in_khz / 1000.0; + } else + BREAK_TO_DEBUGGER(); + if (dm_pp_get_clock_levels_by_type_with_latency( + ctx, DM_PP_CLOCK_TYPE_DPPCLK, &clks) && + clks.num_levels >= 3) { + dc->dcn_soc.max_dppclk_vmin0p65 = clks.data[0].clocks_in_khz / 1000.0; + dc->dcn_soc.max_dppclk_vmid0p72 = clks.data[clks.num_levels - 3].clocks_in_khz / 1000.0; + dc->dcn_soc.max_dppclk_vnom0p8 = clks.data[clks.num_levels - 2].clocks_in_khz / 1000.0; + dc->dcn_soc.max_dppclk_vmax0p9 = clks.data[clks.num_levels - 1].clocks_in_khz / 1000.0; + } + + if (dm_pp_get_clock_levels_by_type_with_latency( + ctx, DM_PP_CLOCK_TYPE_SOCCLK, &clks) && + clks.num_levels >= 3) { + dc->dcn_soc.socclk = clks.data[0].clocks_in_khz / 1000.0; + } else + BREAK_TO_DEBUGGER(); + kernel_fpu_end(); +} + +void dcn_bw_notify_pplib_of_wm_ranges(struct core_dc *dc) +{ + struct dm_pp_wm_sets_with_clock_ranges_soc15 clk_ranges = {0}; + int max_fclk_khz, nom_fclk_khz, min_fclk_khz, max_dcfclk_khz, + nom_dcfclk_khz, min_dcfclk_khz, socclk_khz; + const int overdrive = 5000000; /* 5 GHz to cover Overdrive */ + unsigned factor = (ddr4_dram_factor_single_Channel * dc->dcn_soc.number_of_channels); + + kernel_fpu_begin(); + max_fclk_khz = dc->dcn_soc.fabric_and_dram_bandwidth_vmax0p9 * 1000000 / factor; + nom_fclk_khz = dc->dcn_soc.fabric_and_dram_bandwidth_vnom0p8 * 1000000 / factor; + min_fclk_khz = dc->dcn_soc.fabric_and_dram_bandwidth_vmin0p65 * 1000000 / factor; + max_dcfclk_khz = dc->dcn_soc.dcfclkv_max0p9 * 1000; + nom_dcfclk_khz = dc->dcn_soc.dcfclkv_nom0p8 * 1000; + min_dcfclk_khz = dc->dcn_soc.dcfclkv_min0p65 * 1000; + socclk_khz = dc->dcn_soc.socclk * 1000; + kernel_fpu_end(); + + /* Now notify PPLib/SMU about which Watermarks sets they should select + * depending on DPM state they are in. And update BW MGR GFX Engine and + * Memory clock member variables for Watermarks calculations for each + * Watermark Set + */ + /* SOCCLK does not affect anytihng but writeback for DCN so for now we dont + * care what the value is, hence min to overdrive level + */ + clk_ranges.num_wm_dmif_sets = 4; + clk_ranges.num_wm_mcif_sets = 4; + clk_ranges.wm_dmif_clocks_ranges[0].wm_set_id = WM_SET_A; + clk_ranges.wm_dmif_clocks_ranges[0].wm_min_dcfclk_clk_in_khz = min_dcfclk_khz; + clk_ranges.wm_dmif_clocks_ranges[0].wm_max_dcfclk_clk_in_khz = nom_dcfclk_khz - 1; + clk_ranges.wm_dmif_clocks_ranges[0].wm_min_memg_clk_in_khz = min_fclk_khz; + clk_ranges.wm_dmif_clocks_ranges[0].wm_max_mem_clk_in_khz = nom_fclk_khz - 1; + clk_ranges.wm_mcif_clocks_ranges[0].wm_set_id = WM_SET_A; + clk_ranges.wm_mcif_clocks_ranges[0].wm_min_socclk_clk_in_khz = socclk_khz; + clk_ranges.wm_mcif_clocks_ranges[0].wm_max_socclk_clk_in_khz = overdrive; + clk_ranges.wm_mcif_clocks_ranges[0].wm_min_memg_clk_in_khz = min_fclk_khz; + clk_ranges.wm_mcif_clocks_ranges[0].wm_max_mem_clk_in_khz = nom_fclk_khz - 1; + + clk_ranges.wm_dmif_clocks_ranges[1].wm_set_id = WM_SET_B; + clk_ranges.wm_dmif_clocks_ranges[1].wm_min_dcfclk_clk_in_khz = min_dcfclk_khz; + clk_ranges.wm_dmif_clocks_ranges[1].wm_max_dcfclk_clk_in_khz = nom_dcfclk_khz - 1; + clk_ranges.wm_dmif_clocks_ranges[1].wm_min_memg_clk_in_khz = nom_fclk_khz; + clk_ranges.wm_dmif_clocks_ranges[1].wm_max_mem_clk_in_khz = max_fclk_khz; + clk_ranges.wm_mcif_clocks_ranges[1].wm_set_id = WM_SET_B; + clk_ranges.wm_mcif_clocks_ranges[1].wm_min_socclk_clk_in_khz = socclk_khz; + clk_ranges.wm_mcif_clocks_ranges[1].wm_max_socclk_clk_in_khz = overdrive; + clk_ranges.wm_mcif_clocks_ranges[1].wm_min_memg_clk_in_khz = nom_fclk_khz; + clk_ranges.wm_mcif_clocks_ranges[1].wm_max_mem_clk_in_khz = max_fclk_khz; + + + clk_ranges.wm_dmif_clocks_ranges[2].wm_set_id = WM_SET_C; + clk_ranges.wm_dmif_clocks_ranges[2].wm_min_dcfclk_clk_in_khz = nom_dcfclk_khz; + clk_ranges.wm_dmif_clocks_ranges[2].wm_max_dcfclk_clk_in_khz = max_dcfclk_khz; + clk_ranges.wm_dmif_clocks_ranges[2].wm_min_memg_clk_in_khz = nom_fclk_khz; + clk_ranges.wm_dmif_clocks_ranges[2].wm_max_mem_clk_in_khz = max_fclk_khz; + clk_ranges.wm_mcif_clocks_ranges[2].wm_set_id = WM_SET_C; + clk_ranges.wm_mcif_clocks_ranges[2].wm_min_socclk_clk_in_khz = socclk_khz; + clk_ranges.wm_mcif_clocks_ranges[2].wm_max_socclk_clk_in_khz = overdrive; + clk_ranges.wm_mcif_clocks_ranges[2].wm_min_memg_clk_in_khz = nom_fclk_khz; + clk_ranges.wm_mcif_clocks_ranges[2].wm_max_mem_clk_in_khz = max_fclk_khz; + + clk_ranges.wm_dmif_clocks_ranges[3].wm_set_id = WM_SET_D; + clk_ranges.wm_dmif_clocks_ranges[3].wm_min_dcfclk_clk_in_khz = max_dcfclk_khz + 1; + clk_ranges.wm_dmif_clocks_ranges[3].wm_max_dcfclk_clk_in_khz = overdrive; + clk_ranges.wm_dmif_clocks_ranges[3].wm_min_memg_clk_in_khz = max_fclk_khz + 1; + clk_ranges.wm_dmif_clocks_ranges[3].wm_max_mem_clk_in_khz = overdrive; + clk_ranges.wm_mcif_clocks_ranges[3].wm_set_id = WM_SET_D; + clk_ranges.wm_mcif_clocks_ranges[3].wm_min_socclk_clk_in_khz = socclk_khz; + clk_ranges.wm_mcif_clocks_ranges[3].wm_max_socclk_clk_in_khz = overdrive; + clk_ranges.wm_mcif_clocks_ranges[3].wm_min_memg_clk_in_khz = max_fclk_khz + 1; + clk_ranges.wm_mcif_clocks_ranges[3].wm_max_mem_clk_in_khz = overdrive; + + /* Notify PP Lib/SMU which Watermarks to use for which clock ranges */ + dm_pp_notify_wm_clock_changes_soc15(dc->ctx, &clk_ranges); +} + +void dcn_bw_sync_calcs_and_dml(struct core_dc *dc) +{ + kernel_fpu_begin(); + dc->dml.soc.vmin.socclk_mhz = dc->dcn_soc.socclk; + dc->dml.soc.vmid.socclk_mhz = dc->dcn_soc.socclk; + dc->dml.soc.vnom.socclk_mhz = dc->dcn_soc.socclk; + dc->dml.soc.vmax.socclk_mhz = dc->dcn_soc.socclk; + + dc->dml.soc.vmin.dcfclk_mhz = dc->dcn_soc.dcfclkv_min0p65; + dc->dml.soc.vmid.dcfclk_mhz = dc->dcn_soc.dcfclkv_mid0p72; + dc->dml.soc.vnom.dcfclk_mhz = dc->dcn_soc.dcfclkv_nom0p8; + dc->dml.soc.vmax.dcfclk_mhz = dc->dcn_soc.dcfclkv_max0p9; + + dc->dml.soc.vmin.dispclk_mhz = dc->dcn_soc.max_dispclk_vmin0p65; + dc->dml.soc.vmid.dispclk_mhz = dc->dcn_soc.max_dispclk_vmid0p72; + dc->dml.soc.vnom.dispclk_mhz = dc->dcn_soc.max_dispclk_vnom0p8; + dc->dml.soc.vmax.dispclk_mhz = dc->dcn_soc.max_dispclk_vmax0p9; + + dc->dml.soc.vmin.dppclk_mhz = dc->dcn_soc.max_dppclk_vmin0p65; + dc->dml.soc.vmid.dppclk_mhz = dc->dcn_soc.max_dppclk_vmid0p72; + dc->dml.soc.vnom.dppclk_mhz = dc->dcn_soc.max_dppclk_vnom0p8; + dc->dml.soc.vmax.dppclk_mhz = dc->dcn_soc.max_dppclk_vmax0p9; + + dc->dml.soc.vmin.phyclk_mhz = dc->dcn_soc.phyclkv_min0p65; + dc->dml.soc.vmid.phyclk_mhz = dc->dcn_soc.phyclkv_mid0p72; + dc->dml.soc.vnom.phyclk_mhz = dc->dcn_soc.phyclkv_nom0p8; + dc->dml.soc.vmax.phyclk_mhz = dc->dcn_soc.phyclkv_max0p9; + + dc->dml.soc.vmin.dram_bw_per_chan_gbps = dc->dcn_soc.fabric_and_dram_bandwidth_vmin0p65; + dc->dml.soc.vmid.dram_bw_per_chan_gbps = dc->dcn_soc.fabric_and_dram_bandwidth_vmid0p72; + dc->dml.soc.vnom.dram_bw_per_chan_gbps = dc->dcn_soc.fabric_and_dram_bandwidth_vnom0p8; + dc->dml.soc.vmax.dram_bw_per_chan_gbps = dc->dcn_soc.fabric_and_dram_bandwidth_vmax0p9; + + dc->dml.soc.sr_exit_time_us = dc->dcn_soc.sr_exit_time; + dc->dml.soc.sr_enter_plus_exit_time_us = dc->dcn_soc.sr_enter_plus_exit_time; + dc->dml.soc.urgent_latency_us = dc->dcn_soc.urgent_latency; + dc->dml.soc.writeback_latency_us = dc->dcn_soc.write_back_latency; + dc->dml.soc.ideal_dram_bw_after_urgent_percent = + dc->dcn_soc.percent_of_ideal_drambw_received_after_urg_latency; + dc->dml.soc.max_request_size_bytes = dc->dcn_soc.max_request_size; + dc->dml.soc.downspread_percent = dc->dcn_soc.downspreading; + dc->dml.soc.round_trip_ping_latency_dcfclk_cycles = + dc->dcn_soc.round_trip_ping_latency_cycles; + dc->dml.soc.urgent_out_of_order_return_per_channel_bytes = + dc->dcn_soc.urgent_out_of_order_return_per_channel; + dc->dml.soc.num_chans = dc->dcn_soc.number_of_channels; + dc->dml.soc.vmm_page_size_bytes = dc->dcn_soc.vmm_page_size; + dc->dml.soc.dram_clock_change_latency_us = dc->dcn_soc.dram_clock_change_latency; + dc->dml.soc.return_bus_width_bytes = dc->dcn_soc.return_bus_width; + + dc->dml.ip.rob_buffer_size_kbytes = dc->dcn_ip.rob_buffer_size_in_kbyte; + dc->dml.ip.det_buffer_size_kbytes = dc->dcn_ip.det_buffer_size_in_kbyte; + dc->dml.ip.dpp_output_buffer_pixels = dc->dcn_ip.dpp_output_buffer_pixels; + dc->dml.ip.opp_output_buffer_lines = dc->dcn_ip.opp_output_buffer_lines; + dc->dml.ip.pixel_chunk_size_kbytes = dc->dcn_ip.pixel_chunk_size_in_kbyte; + dc->dml.ip.pte_enable = dc->dcn_ip.pte_enable == dcn_bw_yes; + dc->dml.ip.pte_chunk_size_kbytes = dc->dcn_ip.pte_chunk_size; + dc->dml.ip.meta_chunk_size_kbytes = dc->dcn_ip.meta_chunk_size; + dc->dml.ip.writeback_chunk_size_kbytes = dc->dcn_ip.writeback_chunk_size; + dc->dml.ip.line_buffer_size_bits = dc->dcn_ip.line_buffer_size; + dc->dml.ip.max_line_buffer_lines = dc->dcn_ip.max_line_buffer_lines; + dc->dml.ip.IsLineBufferBppFixed = dc->dcn_ip.is_line_buffer_bpp_fixed == dcn_bw_yes; + dc->dml.ip.LineBufferFixedBpp = dc->dcn_ip.line_buffer_fixed_bpp; + dc->dml.ip.writeback_luma_buffer_size_kbytes = dc->dcn_ip.writeback_luma_buffer_size; + dc->dml.ip.writeback_chroma_buffer_size_kbytes = dc->dcn_ip.writeback_chroma_buffer_size; + dc->dml.ip.max_num_dpp = dc->dcn_ip.max_num_dpp; + dc->dml.ip.max_num_wb = dc->dcn_ip.max_num_writeback; + dc->dml.ip.max_dchub_pscl_bw_pix_per_clk = dc->dcn_ip.max_dchub_topscl_throughput; + dc->dml.ip.max_pscl_lb_bw_pix_per_clk = dc->dcn_ip.max_pscl_tolb_throughput; + dc->dml.ip.max_lb_vscl_bw_pix_per_clk = dc->dcn_ip.max_lb_tovscl_throughput; + dc->dml.ip.max_vscl_hscl_bw_pix_per_clk = dc->dcn_ip.max_vscl_tohscl_throughput; + dc->dml.ip.max_hscl_ratio = dc->dcn_ip.max_hscl_ratio; + dc->dml.ip.max_vscl_ratio = dc->dcn_ip.max_vscl_ratio; + dc->dml.ip.max_hscl_taps = dc->dcn_ip.max_hscl_taps; + dc->dml.ip.max_vscl_taps = dc->dcn_ip.max_vscl_taps; + /*pte_buffer_size_in_requests missing in dml*/ + dc->dml.ip.dispclk_ramp_margin_percent = dc->dcn_ip.dispclk_ramping_margin; + dc->dml.ip.underscan_factor = dc->dcn_ip.under_scan_factor; + dc->dml.ip.max_inter_dcn_tile_repeaters = dc->dcn_ip.max_inter_dcn_tile_repeaters; + dc->dml.ip.can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one = + dc->dcn_ip.can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one == dcn_bw_yes; + dc->dml.ip.bug_forcing_LC_req_same_size_fixed = + dc->dcn_ip.bug_forcing_luma_and_chroma_request_to_same_size_fixed == dcn_bw_yes; + dc->dml.ip.dcfclk_cstate_latency = dc->dcn_ip.dcfclk_cstate_latency; + kernel_fpu_end(); +} diff --git a/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h b/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h new file mode 100644 index 000000000000..499bc1127696 --- /dev/null +++ b/drivers/gpu/drm/amd/display/dc/inc/dcn_calcs.h @@ -0,0 +1,629 @@ +/* + * 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 + * + */ + +/** + * Bandwidth and Watermark calculations interface. + * (Refer to "DCEx_mode_support.xlsm" from Perforce.) + */ +#ifndef __DCN_CALCS_H__ +#define __DCN_CALCS_H__ + +#include "bw_fixed.h" +#include "display_clock.h" +#include "../dml/display_mode_lib.h" + +struct core_dc; +struct validate_context; + +/******************************************************************************* + * DCN data structures. + ******************************************************************************/ + +#define number_of_planes 6 +#define number_of_planes_minus_one 5 +#define number_of_states 4 +#define number_of_states_plus_one 5 + +#define ddr4_dram_width 64 +#define ddr4_dram_factor_single_Channel 16 +enum dcn_bw_defs { + dcn_bw_v_min0p65, + dcn_bw_v_mid0p72, + dcn_bw_v_nom0p8, + dcn_bw_v_max0p9, + dcn_bw_v_max0p91, + dcn_bw_no_support = 5, + dcn_bw_yes, + dcn_bw_hor, + dcn_bw_vert, + dcn_bw_override, + dcn_bw_rgb_sub_64, + dcn_bw_rgb_sub_32, + dcn_bw_rgb_sub_16, + dcn_bw_no, + dcn_bw_sw_linear, + dcn_bw_sw_4_kb_d, + dcn_bw_sw_4_kb_d_x, + dcn_bw_sw_64_kb_d, + dcn_bw_sw_64_kb_d_t, + dcn_bw_sw_64_kb_d_x, + dcn_bw_sw_var_d, + dcn_bw_sw_var_d_x, + dcn_bw_yuv420_sub_8, + dcn_bw_sw_4_kb_s, + dcn_bw_sw_4_kb_s_x, + dcn_bw_sw_64_kb_s, + dcn_bw_sw_64_kb_s_t, + dcn_bw_sw_64_kb_s_x, + dcn_bw_writeback, + dcn_bw_444, + dcn_bw_dp, + dcn_bw_420, + dcn_bw_hdmi, + dcn_bw_sw_var_s, + dcn_bw_sw_var_s_x, + dcn_bw_yuv420_sub_10, + dcn_bw_supported_in_v_active, + dcn_bw_supported_in_v_blank, + dcn_bw_not_supported, + dcn_bw_na, +}; + +/*bounding box parameters*/ +/*mode parameters*/ +/*system configuration*/ +/* display configuration*/ +struct dcn_bw_internal_vars { + float voltage[number_of_states_plus_one + 1]; + float max_dispclk[number_of_states_plus_one + 1]; + float max_dppclk[number_of_states_plus_one + 1]; + float dcfclk_per_state[number_of_states_plus_one + 1]; + float phyclk_per_state[number_of_states_plus_one + 1]; + float fabric_and_dram_bandwidth_per_state[number_of_states_plus_one + 1]; + float sr_exit_time; + float sr_enter_plus_exit_time; + float dram_clock_change_latency; + float urgent_latency; + float write_back_latency; + float percent_of_ideal_drambw_received_after_urg_latency; + float dcfclkv_max0p9; + float dcfclkv_nom0p8; + float dcfclkv_mid0p72; + float dcfclkv_min0p65; + float max_dispclk_vmax0p9; + float max_dppclk_vmax0p9; + float max_dispclk_vnom0p8; + float max_dppclk_vnom0p8; + float max_dispclk_vmid0p72; + float max_dppclk_vmid0p72; + float max_dispclk_vmin0p65; + float max_dppclk_vmin0p65; + float socclk; + float fabric_and_dram_bandwidth_vmax0p9; + float fabric_and_dram_bandwidth_vnom0p8; + float fabric_and_dram_bandwidth_vmid0p72; + float fabric_and_dram_bandwidth_vmin0p65; + float round_trip_ping_latency_cycles; + float urgent_out_of_order_return_per_channel; + float number_of_channels; + float vmm_page_size; + float return_bus_width; + float rob_buffer_size_in_kbyte; + float det_buffer_size_in_kbyte; + float dpp_output_buffer_pixels; + float opp_output_buffer_lines; + float pixel_chunk_size_in_kbyte; + float pte_chunk_size; + float meta_chunk_size; + float writeback_chunk_size; + enum dcn_bw_defs odm_capability; + enum dcn_bw_defs dsc_capability; + float line_buffer_size; + enum dcn_bw_defs is_line_buffer_bpp_fixed; + float line_buffer_fixed_bpp; + float max_line_buffer_lines; + float writeback_luma_buffer_size; + float writeback_chroma_buffer_size; + float max_num_dpp; + float max_num_writeback; + float max_dchub_topscl_throughput; + float max_pscl_tolb_throughput; + float max_lb_tovscl_throughput; + float max_vscl_tohscl_throughput; + float max_hscl_ratio; + float max_vscl_ratio; + float max_hscl_taps; + float max_vscl_taps; + float under_scan_factor; + float phyclkv_max0p9; + float phyclkv_nom0p8; + float phyclkv_mid0p72; + float phyclkv_min0p65; + float pte_buffer_size_in_requests; + float dispclk_ramping_margin; + float downspreading; + float max_inter_dcn_tile_repeaters; + enum dcn_bw_defs can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one; + enum dcn_bw_defs bug_forcing_luma_and_chroma_request_to_same_size_fixed; + int mode; + float viewport_width[number_of_planes_minus_one + 1]; + float htotal[number_of_planes_minus_one + 1]; + float vtotal[number_of_planes_minus_one + 1]; + float v_sync_plus_back_porch[number_of_planes_minus_one + 1]; + float vactive[number_of_planes_minus_one + 1]; + float pixel_clock[number_of_planes_minus_one + 1]; /*MHz*/ + float viewport_height[number_of_planes_minus_one + 1]; + enum dcn_bw_defs dcc_enable[number_of_planes_minus_one + 1]; + float dcc_rate[number_of_planes_minus_one + 1]; + enum dcn_bw_defs source_scan[number_of_planes_minus_one + 1]; + float lb_bit_per_pixel[number_of_planes_minus_one + 1]; + enum dcn_bw_defs source_pixel_format[number_of_planes_minus_one + 1]; + enum dcn_bw_defs source_surface_mode[number_of_planes_minus_one + 1]; + enum dcn_bw_defs output_format[number_of_planes_minus_one + 1]; + enum dcn_bw_defs output[number_of_planes_minus_one + 1]; + float scaler_rec_out_width[number_of_planes_minus_one + 1]; + float scaler_recout_height[number_of_planes_minus_one + 1]; + float underscan_output[number_of_planes_minus_one + 1]; + float interlace_output[number_of_planes_minus_one + 1]; + float override_hta_ps[number_of_planes_minus_one + 1]; + float override_vta_ps[number_of_planes_minus_one + 1]; + float override_hta_pschroma[number_of_planes_minus_one + 1]; + float override_vta_pschroma[number_of_planes_minus_one + 1]; + float urgent_latency_support_us[number_of_planes_minus_one + 1]; + float h_ratio[number_of_planes_minus_one + 1]; + float v_ratio[number_of_planes_minus_one + 1]; + float htaps[number_of_planes_minus_one + 1]; + float vtaps[number_of_planes_minus_one + 1]; + float hta_pschroma[number_of_planes_minus_one + 1]; + float vta_pschroma[number_of_planes_minus_one + 1]; + enum dcn_bw_defs pte_enable; + enum dcn_bw_defs synchronized_vblank; + enum dcn_bw_defs ta_pscalculation; + int voltage_override_level; + int number_of_active_planes; + int voltage_level; + enum dcn_bw_defs immediate_flip_supported; + float dcfclk; + float max_phyclk; + float fabric_and_dram_bandwidth; + float dpp_per_plane_per_ratio[1 + 1][number_of_planes_minus_one + 1]; + enum dcn_bw_defs dispclk_dppclk_support_per_ratio[1 + 1]; + float required_dispclk_per_ratio[1 + 1]; + enum dcn_bw_defs error_message[1 + 1]; + int dispclk_dppclk_ratio; + float dpp_per_plane[number_of_planes_minus_one + 1]; + float det_buffer_size_y[number_of_planes_minus_one + 1]; + float det_buffer_size_c[number_of_planes_minus_one + 1]; + float swath_height_y[number_of_planes_minus_one + 1]; + float swath_height_c[number_of_planes_minus_one + 1]; + enum dcn_bw_defs final_error_message; + float frequency; + float header_line; + float header; + enum dcn_bw_defs voltage_override; + enum dcn_bw_defs allow_different_hratio_vratio; + float acceptable_quality_hta_ps; + float acceptable_quality_vta_ps; + float no_of_dpp[number_of_states_plus_one + 1][1 + 1][number_of_planes_minus_one + 1]; + float swath_width_yper_state[number_of_states_plus_one + 1][1 + 1][number_of_planes_minus_one + 1]; + float swath_height_yper_state[number_of_states_plus_one + 1][1 + 1][number_of_planes_minus_one + 1]; + float swath_height_cper_state[number_of_states_plus_one + 1][1 + 1][number_of_planes_minus_one + 1]; + float urgent_latency_support_us_per_state[number_of_states_plus_one + 1][1 + 1][number_of_planes_minus_one + 1]; + float v_ratio_pre_ywith_immediate_flip[number_of_states_plus_one + 1][1 + 1][number_of_planes_minus_one + 1]; + float v_ratio_pre_cwith_immediate_flip[number_of_states_plus_one + 1][1 + 1][number_of_planes_minus_one + 1]; + float required_prefetch_pixel_data_bw_with_immediate_flip[number_of_states_plus_one + 1][1 + 1][number_of_planes_minus_one + 1]; + float v_ratio_pre_ywithout_immediate_flip[number_of_states_plus_one + 1][1 + 1][number_of_planes_minus_one + 1]; + float v_ratio_pre_cwithout_immediate_flip[number_of_states_plus_one + 1][1 + 1][number_of_planes_minus_one + 1]; + float required_prefetch_pixel_data_bw_without_immediate_flip[number_of_states_plus_one + 1][1 + 1][number_of_planes_minus_one + 1]; + enum dcn_bw_defs prefetch_supported_with_immediate_flip[number_of_states_plus_one + 1][1 + 1]; + enum dcn_bw_defs prefetch_supported_without_immediate_flip[number_of_states_plus_one + 1][1 + 1]; + enum dcn_bw_defs v_ratio_in_prefetch_supported_with_immediate_flip[number_of_states_plus_one + 1][1 + 1]; + enum dcn_bw_defs v_ratio_in_prefetch_supported_without_immediate_flip[number_of_states_plus_one + 1][1 + 1]; + float required_dispclk[number_of_states_plus_one + 1][1 + 1]; + enum dcn_bw_defs dispclk_dppclk_support[number_of_states_plus_one + 1][1 + 1]; + enum dcn_bw_defs total_available_pipes_support[number_of_states_plus_one + 1][1 + 1]; + float total_number_of_active_dpp[number_of_states_plus_one + 1][1 + 1]; + float total_number_of_dcc_active_dpp[number_of_states_plus_one + 1][1 + 1]; + enum dcn_bw_defs urgent_latency_support[number_of_states_plus_one + 1][1 + 1]; + enum dcn_bw_defs mode_support_with_immediate_flip[number_of_states_plus_one + 1][1 + 1]; + enum dcn_bw_defs mode_support_without_immediate_flip[number_of_states_plus_one + 1][1 + 1]; + float return_bw_per_state[number_of_states_plus_one + 1]; + enum dcn_bw_defs dio_support[number_of_states_plus_one + 1]; + float urgent_round_trip_and_out_of_order_latency_per_state[number_of_states_plus_one + 1]; + enum dcn_bw_defs rob_support[number_of_states_plus_one + 1]; + enum dcn_bw_defs bandwidth_support[number_of_states_plus_one + 1]; + float prefetch_bw[number_of_planes_minus_one + 1]; + float meta_pte_bytes_per_frame[number_of_planes_minus_one + 1]; + float meta_row_bytes[number_of_planes_minus_one + 1]; + float dpte_bytes_per_row[number_of_planes_minus_one + 1]; + float prefetch_lines_y[number_of_planes_minus_one + 1]; + float prefetch_lines_c[number_of_planes_minus_one + 1]; + float max_num_sw_y[number_of_planes_minus_one + 1]; + float max_num_sw_c[number_of_planes_minus_one + 1]; + float line_times_for_prefetch[number_of_planes_minus_one + 1]; + float lines_for_meta_pte_with_immediate_flip[number_of_planes_minus_one + 1]; + float lines_for_meta_pte_without_immediate_flip[number_of_planes_minus_one + 1]; + float lines_for_meta_and_dpte_row_with_immediate_flip[number_of_planes_minus_one + 1]; + float lines_for_meta_and_dpte_row_without_immediate_flip[number_of_planes_minus_one + 1]; + float min_dppclk_using_single_dpp[number_of_planes_minus_one + 1]; + float swath_width_ysingle_dpp[number_of_planes_minus_one + 1]; + float byte_per_pixel_in_dety[number_of_planes_minus_one + 1]; + float byte_per_pixel_in_detc[number_of_planes_minus_one + 1]; + float number_of_dpp_required_for_det_and_lb_size[number_of_planes_minus_one + 1]; + float required_phyclk[number_of_planes_minus_one + 1]; + float read256_block_height_y[number_of_planes_minus_one + 1]; + float read256_block_width_y[number_of_planes_minus_one + 1]; + float read256_block_height_c[number_of_planes_minus_one + 1]; + float read256_block_width_c[number_of_planes_minus_one + 1]; + float max_swath_height_y[number_of_planes_minus_one + 1]; + float max_swath_height_c[number_of_planes_minus_one + 1]; + float min_swath_height_y[number_of_planes_minus_one + 1]; + float min_swath_height_c[number_of_planes_minus_one + 1]; + float read_bandwidth[number_of_planes_minus_one + 1]; + float write_bandwidth[number_of_planes_minus_one + 1]; + float pscl_factor[number_of_planes_minus_one + 1]; + float pscl_factor_chroma[number_of_planes_minus_one + 1]; + enum dcn_bw_defs scale_ratio_support; + enum dcn_bw_defs source_format_pixel_and_scan_support; + float total_read_bandwidth_consumed_gbyte_per_second; + float total_write_bandwidth_consumed_gbyte_per_second; + float total_bandwidth_consumed_gbyte_per_second; + enum dcn_bw_defs dcc_enabled_in_any_plane; + float return_bw_todcn_per_state; + float critical_point; + enum dcn_bw_defs writeback_latency_support; + float required_output_bw; + float total_number_of_active_writeback; + enum dcn_bw_defs total_available_writeback_support; + float maximum_swath_width; + float number_of_dpp_required_for_det_size; + float number_of_dpp_required_for_lb_size; + float min_dispclk_using_single_dpp; + float min_dispclk_using_dual_dpp; + enum dcn_bw_defs viewport_size_support; + float swath_width_granularity_y; + float rounded_up_max_swath_size_bytes_y; + float swath_width_granularity_c; + float rounded_up_max_swath_size_bytes_c; + float lines_in_det_luma; + float lines_in_det_chroma; + float effective_lb_latency_hiding_source_lines_luma; + float effective_lb_latency_hiding_source_lines_chroma; + float effective_detlb_lines_luma; + float effective_detlb_lines_chroma; + float projected_dcfclk_deep_sleep; + float meta_req_height_y; + float meta_req_width_y; + float meta_surface_width_y; + float meta_surface_height_y; + float meta_pte_bytes_per_frame_y; + float meta_row_bytes_y; + float macro_tile_block_size_bytes_y; + float macro_tile_block_height_y; + float data_pte_req_height_y; + float data_pte_req_width_y; + float dpte_bytes_per_row_y; + float meta_req_height_c; + float meta_req_width_c; + float meta_surface_width_c; + float meta_surface_height_c; + float meta_pte_bytes_per_frame_c; + float meta_row_bytes_c; + float macro_tile_block_size_bytes_c; + float macro_tile_block_height_c; + float macro_tile_block_width_c; + float data_pte_req_height_c; + float data_pte_req_width_c; + float dpte_bytes_per_row_c; + float v_init_y; + float max_partial_sw_y; + float v_init_c; + float max_partial_sw_c; + float dst_x_after_scaler; + float dst_y_after_scaler; + float time_calc; + float v_update_offset[number_of_planes_minus_one + 1]; + float total_repeater_delay; + float v_update_width[number_of_planes_minus_one + 1]; + float v_ready_offset[number_of_planes_minus_one + 1]; + float time_setup; + float extra_latency; + float maximum_vstartup; + float bw_available_for_immediate_flip; + float total_immediate_flip_bytes[number_of_planes_minus_one + 1]; + float time_for_meta_pte_with_immediate_flip; + float time_for_meta_pte_without_immediate_flip; + float time_for_meta_and_dpte_row_with_immediate_flip; + float time_for_meta_and_dpte_row_without_immediate_flip; + float line_times_to_request_prefetch_pixel_data_with_immediate_flip; + float line_times_to_request_prefetch_pixel_data_without_immediate_flip; + float maximum_read_bandwidth_with_prefetch_with_immediate_flip; + float maximum_read_bandwidth_with_prefetch_without_immediate_flip; + float voltage_level_with_immediate_flip; + float voltage_level_without_immediate_flip; + float total_number_of_active_dpp_per_ratio[1 + 1]; + float byte_per_pix_dety; + float byte_per_pix_detc; + float read256_bytes_block_height_y; + float read256_bytes_block_width_y; + float read256_bytes_block_height_c; + float read256_bytes_block_width_c; + float maximum_swath_height_y; + float maximum_swath_height_c; + float minimum_swath_height_y; + float minimum_swath_height_c; + float swath_width; + float prefetch_bandwidth[number_of_planes_minus_one + 1]; + float v_init_pre_fill_y[number_of_planes_minus_one + 1]; + float v_init_pre_fill_c[number_of_planes_minus_one + 1]; + float max_num_swath_y[number_of_planes_minus_one + 1]; + float max_num_swath_c[number_of_planes_minus_one + 1]; + float prefill_y[number_of_planes_minus_one + 1]; + float prefill_c[number_of_planes_minus_one + 1]; + float v_startup[number_of_planes_minus_one + 1]; + enum dcn_bw_defs allow_dram_clock_change_during_vblank[number_of_planes_minus_one + 1]; + float allow_dram_self_refresh_during_vblank[number_of_planes_minus_one + 1]; + float v_ratio_prefetch_y[number_of_planes_minus_one + 1]; + float v_ratio_prefetch_c[number_of_planes_minus_one + 1]; + float destination_lines_for_prefetch[number_of_planes_minus_one + 1]; + float destination_lines_to_request_vm_inv_blank[number_of_planes_minus_one + 1]; + float destination_lines_to_request_row_in_vblank[number_of_planes_minus_one + 1]; + float min_ttuv_blank[number_of_planes_minus_one + 1]; + float byte_per_pixel_dety[number_of_planes_minus_one + 1]; + float byte_per_pixel_detc[number_of_planes_minus_one + 1]; + float swath_width_y[number_of_planes_minus_one + 1]; + float lines_in_dety[number_of_planes_minus_one + 1]; + float lines_in_dety_rounded_down_to_swath[number_of_planes_minus_one + 1]; + float lines_in_detc[number_of_planes_minus_one + 1]; + float lines_in_detc_rounded_down_to_swath[number_of_planes_minus_one + 1]; + float full_det_buffering_time_y[number_of_planes_minus_one + 1]; + float full_det_buffering_time_c[number_of_planes_minus_one + 1]; + float active_dram_clock_change_latency_margin[number_of_planes_minus_one + 1]; + float v_blank_dram_clock_change_latency_margin[number_of_planes_minus_one + 1]; + float dcfclk_deep_sleep_per_plane[number_of_planes_minus_one + 1]; + float read_bandwidth_plane_luma[number_of_planes_minus_one + 1]; + float read_bandwidth_plane_chroma[number_of_planes_minus_one + 1]; + float display_pipe_line_delivery_time_luma[number_of_planes_minus_one + 1]; + float display_pipe_line_delivery_time_chroma[number_of_planes_minus_one + 1]; + float display_pipe_line_delivery_time_luma_prefetch[number_of_planes_minus_one + 1]; + float display_pipe_line_delivery_time_chroma_prefetch[number_of_planes_minus_one + 1]; + float pixel_pte_bytes_per_row[number_of_planes_minus_one + 1]; + float meta_pte_bytes_frame[number_of_planes_minus_one + 1]; + float meta_row_byte[number_of_planes_minus_one + 1]; + float prefetch_source_lines_y[number_of_planes_minus_one + 1]; + float prefetch_source_lines_c[number_of_planes_minus_one + 1]; + float pscl_throughput[number_of_planes_minus_one + 1]; + float pscl_throughput_chroma[number_of_planes_minus_one + 1]; + float output_bpphdmi[number_of_planes_minus_one + 1]; + float output_bppdp4_lane_hbr[number_of_planes_minus_one + 1]; + float output_bppdp4_lane_hbr2[number_of_planes_minus_one + 1]; + float output_bppdp4_lane_hbr3[number_of_planes_minus_one + 1]; + float max_vstartup_lines[number_of_planes_minus_one + 1]; + float dispclk_with_ramping; + float dispclk_without_ramping; + float dppclk_using_single_dpp_luma; + float dppclk_using_single_dpp; + float dppclk_using_single_dpp_chroma; + enum dcn_bw_defs odm_capable; + float dispclk; + float dppclk; + float return_bandwidth_to_dcn; + enum dcn_bw_defs dcc_enabled_any_plane; + float return_bw; + float critical_compression; + float total_data_read_bandwidth; + float total_active_dpp; + float total_dcc_active_dpp; + float urgent_round_trip_and_out_of_order_latency; + float last_pixel_of_line_extra_watermark; + float data_fabric_line_delivery_time_luma; + float data_fabric_line_delivery_time_chroma; + float urgent_extra_latency; + float urgent_watermark; + float ptemeta_urgent_watermark; + float dram_clock_change_watermark; + float total_active_writeback; + float writeback_dram_clock_change_watermark; + float min_full_det_buffering_time; + float frame_time_for_min_full_det_buffering_time; + float average_read_bandwidth_gbyte_per_second; + float part_of_burst_that_fits_in_rob; + float stutter_burst_time; + float stutter_efficiency_not_including_vblank; + float smallest_vblank; + float v_blank_time; + float stutter_efficiency; + float dcf_clk_deep_sleep; + float stutter_exit_watermark; + float stutter_enter_plus_exit_watermark; + float effective_det_plus_lb_lines_luma; + float urgent_latency_support_us_luma; + float effective_det_plus_lb_lines_chroma; + float urgent_latency_support_us_chroma; + float min_urgent_latency_support_us; + float non_urgent_latency_tolerance; + float block_height256_bytes_y; + float block_height256_bytes_c; + float meta_request_width_y; + float meta_surf_width_y; + float meta_surf_height_y; + float meta_pte_bytes_frame_y; + float meta_row_byte_y; + float macro_tile_size_byte_y; + float macro_tile_height_y; + float pixel_pte_req_height_y; + float pixel_pte_req_width_y; + float pixel_pte_bytes_per_row_y; + float meta_request_width_c; + float meta_surf_width_c; + float meta_surf_height_c; + float meta_pte_bytes_frame_c; + float meta_row_byte_c; + float macro_tile_size_bytes_c; + float macro_tile_height_c; + float pixel_pte_req_height_c; + float pixel_pte_req_width_c; + float pixel_pte_bytes_per_row_c; + float max_partial_swath_y; + float max_partial_swath_c; + float t_calc; + float next_prefetch_mode; + float v_startup_lines; + enum dcn_bw_defs planes_with_room_to_increase_vstartup_prefetch_bw_less_than_active_bw; + enum dcn_bw_defs planes_with_room_to_increase_vstartup_vratio_prefetch_more_than4; + enum dcn_bw_defs planes_with_room_to_increase_vstartup_destination_line_times_for_prefetch_less_than2; + enum dcn_bw_defs v_ratio_prefetch_more_than4; + enum dcn_bw_defs destination_line_times_for_prefetch_less_than2; + float prefetch_mode; + float dstx_after_scaler; + float dsty_after_scaler; + float v_update_offset_pix; + float total_repeater_delay_time; + float v_update_width_pix; + float v_ready_offset_pix; + float t_setup; + float t_wait; + float bandwidth_available_for_immediate_flip; + float tot_immediate_flip_bytes; + float max_rd_bandwidth; + float time_for_fetching_meta_pte; + float time_for_fetching_row_in_vblank; + float lines_to_request_prefetch_pixel_data; + float required_prefetch_pix_data_bw; + enum dcn_bw_defs prefetch_mode_supported; + float active_dp_ps; + float lb_latency_hiding_source_lines_y; + float lb_latency_hiding_source_lines_c; + float effective_lb_latency_hiding_y; + float effective_lb_latency_hiding_c; + float dpp_output_buffer_lines_y; + float dpp_output_buffer_lines_c; + float dppopp_buffering_y; + float max_det_buffering_time_y; + float active_dram_clock_change_latency_margin_y; + float dppopp_buffering_c; + float max_det_buffering_time_c; + float active_dram_clock_change_latency_margin_c; + float writeback_dram_clock_change_latency_margin; + float min_active_dram_clock_change_margin; + float v_blank_of_min_active_dram_clock_change_margin; + float second_min_active_dram_clock_change_margin; + float min_vblank_dram_clock_change_margin; + float dram_clock_change_margin; + float dram_clock_change_support; + float wr_bandwidth; + float max_used_bw; +}; + +struct dcn_soc_bounding_box { + float sr_exit_time; /*us*/ + float sr_enter_plus_exit_time; /*us*/ + float urgent_latency; /*us*/ + float write_back_latency; /*us*/ + float percent_of_ideal_drambw_received_after_urg_latency; /*%*/ + int max_request_size; /*bytes*/ + float dcfclkv_max0p9; /*MHz*/ + float dcfclkv_nom0p8; /*MHz*/ + float dcfclkv_mid0p72; /*MHz*/ + float dcfclkv_min0p65; /*MHz*/ + float max_dispclk_vmax0p9; /*MHz*/ + float max_dispclk_vmid0p72; /*MHz*/ + float max_dispclk_vnom0p8; /*MHz*/ + float max_dispclk_vmin0p65; /*MHz*/ + float max_dppclk_vmax0p9; /*MHz*/ + float max_dppclk_vnom0p8; /*MHz*/ + float max_dppclk_vmid0p72; /*MHz*/ + float max_dppclk_vmin0p65; /*MHz*/ + float socclk; /*MHz*/ + float fabric_and_dram_bandwidth_vmax0p9; /*GB/s*/ + float fabric_and_dram_bandwidth_vnom0p8; /*GB/s*/ + float fabric_and_dram_bandwidth_vmid0p72; /*GB/s*/ + float fabric_and_dram_bandwidth_vmin0p65; /*GB/s*/ + float phyclkv_max0p9; /*MHz*/ + float phyclkv_nom0p8; /*MHz*/ + float phyclkv_mid0p72; /*MHz*/ + float phyclkv_min0p65; /*MHz*/ + float downspreading; /*%*/ + int round_trip_ping_latency_cycles; /*DCFCLK Cycles*/ + int urgent_out_of_order_return_per_channel; /*bytes*/ + int number_of_channels; + int vmm_page_size; /*bytes*/ + float dram_clock_change_latency; /*us*/ + int return_bus_width; /*bytes*/ +}; +extern const struct dcn_soc_bounding_box dcn10_soc_defaults; + +struct dcn_ip_params { + float rob_buffer_size_in_kbyte; + float det_buffer_size_in_kbyte; + float dpp_output_buffer_pixels; + float opp_output_buffer_lines; + float pixel_chunk_size_in_kbyte; + enum dcn_bw_defs pte_enable; + int pte_chunk_size; /*kbytes*/ + int meta_chunk_size; /*kbytes*/ + int writeback_chunk_size; /*kbytes*/ + enum dcn_bw_defs odm_capability; + enum dcn_bw_defs dsc_capability; + int line_buffer_size; /*bit*/ + int max_line_buffer_lines; + enum dcn_bw_defs is_line_buffer_bpp_fixed; + int line_buffer_fixed_bpp; + int writeback_luma_buffer_size; /*kbytes*/ + int writeback_chroma_buffer_size; /*kbytes*/ + int max_num_dpp; + int max_num_writeback; + int max_dchub_topscl_throughput; /*pixels/dppclk*/ + int max_pscl_tolb_throughput; /*pixels/dppclk*/ + int max_lb_tovscl_throughput; /*pixels/dppclk*/ + int max_vscl_tohscl_throughput; /*pixels/dppclk*/ + float max_hscl_ratio; + float max_vscl_ratio; + int max_hscl_taps; + int max_vscl_taps; + int pte_buffer_size_in_requests; + float dispclk_ramping_margin; /*%*/ + float under_scan_factor; + int max_inter_dcn_tile_repeaters; + enum dcn_bw_defs can_vstartup_lines_exceed_vsync_plus_back_porch_lines_minus_one; + enum dcn_bw_defs bug_forcing_luma_and_chroma_request_to_same_size_fixed; + int dcfclk_cstate_latency; +}; +extern const struct dcn_ip_params dcn10_ip_defaults; + +bool dcn_validate_bandwidth( + const struct core_dc *dc, + struct validate_context *context); + +unsigned int dcn_find_dcfclk_suits_all( + const struct core_dc *dc, + struct clocks_value *clocks); + +void dcn_bw_update_from_pplib(struct core_dc *dc); +void dcn_bw_notify_pplib_of_wm_ranges(struct core_dc *dc); +void dcn_bw_sync_calcs_and_dml(struct core_dc *dc); + +#endif /* __DCN_CALCS_H__ */ + -- 2.30.2