|
@@ -117,18 +117,25 @@ struct dp_dhdr_maxpkt_calc_input {
|
|
|
|
|
|
struct tu_algo_data {
|
|
|
s64 lclk_fp;
|
|
|
+ s64 orig_lclk_fp;
|
|
|
+
|
|
|
s64 pclk_fp;
|
|
|
+ s64 orig_pclk_fp;
|
|
|
s64 lwidth;
|
|
|
s64 lwidth_fp;
|
|
|
+ int orig_lwidth;
|
|
|
s64 hbp_relative_to_pclk;
|
|
|
s64 hbp_relative_to_pclk_fp;
|
|
|
+ int orig_hbp;
|
|
|
int nlanes;
|
|
|
int bpp;
|
|
|
int pixelEnc;
|
|
|
int dsc_en;
|
|
|
int async_en;
|
|
|
+ int fec_en;
|
|
|
int bpc;
|
|
|
|
|
|
+ int rb2;
|
|
|
uint delay_start_link_extra_pixclk;
|
|
|
int extra_buffer_margin;
|
|
|
s64 ratio_fp;
|
|
@@ -185,12 +192,21 @@ struct tu_algo_data {
|
|
|
int even_distribution_BF;
|
|
|
int even_distribution_legacy;
|
|
|
int even_distribution;
|
|
|
+ int hbp_delayStartCheck;
|
|
|
+ int pre_tu_hw_pipe_delay;
|
|
|
+ int post_tu_hw_pipe_delay;
|
|
|
+ int link_config_hactive_time;
|
|
|
+ int delay_start_link_lclk;
|
|
|
+ int tu_active_cycles;
|
|
|
+ s64 parity_symbols;
|
|
|
+ int resolution_line_time;
|
|
|
+ int last_partial_lclk;
|
|
|
int min_hblank_violated;
|
|
|
s64 delay_start_time_fp;
|
|
|
s64 hbp_time_fp;
|
|
|
s64 hactive_time_fp;
|
|
|
s64 diff_abs_fp;
|
|
|
-
|
|
|
+ int second_loop_set;
|
|
|
s64 ratio;
|
|
|
};
|
|
|
|
|
@@ -323,6 +339,21 @@ static int _tu_param_compare(s64 a, s64 b)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static s64 fixp_subtract(s64 a, s64 b)
|
|
|
+{
|
|
|
+ s64 minus_1 = drm_fixp_from_fraction(-1, 1);
|
|
|
+
|
|
|
+ if (a >= b)
|
|
|
+ return a - b;
|
|
|
+
|
|
|
+ return drm_fixp_mul(b - a, minus_1);
|
|
|
+}
|
|
|
+
|
|
|
+static inline int fixp2int_ceil(s64 a)
|
|
|
+{
|
|
|
+ return (a ? drm_fixp2int_ceil(a) : 0);
|
|
|
+}
|
|
|
+
|
|
|
static void dp_panel_update_tu_timings(struct dp_tu_calc_input *in,
|
|
|
struct tu_algo_data *tu)
|
|
|
{
|
|
@@ -339,21 +370,27 @@ static void dp_panel_update_tu_timings(struct dp_tu_calc_input *in,
|
|
|
int tot_num_hor_bytes = 0;
|
|
|
int tot_num_dummy_bytes = 0;
|
|
|
int dwidth_dsc_bytes = 0;
|
|
|
- int eoc_bytes = 0;
|
|
|
+ int eoc_bytes = 0;
|
|
|
|
|
|
s64 temp1_fp, temp2_fp, temp3_fp;
|
|
|
|
|
|
tu->lclk_fp = drm_fixp_from_fraction(in->lclk, 1);
|
|
|
+ tu->orig_lclk_fp = tu->lclk_fp;
|
|
|
tu->pclk_fp = drm_fixp_from_fraction(in->pclk_khz, 1000);
|
|
|
+ tu->orig_pclk_fp = tu->pclk_fp;
|
|
|
tu->lwidth = in->hactive;
|
|
|
tu->hbp_relative_to_pclk = in->hporch;
|
|
|
tu->nlanes = in->nlanes;
|
|
|
tu->bpp = in->bpp;
|
|
|
tu->pixelEnc = in->pixel_enc;
|
|
|
tu->dsc_en = in->dsc_en;
|
|
|
+ tu->fec_en = in->fec_en;
|
|
|
tu->async_en = in->async_en;
|
|
|
tu->lwidth_fp = drm_fixp_from_fraction(in->hactive, 1);
|
|
|
+ tu->orig_lwidth = in->hactive;
|
|
|
tu->hbp_relative_to_pclk_fp = drm_fixp_from_fraction(in->hporch, 1);
|
|
|
+ tu->orig_hbp = in->hporch;
|
|
|
+ tu->rb2 = (in->hporch <= 80) ? 1 : 0;
|
|
|
|
|
|
if (tu->pixelEnc == 420) {
|
|
|
temp1_fp = drm_fixp_from_fraction(2, 1);
|
|
@@ -438,12 +475,12 @@ static void _tu_valid_boundary_calc(struct tu_algo_data *tu)
|
|
|
temp1_fp = drm_fixp_from_fraction(tu->tu_size, 1);
|
|
|
temp2_fp = drm_fixp_mul(tu->ratio_fp, temp1_fp);
|
|
|
|
|
|
- tu->new_valid_boundary_link = drm_fixp2int_ceil(temp2_fp);
|
|
|
+ tu->new_valid_boundary_link = fixp2int_ceil(temp2_fp);
|
|
|
|
|
|
temp = (tu->i_upper_boundary_count *
|
|
|
tu->new_valid_boundary_link +
|
|
|
tu->i_lower_boundary_count *
|
|
|
- (tu->new_valid_boundary_link-1));
|
|
|
+ (tu->new_valid_boundary_link - 1));
|
|
|
tu->average_valid2_fp = drm_fixp_from_fraction(temp,
|
|
|
(tu->i_upper_boundary_count +
|
|
|
tu->i_lower_boundary_count));
|
|
@@ -518,11 +555,11 @@ static void _tu_valid_boundary_calc(struct tu_algo_data *tu)
|
|
|
|
|
|
temp1_fp = drm_fixp_from_fraction(tu->tu_size, 1);
|
|
|
temp2_fp = drm_fixp_mul(tu->ratio_fp, temp1_fp);
|
|
|
- tu->n_n_err_fp = tu->effective_valid_fp - temp2_fp;
|
|
|
+ tu->n_n_err_fp = fixp_subtract(tu->effective_valid_fp, temp2_fp);
|
|
|
|
|
|
temp1_fp = drm_fixp_from_fraction(tu->tu_size, 1);
|
|
|
temp2_fp = drm_fixp_mul(tu->ratio_fp, temp1_fp);
|
|
|
- tu->n_err_fp = tu->average_valid2_fp - temp2_fp;
|
|
|
+ tu->n_err_fp = fixp_subtract(tu->average_valid2_fp, temp2_fp);
|
|
|
|
|
|
tu->even_distribution = tu->n_tus % tu->nlanes == 0 ? 1 : 0;
|
|
|
|
|
@@ -530,11 +567,7 @@ static void _tu_valid_boundary_calc(struct tu_algo_data *tu)
|
|
|
temp2_fp = tu->lwidth_fp;
|
|
|
temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp);
|
|
|
temp2_fp = drm_fixp_div(temp1_fp, tu->average_valid2_fp);
|
|
|
-
|
|
|
- if (temp2_fp)
|
|
|
- tu->n_tus_incl_last_incomplete_tu = drm_fixp2int_ceil(temp2_fp);
|
|
|
- else
|
|
|
- tu->n_tus_incl_last_incomplete_tu = 0;
|
|
|
+ tu->n_tus_incl_last_incomplete_tu = fixp2int_ceil(temp2_fp);
|
|
|
|
|
|
temp1 = 0;
|
|
|
temp1_fp = drm_fixp_from_fraction(tu->tu_size, 1);
|
|
@@ -542,9 +575,7 @@ static void _tu_valid_boundary_calc(struct tu_algo_data *tu)
|
|
|
temp1_fp = tu->average_valid2_fp - temp2_fp;
|
|
|
temp2_fp = drm_fixp_from_fraction(tu->n_tus_incl_last_incomplete_tu, 1);
|
|
|
temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp);
|
|
|
-
|
|
|
- if (temp1_fp)
|
|
|
- temp1 = drm_fixp2int_ceil(temp1_fp);
|
|
|
+ temp1 = fixp2int_ceil(temp1_fp);
|
|
|
|
|
|
temp = tu->i_upper_boundary_count * tu->nlanes;
|
|
|
temp1_fp = drm_fixp_from_fraction(tu->tu_size, 1);
|
|
@@ -553,32 +584,20 @@ static void _tu_valid_boundary_calc(struct tu_algo_data *tu)
|
|
|
temp2_fp = temp1_fp - temp2_fp;
|
|
|
temp1_fp = drm_fixp_from_fraction(temp, 1);
|
|
|
temp2_fp = drm_fixp_mul(temp1_fp, temp2_fp);
|
|
|
+ temp2 = fixp2int_ceil(temp2_fp);
|
|
|
|
|
|
- if (temp2_fp)
|
|
|
- temp2 = drm_fixp2int_ceil(temp2_fp);
|
|
|
- else
|
|
|
- temp2 = 0;
|
|
|
tu->extra_required_bytes_new_tmp = (int)(temp1 + temp2);
|
|
|
|
|
|
temp1_fp = drm_fixp_from_fraction(8, tu->bpp);
|
|
|
temp2_fp = drm_fixp_from_fraction(
|
|
|
tu->extra_required_bytes_new_tmp, 1);
|
|
|
temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp);
|
|
|
-
|
|
|
- if (temp1_fp)
|
|
|
- tu->extra_pclk_cycles_tmp = drm_fixp2int_ceil(temp1_fp);
|
|
|
- else
|
|
|
- tu->extra_pclk_cycles_tmp = 0;
|
|
|
+ tu->extra_pclk_cycles_tmp = fixp2int_ceil(temp1_fp);
|
|
|
|
|
|
temp1_fp = drm_fixp_from_fraction(tu->extra_pclk_cycles_tmp, 1);
|
|
|
temp2_fp = drm_fixp_div(tu->lclk_fp, tu->pclk_fp);
|
|
|
temp1_fp = drm_fixp_mul(temp1_fp, temp2_fp);
|
|
|
-
|
|
|
- if (temp1_fp)
|
|
|
- tu->extra_pclk_cycles_in_link_clk_tmp =
|
|
|
- drm_fixp2int_ceil(temp1_fp);
|
|
|
- else
|
|
|
- tu->extra_pclk_cycles_in_link_clk_tmp = 0;
|
|
|
+ tu->extra_pclk_cycles_in_link_clk_tmp = fixp2int_ceil(temp1_fp);
|
|
|
|
|
|
tu->filler_size_tmp = tu->tu_size - tu->new_valid_boundary_link;
|
|
|
|
|
@@ -591,6 +610,61 @@ static void _tu_valid_boundary_calc(struct tu_algo_data *tu)
|
|
|
temp1_fp = drm_fixp_from_fraction(tu->delay_start_link_tmp, 1);
|
|
|
tu->delay_start_time_fp = drm_fixp_div(temp1_fp, tu->lclk_fp);
|
|
|
|
|
|
+ if (tu->rb2)
|
|
|
+ {
|
|
|
+ temp1_fp = drm_fixp_mul(tu->delay_start_time_fp, tu->lclk_fp);
|
|
|
+ tu->delay_start_link_lclk = fixp2int_ceil(temp1_fp);
|
|
|
+
|
|
|
+ if (tu->remainder_tus > tu->i_upper_boundary_count) {
|
|
|
+ temp = (tu->remainder_tus - tu->i_upper_boundary_count) * (tu->new_valid_boundary_link - 1);
|
|
|
+ temp += (tu->i_upper_boundary_count * tu->new_valid_boundary_link);
|
|
|
+ temp *= tu->nlanes;
|
|
|
+ } else {
|
|
|
+ temp = tu->nlanes * tu->remainder_tus * tu->new_valid_boundary_link;
|
|
|
+ }
|
|
|
+
|
|
|
+ temp1 = tu->i_lower_boundary_count * (tu->new_valid_boundary_link - 1);
|
|
|
+ temp1 += tu->i_upper_boundary_count * tu->new_valid_boundary_link;
|
|
|
+ temp1 *= tu->paired_tus * tu->nlanes;
|
|
|
+ temp1_fp = drm_fixp_from_fraction(tu->n_symbols - temp1 - temp, tu->nlanes);
|
|
|
+ tu->last_partial_lclk = fixp2int_ceil(temp1_fp);
|
|
|
+
|
|
|
+ tu->tu_active_cycles = (int)((tu->n_tus_per_lane * tu->tu_size) + tu->last_partial_lclk);
|
|
|
+ tu->post_tu_hw_pipe_delay = 4 /*BS_on_the_link*/ + 1 /*BE_next_ren*/;
|
|
|
+ temp = tu->pre_tu_hw_pipe_delay + tu->delay_start_link_lclk + tu->tu_active_cycles + tu->post_tu_hw_pipe_delay;
|
|
|
+
|
|
|
+ if (tu->fec_en == 1)
|
|
|
+ {
|
|
|
+ if (tu->nlanes == 1)
|
|
|
+ {
|
|
|
+ temp1_fp = drm_fixp_from_fraction(temp, 500);
|
|
|
+ tu->parity_symbols = fixp2int_ceil(temp1_fp) * 12 + 1;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ temp1_fp = drm_fixp_from_fraction(temp, 250);
|
|
|
+ tu->parity_symbols = fixp2int_ceil(temp1_fp) * 6 + 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else //no fec BW impact
|
|
|
+ {
|
|
|
+ tu->parity_symbols = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ tu->link_config_hactive_time = temp + tu->parity_symbols;
|
|
|
+
|
|
|
+ if (tu->resolution_line_time >= tu->link_config_hactive_time + 1 /*margin*/)
|
|
|
+ tu->hbp_delayStartCheck = 1;
|
|
|
+ else
|
|
|
+ tu->hbp_delayStartCheck = 0;
|
|
|
+ } else {
|
|
|
+ compare_result_3 = _tu_param_compare(tu->hbp_time_fp, tu->delay_start_time_fp);
|
|
|
+ if (compare_result_3 < 2)
|
|
|
+ tu->hbp_delayStartCheck = 1;
|
|
|
+ else
|
|
|
+ tu->hbp_delayStartCheck = 0;
|
|
|
+ }
|
|
|
+
|
|
|
compare_result_1 = _tu_param_compare(tu->n_n_err_fp, tu->diff_abs_fp);
|
|
|
if (compare_result_1 == 2)
|
|
|
compare_result_1 = 1;
|
|
@@ -603,13 +677,6 @@ static void _tu_valid_boundary_calc(struct tu_algo_data *tu)
|
|
|
else
|
|
|
compare_result_2 = 0;
|
|
|
|
|
|
- compare_result_3 = _tu_param_compare(tu->hbp_time_fp,
|
|
|
- tu->delay_start_time_fp);
|
|
|
- if (compare_result_3 == 2)
|
|
|
- compare_result_3 = 0;
|
|
|
- else
|
|
|
- compare_result_3 = 1;
|
|
|
-
|
|
|
if (((tu->even_distribution == 1) ||
|
|
|
((tu->even_distribution_BF == 0) &&
|
|
|
(tu->even_distribution_legacy == 0))) &&
|
|
@@ -617,7 +684,7 @@ static void _tu_valid_boundary_calc(struct tu_algo_data *tu)
|
|
|
compare_result_2 &&
|
|
|
(compare_result_1 || (tu->min_hblank_violated == 1)) &&
|
|
|
(tu->new_valid_boundary_link - 1) > 0 &&
|
|
|
- compare_result_3 &&
|
|
|
+ (tu->hbp_delayStartCheck == 1) &&
|
|
|
(tu->delay_start_link_tmp <= 1023)) {
|
|
|
tu->upper_boundary_count = tu->i_upper_boundary_count;
|
|
|
tu->lower_boundary_count = tu->i_lower_boundary_count;
|
|
@@ -638,7 +705,6 @@ static void _tu_valid_boundary_calc(struct tu_algo_data *tu)
|
|
|
|
|
|
static void _dp_calc_boundary(struct tu_algo_data *tu)
|
|
|
{
|
|
|
-
|
|
|
s64 temp1_fp = 0, temp2_fp = 0;
|
|
|
|
|
|
do {
|
|
@@ -648,20 +714,11 @@ static void _dp_calc_boundary(struct tu_algo_data *tu)
|
|
|
temp2_fp = drm_fixp_from_fraction(
|
|
|
tu->delay_start_link_extra_pixclk, 1);
|
|
|
temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp);
|
|
|
-
|
|
|
- if (temp1_fp)
|
|
|
- tu->extra_buffer_margin =
|
|
|
- drm_fixp2int_ceil(temp1_fp);
|
|
|
- else
|
|
|
- tu->extra_buffer_margin = 0;
|
|
|
+ tu->extra_buffer_margin = fixp2int_ceil(temp1_fp);
|
|
|
|
|
|
temp1_fp = drm_fixp_from_fraction(tu->bpp, 8);
|
|
|
temp1_fp = drm_fixp_mul(tu->lwidth_fp, temp1_fp);
|
|
|
-
|
|
|
- if (temp1_fp)
|
|
|
- tu->n_symbols = drm_fixp2int_ceil(temp1_fp);
|
|
|
- else
|
|
|
- tu->n_symbols = 0;
|
|
|
+ tu->n_symbols = fixp2int_ceil(temp1_fp);
|
|
|
|
|
|
for (tu->tu_size = 32; tu->tu_size <= 64; tu->tu_size++) {
|
|
|
for (tu->i_upper_boundary_count = 1;
|
|
@@ -677,7 +734,8 @@ static void _dp_calc_boundary(struct tu_algo_data *tu)
|
|
|
tu->delay_start_link_extra_pixclk--;
|
|
|
} while (!tu->boundary_moderation_en &&
|
|
|
tu->boundary_mod_lower_err == 1 &&
|
|
|
- tu->delay_start_link_extra_pixclk != 0);
|
|
|
+ tu->delay_start_link_extra_pixclk != 0 &&
|
|
|
+ ((tu->second_loop_set == 0 && tu->rb2 == 1) || tu->rb2 == 0));
|
|
|
}
|
|
|
|
|
|
static void _dp_calc_extra_bytes(struct tu_algo_data *tu)
|
|
@@ -693,28 +751,20 @@ static void _dp_calc_extra_bytes(struct tu_algo_data *tu)
|
|
|
temp2_fp = drm_fixp_mul(temp1_fp, temp2_fp);
|
|
|
|
|
|
temp = drm_fixp2int(temp2_fp);
|
|
|
- if (temp && temp2_fp)
|
|
|
- tu->extra_bytes = drm_fixp2int_ceil(temp2_fp);
|
|
|
+ if (temp)
|
|
|
+ tu->extra_bytes = fixp2int_ceil(temp2_fp);
|
|
|
else
|
|
|
tu->extra_bytes = 0;
|
|
|
|
|
|
temp1_fp = drm_fixp_from_fraction(tu->extra_bytes, 1);
|
|
|
temp2_fp = drm_fixp_from_fraction(8, tu->bpp);
|
|
|
temp1_fp = drm_fixp_mul(temp1_fp, temp2_fp);
|
|
|
-
|
|
|
- if (temp1_fp)
|
|
|
- tu->extra_pclk_cycles = drm_fixp2int_ceil(temp1_fp);
|
|
|
- else
|
|
|
- tu->extra_pclk_cycles = drm_fixp2int(temp1_fp);
|
|
|
+ tu->extra_pclk_cycles = fixp2int_ceil(temp1_fp);
|
|
|
|
|
|
temp1_fp = drm_fixp_div(tu->lclk_fp, tu->pclk_fp);
|
|
|
temp2_fp = drm_fixp_from_fraction(tu->extra_pclk_cycles, 1);
|
|
|
temp1_fp = drm_fixp_mul(temp2_fp, temp1_fp);
|
|
|
-
|
|
|
- if (temp1_fp)
|
|
|
- tu->extra_pclk_cycles_in_link_clk = drm_fixp2int_ceil(temp1_fp);
|
|
|
- else
|
|
|
- tu->extra_pclk_cycles_in_link_clk = drm_fixp2int(temp1_fp);
|
|
|
+ tu->extra_pclk_cycles_in_link_clk = fixp2int_ceil(temp1_fp);
|
|
|
}
|
|
|
|
|
|
static void _dp_panel_calc_tu(struct dp_tu_calc_input *in,
|
|
@@ -722,18 +772,17 @@ static void _dp_panel_calc_tu(struct dp_tu_calc_input *in,
|
|
|
{
|
|
|
struct tu_algo_data tu;
|
|
|
int compare_result_1, compare_result_2;
|
|
|
- u64 temp = 0;
|
|
|
+ u64 temp = 0, temp1;
|
|
|
s64 temp_fp = 0, temp1_fp = 0, temp2_fp = 0;
|
|
|
|
|
|
s64 LCLK_FAST_SKEW_fp = drm_fixp_from_fraction(6, 10000); /* 0.0006 */
|
|
|
- s64 const_p49_fp = drm_fixp_from_fraction(49, 100); /* 0.49 */
|
|
|
- s64 const_p56_fp = drm_fixp_from_fraction(56, 100); /* 0.56 */
|
|
|
s64 RATIO_SCALE_fp = drm_fixp_from_fraction(1001, 1000);
|
|
|
|
|
|
u8 DP_BRUTE_FORCE = 1;
|
|
|
s64 BRUTE_FORCE_THRESHOLD_fp = drm_fixp_from_fraction(1, 10); /* 0.1 */
|
|
|
uint EXTRA_PIXCLK_CYCLE_DELAY = 4;
|
|
|
- uint HBLANK_MARGIN = 4;
|
|
|
+ s64 HBLANK_MARGIN = drm_fixp_from_fraction(4, 1);
|
|
|
+ s64 HBLANK_MARGIN_EXTRA = 0;
|
|
|
|
|
|
memset(&tu, 0, sizeof(tu));
|
|
|
|
|
@@ -744,9 +793,13 @@ static void _dp_panel_calc_tu(struct dp_tu_calc_input *in,
|
|
|
temp1_fp = drm_fixp_from_fraction(4, 1);
|
|
|
temp2_fp = drm_fixp_mul(temp1_fp, tu.lclk_fp);
|
|
|
temp_fp = drm_fixp_div(temp2_fp, tu.pclk_fp);
|
|
|
- tu.extra_buffer_margin = drm_fixp2int_ceil(temp_fp);
|
|
|
+ tu.extra_buffer_margin = fixp2int_ceil(temp_fp);
|
|
|
+
|
|
|
+ if (in->compress_ratio == 375 && tu.bpp == 30)
|
|
|
+ temp1_fp = drm_fixp_from_fraction(24, 8);
|
|
|
+ else
|
|
|
+ temp1_fp = drm_fixp_from_fraction(tu.bpp, 8);
|
|
|
|
|
|
- temp1_fp = drm_fixp_from_fraction(tu.bpp, 8);
|
|
|
temp2_fp = drm_fixp_mul(tu.pclk_fp, temp1_fp);
|
|
|
temp1_fp = drm_fixp_from_fraction(tu.nlanes, 1);
|
|
|
temp2_fp = drm_fixp_div(temp2_fp, temp1_fp);
|
|
@@ -762,51 +815,42 @@ static void _dp_panel_calc_tu(struct dp_tu_calc_input *in,
|
|
|
tu.even_distribution_BF = 0;
|
|
|
tu.even_distribution_legacy = 0;
|
|
|
tu.even_distribution = 0;
|
|
|
+ tu.hbp_delayStartCheck = 0;
|
|
|
+ tu.pre_tu_hw_pipe_delay = 0;
|
|
|
+ tu.post_tu_hw_pipe_delay = 0;
|
|
|
+ tu.link_config_hactive_time = 0;
|
|
|
+ tu.delay_start_link_lclk = 0;
|
|
|
+ tu.tu_active_cycles = 0;
|
|
|
+ tu.resolution_line_time = 0;
|
|
|
+ tu.last_partial_lclk = 0;
|
|
|
tu.delay_start_time_fp = 0;
|
|
|
+ tu.second_loop_set = 0;
|
|
|
|
|
|
tu.err_fp = drm_fixp_from_fraction(1000, 1);
|
|
|
tu.n_err_fp = 0;
|
|
|
tu.n_n_err_fp = 0;
|
|
|
|
|
|
- tu.ratio = drm_fixp2int(tu.ratio_fp);
|
|
|
- temp1_fp = drm_fixp_from_fraction(tu.nlanes, 1);
|
|
|
- temp2_fp = tu.lwidth_fp % temp1_fp;
|
|
|
- if (temp2_fp != 0 &&
|
|
|
- !tu.ratio && tu.dsc_en == 0) {
|
|
|
+ temp = drm_fixp2int(tu.lwidth_fp);
|
|
|
+ if ((((u32)temp % tu.nlanes) != 0) && (_tu_param_compare(tu.ratio_fp, DRM_FIXED_ONE) == 2)
|
|
|
+ && (tu.dsc_en == 0)) {
|
|
|
tu.ratio_fp = drm_fixp_mul(tu.ratio_fp, RATIO_SCALE_fp);
|
|
|
- tu.ratio = drm_fixp2int(tu.ratio_fp);
|
|
|
- if (tu.ratio)
|
|
|
- tu.ratio_fp = drm_fixp_from_fraction(1, 1);
|
|
|
+ if (_tu_param_compare(tu.ratio_fp, DRM_FIXED_ONE) == 1)
|
|
|
+ tu.ratio_fp = DRM_FIXED_ONE;
|
|
|
}
|
|
|
|
|
|
- if (tu.ratio > 1)
|
|
|
- tu.ratio = 1;
|
|
|
-
|
|
|
- if (tu.ratio == 1)
|
|
|
- goto tu_size_calc;
|
|
|
+ if (_tu_param_compare(tu.ratio_fp, DRM_FIXED_ONE) == 1)
|
|
|
+ tu.ratio_fp = DRM_FIXED_ONE;
|
|
|
|
|
|
- compare_result_1 = _tu_param_compare(tu.ratio_fp, const_p49_fp);
|
|
|
- if (!compare_result_1 || compare_result_1 == 1)
|
|
|
- compare_result_1 = 1;
|
|
|
- else
|
|
|
- compare_result_1 = 0;
|
|
|
-
|
|
|
- compare_result_2 = _tu_param_compare(tu.ratio_fp, const_p56_fp);
|
|
|
- if (!compare_result_2 || compare_result_2 == 2)
|
|
|
- compare_result_2 = 1;
|
|
|
- else
|
|
|
- compare_result_2 = 0;
|
|
|
-
|
|
|
- if (tu.dsc_en && compare_result_1 && compare_result_2) {
|
|
|
- HBLANK_MARGIN += 4;
|
|
|
- DP_DEBUG("Info: increase HBLANK_MARGIN to %d\n", HBLANK_MARGIN);
|
|
|
+ if (HBLANK_MARGIN_EXTRA != 0) {
|
|
|
+ HBLANK_MARGIN += HBLANK_MARGIN_EXTRA;
|
|
|
+ DP_DEBUG("Info: increase HBLANK_MARGIN to %d. (PLUS%d)\n", HBLANK_MARGIN,
|
|
|
+ HBLANK_MARGIN_EXTRA);
|
|
|
}
|
|
|
|
|
|
-tu_size_calc:
|
|
|
for (tu.tu_size = 32; tu.tu_size <= 64; tu.tu_size++) {
|
|
|
temp1_fp = drm_fixp_from_fraction(tu.tu_size, 1);
|
|
|
temp2_fp = drm_fixp_mul(tu.ratio_fp, temp1_fp);
|
|
|
- temp = drm_fixp2int_ceil(temp2_fp);
|
|
|
+ temp = fixp2int_ceil(temp2_fp);
|
|
|
temp1_fp = drm_fixp_from_fraction(temp, 1);
|
|
|
tu.n_err_fp = temp1_fp - temp2_fp;
|
|
|
|
|
@@ -820,7 +864,7 @@ tu_size_calc:
|
|
|
|
|
|
temp1_fp = drm_fixp_from_fraction(tu.tu_size_desired, 1);
|
|
|
temp2_fp = drm_fixp_mul(tu.ratio_fp, temp1_fp);
|
|
|
- tu.valid_boundary_link = drm_fixp2int_ceil(temp2_fp);
|
|
|
+ tu.valid_boundary_link = fixp2int_ceil(temp2_fp);
|
|
|
|
|
|
temp1_fp = drm_fixp_from_fraction(tu.bpp, 8);
|
|
|
temp2_fp = tu.lwidth_fp;
|
|
@@ -853,8 +897,7 @@ tu_size_calc:
|
|
|
temp2_fp = drm_fixp_div(tu.resulting_valid_fp, temp1_fp);
|
|
|
tu.TU_ratio_err_fp = temp2_fp - tu.original_ratio_fp;
|
|
|
|
|
|
- temp1_fp = drm_fixp_from_fraction(HBLANK_MARGIN, 1);
|
|
|
- temp1_fp = tu.hbp_relative_to_pclk_fp - temp1_fp;
|
|
|
+ temp1_fp = drm_fixp_from_fraction((tu.hbp_relative_to_pclk - HBLANK_MARGIN), 1);
|
|
|
tu.hbp_time_fp = drm_fixp_div(temp1_fp, tu.pclk_fp);
|
|
|
|
|
|
temp1_fp = drm_fixp_from_fraction(tu.delay_start_link, 1);
|
|
@@ -872,8 +915,6 @@ tu_size_calc:
|
|
|
if (compare_result_2 == 2)
|
|
|
tu.min_hblank_violated = 1;
|
|
|
|
|
|
- tu.delay_start_time_fp = 0;
|
|
|
-
|
|
|
/* brute force */
|
|
|
|
|
|
tu.delay_start_link_extra_pixclk = EXTRA_PIXCLK_CYCLE_DELAY;
|
|
@@ -888,12 +929,93 @@ tu_size_calc:
|
|
|
tu.diff_abs_fp = drm_fixp_mul(tu.diff_abs_fp, -1);
|
|
|
|
|
|
tu.boundary_mod_lower_err = 0;
|
|
|
+
|
|
|
+ temp1_fp = drm_fixp_div(tu.orig_lclk_fp, tu.orig_pclk_fp);
|
|
|
+
|
|
|
+ temp2_fp = drm_fixp_from_fraction(tu.orig_lwidth + tu.orig_hbp, 2);
|
|
|
+ temp_fp = drm_fixp_mul(temp1_fp, temp2_fp);
|
|
|
+ tu.resolution_line_time = drm_fixp2int(temp_fp);
|
|
|
+ tu.pre_tu_hw_pipe_delay = fixp2int_ceil(temp1_fp) + 2 /*cdc fifo write jitter+2*/
|
|
|
+ + 3 /*pre-delay start cycles*/
|
|
|
+ + 3 /*post-delay start cycles*/ + 1 /*BE on the link*/;
|
|
|
+ tu.post_tu_hw_pipe_delay = 4 /*BS_on_the_link*/ + 1 /*BE_next_ren*/;
|
|
|
+
|
|
|
+ temp1_fp = drm_fixp_from_fraction(tu.bpp, 8);
|
|
|
+ temp1_fp = drm_fixp_mul(tu.lwidth_fp, temp1_fp);
|
|
|
+ tu.n_symbols = fixp2int_ceil(temp1_fp);
|
|
|
+
|
|
|
+ if (tu.rb2)
|
|
|
+ {
|
|
|
+ temp1_fp = drm_fixp_mul(tu.delay_start_time_fp, tu.lclk_fp);
|
|
|
+ tu.delay_start_link_lclk = fixp2int_ceil(temp1_fp);
|
|
|
+
|
|
|
+ tu.new_valid_boundary_link = tu.valid_boundary_link;
|
|
|
+ tu.i_upper_boundary_count = 1;
|
|
|
+ tu.i_lower_boundary_count = 0;
|
|
|
+
|
|
|
+ temp1 = tu.i_upper_boundary_count * tu.new_valid_boundary_link;
|
|
|
+ temp1 += tu.i_lower_boundary_count * (tu.new_valid_boundary_link - 1);
|
|
|
+ tu.average_valid2_fp = drm_fixp_from_fraction(temp1, (tu.i_upper_boundary_count + tu.i_lower_boundary_count));
|
|
|
+
|
|
|
+ temp1_fp = drm_fixp_from_fraction(tu.bpp, 8);
|
|
|
+ temp1_fp = drm_fixp_mul(tu.lwidth_fp, temp1_fp);
|
|
|
+ temp2_fp = drm_fixp_div(temp1_fp, tu.average_valid2_fp);
|
|
|
+ tu.n_tus = drm_fixp2int(temp2_fp);
|
|
|
+
|
|
|
+ tu.n_tus_per_lane = tu.n_tus / tu.nlanes;
|
|
|
+ tu.paired_tus = (int)((tu.n_tus_per_lane) / (tu.i_upper_boundary_count + tu.i_lower_boundary_count));
|
|
|
+
|
|
|
+ tu.remainder_tus = tu.n_tus_per_lane - tu.paired_tus * (tu.i_upper_boundary_count + tu.i_lower_boundary_count);
|
|
|
+
|
|
|
+ if (tu.remainder_tus > tu.i_upper_boundary_count) {
|
|
|
+ temp = (tu.remainder_tus - tu.i_upper_boundary_count) * (tu.new_valid_boundary_link - 1);
|
|
|
+ temp += (tu.i_upper_boundary_count * tu.new_valid_boundary_link);
|
|
|
+ temp *= tu.nlanes;
|
|
|
+ } else {
|
|
|
+ temp = tu.nlanes * tu.remainder_tus * tu.new_valid_boundary_link;
|
|
|
+ }
|
|
|
+
|
|
|
+ temp1 = tu.i_lower_boundary_count * (tu.new_valid_boundary_link - 1);
|
|
|
+ temp1 += tu.i_upper_boundary_count * tu.new_valid_boundary_link;
|
|
|
+ temp1 *= tu.paired_tus * tu.nlanes;
|
|
|
+ temp1_fp = drm_fixp_from_fraction(tu.n_symbols - temp1 - temp, tu.nlanes);
|
|
|
+ tu.last_partial_lclk = fixp2int_ceil(temp1_fp);
|
|
|
+
|
|
|
+ tu.tu_active_cycles = (int)((tu.n_tus_per_lane * tu.tu_size) + tu.last_partial_lclk);
|
|
|
+
|
|
|
+ temp = tu.pre_tu_hw_pipe_delay + tu.delay_start_link_lclk + tu.tu_active_cycles + tu.post_tu_hw_pipe_delay;
|
|
|
+
|
|
|
+ if (tu.fec_en == 1)
|
|
|
+ {
|
|
|
+ if (tu.nlanes == 1)
|
|
|
+ {
|
|
|
+ temp1_fp = drm_fixp_from_fraction(temp, 500);
|
|
|
+ tu.parity_symbols = fixp2int_ceil(temp1_fp) * 12 + 1;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ temp1_fp = drm_fixp_from_fraction(temp, 250);
|
|
|
+ tu.parity_symbols = fixp2int_ceil(temp1_fp) * 6 + 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else //no fec BW impact
|
|
|
+ {
|
|
|
+ tu.parity_symbols = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ tu.link_config_hactive_time = temp + tu.parity_symbols;
|
|
|
+
|
|
|
+ if (tu.link_config_hactive_time + 1 /*margin*/ >= tu.resolution_line_time)
|
|
|
+ tu.min_hblank_violated = 1;
|
|
|
+ }
|
|
|
+
|
|
|
+ tu.delay_start_time_fp = 0;
|
|
|
+
|
|
|
if ((tu.diff_abs_fp != 0 &&
|
|
|
((tu.diff_abs_fp > BRUTE_FORCE_THRESHOLD_fp) ||
|
|
|
(tu.even_distribution_legacy == 0) ||
|
|
|
(DP_BRUTE_FORCE == 1))) ||
|
|
|
(tu.min_hblank_violated == 1)) {
|
|
|
-
|
|
|
_dp_calc_boundary(&tu);
|
|
|
|
|
|
if (tu.boundary_moderation_en) {
|
|
@@ -933,23 +1055,20 @@ tu_size_calc:
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- temp2_fp = drm_fixp_mul(LCLK_FAST_SKEW_fp, tu.lwidth_fp);
|
|
|
+ if (tu.async_en) {
|
|
|
+ temp2_fp = drm_fixp_mul(LCLK_FAST_SKEW_fp, tu.lwidth_fp);
|
|
|
+ temp = fixp2int_ceil(temp2_fp);
|
|
|
|
|
|
- if (temp2_fp)
|
|
|
- temp = drm_fixp2int_ceil(temp2_fp);
|
|
|
- else
|
|
|
- temp = 0;
|
|
|
-
|
|
|
- temp1_fp = drm_fixp_from_fraction(tu.nlanes, 1);
|
|
|
- temp2_fp = drm_fixp_mul(tu.original_ratio_fp, temp1_fp);
|
|
|
- temp1_fp = drm_fixp_from_fraction(tu.bpp, 8);
|
|
|
- temp2_fp = drm_fixp_div(temp1_fp, temp2_fp);
|
|
|
- temp1_fp = drm_fixp_from_fraction(temp, 1);
|
|
|
- temp2_fp = drm_fixp_mul(temp1_fp, temp2_fp);
|
|
|
- temp = drm_fixp2int(temp2_fp);
|
|
|
+ temp1_fp = drm_fixp_from_fraction(tu.nlanes, 1);
|
|
|
+ temp2_fp = drm_fixp_mul(tu.original_ratio_fp, temp1_fp);
|
|
|
+ temp1_fp = drm_fixp_from_fraction(tu.bpp, 8);
|
|
|
+ temp2_fp = drm_fixp_div(temp1_fp, temp2_fp);
|
|
|
+ temp1_fp = drm_fixp_from_fraction(temp, 1);
|
|
|
+ temp2_fp = drm_fixp_mul(temp1_fp, temp2_fp);
|
|
|
+ temp = drm_fixp2int(temp2_fp);
|
|
|
|
|
|
- if (tu.async_en)
|
|
|
tu.delay_start_link += (int)temp;
|
|
|
+ }
|
|
|
|
|
|
temp1_fp = drm_fixp_from_fraction(tu.delay_start_link, 1);
|
|
|
tu.delay_start_time_fp = drm_fixp_div(temp1_fp, tu.lclk_fp);
|
|
@@ -1235,7 +1354,7 @@ static void dp_panel_dsc_pclk_param_calc(struct dp_panel *dp_panel,
|
|
|
numerator_fp = drm_fixp_from_fraction(
|
|
|
intf_width * dsc->config.bits_per_component * 3, 1);
|
|
|
dsc_byte_count_fp = drm_fixp_div(numerator_fp, denominator_fp);
|
|
|
- dsc_byte_count = drm_fixp2int_ceil(dsc_byte_count_fp);
|
|
|
+ dsc_byte_count = fixp2int_ceil(dsc_byte_count_fp);
|
|
|
|
|
|
temp1 = dsc_byte_count * slice_per_intf;
|
|
|
temp2 = temp1;
|
|
@@ -1246,7 +1365,7 @@ static void dp_panel_dsc_pclk_param_calc(struct dp_panel *dp_panel,
|
|
|
|
|
|
temp1_fp = drm_fixp_from_fraction(slice_per_intf, 6);
|
|
|
temp2_fp = drm_fixp_mul(dsc_byte_count_fp, temp1_fp);
|
|
|
- dsc->pclk_per_line = drm_fixp2int_ceil(temp2_fp);
|
|
|
+ dsc->pclk_per_line = fixp2int_ceil(temp2_fp);
|
|
|
|
|
|
_dp_panel_dsc_get_num_extra_pclk(dsc, ratio);
|
|
|
dsc->pclk_per_line--;
|
|
@@ -2349,21 +2468,21 @@ static u32 dp_panel_calc_dhdr_pkt_limit(struct dp_panel *dp_panel,
|
|
|
if (input->mst_en)
|
|
|
mst_bw_fp = drm_fixp_div(target_sc, i64_fp);
|
|
|
|
|
|
- f1 = drm_fixp2int_ceil(drm_fixp_div(drm_fixp_mul(i10_fp, lclk_fp),
|
|
|
+ f1 = fixp2int_ceil(drm_fixp_div(drm_fixp_mul(i10_fp, lclk_fp),
|
|
|
mdpclk_fp));
|
|
|
- f2 = drm_fixp2int_ceil(drm_fixp_div(drm_fixp_mul(i2_fp, lclk_fp),
|
|
|
- mdpclk_fp)) + drm_fixp2int_ceil(drm_fixp_div(
|
|
|
+ f2 = fixp2int_ceil(drm_fixp_div(drm_fixp_mul(i2_fp, lclk_fp),
|
|
|
+ mdpclk_fp)) + fixp2int_ceil(drm_fixp_div(
|
|
|
drm_fixp_mul(i1_fp, lclk_fp), mdpclk_fp));
|
|
|
|
|
|
mst_bw64_fp = drm_fixp_mul(mst_bw_fp, i64_fp);
|
|
|
if (drm_fixp2int(mst_bw64_fp) == 0)
|
|
|
f3_f5_slot_fp = drm_fixp_div(i1_fp, drm_int2fixp(
|
|
|
- drm_fixp2int_ceil(drm_fixp_div(
|
|
|
+ fixp2int_ceil(drm_fixp_div(
|
|
|
i1_fp, mst_bw64_fp))));
|
|
|
else
|
|
|
f3_f5_slot_fp = drm_int2fixp(drm_fixp2int(mst_bw_fp));
|
|
|
|
|
|
- mst_bw64_ceil_fp = drm_int2fixp(drm_fixp2int_ceil(mst_bw64_fp));
|
|
|
+ mst_bw64_ceil_fp = drm_int2fixp(fixp2int_ceil(mst_bw64_fp));
|
|
|
f3 = drm_fixp2int(drm_fixp_mul(drm_int2fixp(drm_fixp2int(
|
|
|
drm_fixp_div(i2_fp, f3_f5_slot_fp)) + 1),
|
|
|
(i64_fp - mst_bw64_ceil_fp))) + 2;
|