diff --git a/msm/sde/sde_encoder_dce.c b/msm/sde/sde_encoder_dce.c index 99b294734c..0886e6eb3a 100644 --- a/msm/sde/sde_encoder_dce.c +++ b/msm/sde/sde_encoder_dce.c @@ -112,29 +112,68 @@ static void _dce_dsc_pclk_param_calc(struct msm_display_dsc_info *dsc, } static int _dce_dsc_initial_line_calc(struct msm_display_dsc_info *dsc, - int enc_ip_width) + int enc_ip_width, + int dsc_cmn_mode) { - int max_ssm_delay, max_se_size, obuf_latency; - int input_ssm_out_latency, base_hs_latency; + int max_ssm_delay, max_se_size, max_muxword_size; + int compress_bpp_group, obuf_latency, input_ssm_out_latency; + int base_hs_latency, chunk_bits, ob_data_width; + int output_rate_extra_budget_bits, multi_hs_extra_budget_bits; int multi_hs_extra_latency, mux_word_size; + int ob_data_width_4comps, ob_data_width_3comps; + int output_rate_ratio_complement, container_slice_width; + int rtl_num_components, multi_hs_c, multi_hs_d; /* Hardent core config */ - int max_muxword_size = 48; - int output_rate = 64; - int rtl_max_bpc = 10; + int multiplex_mode_enable = 0, split_panel_enable = 0; + int rtl_max_bpc = 10, rtl_output_data_width = 64; int pipeline_latency = 28; + int bpc = dsc->bpc, bpp = dsc->bpp; + int num_of_active_ss = dsc->full_frame_slices; + bool native_422 = false, native_420 = false; + if (dsc_cmn_mode & DSC_MODE_MULTIPLEX) + multiplex_mode_enable = 1; + if (dsc_cmn_mode & DSC_MODE_SPLIT_PANEL) + split_panel_enable = 0; + container_slice_width = (native_422 ? + dsc->slice_width / 2 : dsc->slice_width); + max_muxword_size = ((rtl_max_bpc >= 12) ? 64 : 48); max_se_size = 4 * (rtl_max_bpc + 1); max_ssm_delay = max_se_size + max_muxword_size - 1; - mux_word_size = (dsc->bpc >= 12 ? 64 : 48); - input_ssm_out_latency = pipeline_latency + (3 * (max_ssm_delay + 2)); - obuf_latency = DIV_ROUND_UP((9 * output_rate + - mux_word_size), dsc->bpp) + 1; + mux_word_size = (bpc >= 12 ? 64 : 48); + compress_bpp_group = (native_422 ? 2 * bpp : bpp); + input_ssm_out_latency = pipeline_latency + (3 * (max_ssm_delay + 2) + * num_of_active_ss); + rtl_num_components = (native_420 | native_422 ? 4 : 3); + ob_data_width_4comps = ((rtl_output_data_width >= (2 * + max_muxword_size)) ? + rtl_output_data_width : + (2 * rtl_output_data_width)); + ob_data_width_3comps = (rtl_output_data_width >= max_muxword_size ? + rtl_output_data_width : 2 * rtl_output_data_width); + ob_data_width = (rtl_num_components == 4 ? + ob_data_width_4comps : ob_data_width_3comps); + obuf_latency = DIV_ROUND_UP((9 * ob_data_width + mux_word_size), + compress_bpp_group) + 1; base_hs_latency = dsc->initial_xmit_delay + input_ssm_out_latency - + obuf_latency; - multi_hs_extra_latency = DIV_ROUND_UP((8 * dsc->chunk_size), dsc->bpp); + + obuf_latency; + chunk_bits = 8 * dsc->chunk_size; + output_rate_ratio_complement = ob_data_width - compress_bpp_group; + output_rate_extra_budget_bits = + (output_rate_ratio_complement * chunk_bits) >> + (ob_data_width == 128 ? 7 : 6); + multi_hs_c = split_panel_enable * multiplex_mode_enable; + multi_hs_d = (num_of_active_ss > 1) * (ob_data_width > + compress_bpp_group); + multi_hs_extra_budget_bits = (multi_hs_c ? + chunk_bits : (multi_hs_d ? chunk_bits : + output_rate_extra_budget_bits)); + multi_hs_extra_latency = DIV_ROUND_UP(multi_hs_extra_budget_bits, + compress_bpp_group); dsc->initial_lines = DIV_ROUND_UP((base_hs_latency + - multi_hs_extra_latency), dsc->slice_width); + multi_hs_extra_latency), + container_slice_width); return 0; } @@ -307,7 +346,7 @@ static int _dce_dsc_setup(struct sde_encoder_virt *sde_enc, if (dsc_merge) enc_ip_w = intf_ip_w / 2; - _dce_dsc_initial_line_calc(dsc, enc_ip_w); + _dce_dsc_initial_line_calc(dsc, enc_ip_w, dsc_common_mode); /* * __is_ich_reset_override_needed should be called only after