From cbe07adbf254a632a26b87e80acb39c7211ad234 Mon Sep 17 00:00:00 2001 From: Chandan Uddaraju Date: Tue, 15 Nov 2016 23:55:42 -0800 Subject: [PATCH 1/2] mdss: display-port: add support to configure transfer unit attributes Add code to calculate transfer unit parameters that change depending on the DP monitor/Sync resolution. Use these parameters to configure the transfer unit registers. CRs-Fixed: 1086278 Change-Id: If2978d3721c7ac6910379f3d31342f820062e3c6 Signed-off-by: Chandan Uddaraju --- drivers/video/fbdev/msm/mdss_dp_aux.c | 3 +- drivers/video/fbdev/msm/mdss_dp_util.c | 500 ++++++++++++++++++++++++- drivers/video/fbdev/msm/mdss_dp_util.h | 2 +- 3 files changed, 494 insertions(+), 11 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_dp_aux.c b/drivers/video/fbdev/msm/mdss_dp_aux.c index fb88fb8fc335..fa1af0d392e7 100644 --- a/drivers/video/fbdev/msm/mdss_dp_aux.c +++ b/drivers/video/fbdev/msm/mdss_dp_aux.c @@ -1836,7 +1836,8 @@ clear: mdss_dp_config_misc_settings(&dp->ctrl_io, &dp->panel_data.panel_info); mdss_dp_setup_tr_unit(&dp->ctrl_io, dp->link_rate, - dp->lane_cnt, dp->vic); + dp->lane_cnt, dp->vic, + &dp->panel_data.panel_info); mdss_dp_state_ctrl(&dp->ctrl_io, ST_SEND_VIDEO); pr_debug("State_ctrl set to SEND_VIDEO\n"); } diff --git a/drivers/video/fbdev/msm/mdss_dp_util.c b/drivers/video/fbdev/msm/mdss_dp_util.c index 3b294a11f555..39d82efdcde5 100644 --- a/drivers/video/fbdev/msm/mdss_dp_util.c +++ b/drivers/video/fbdev/msm/mdss_dp_util.c @@ -208,6 +208,487 @@ void mdss_dp_state_ctrl(struct dss_io_data *ctrl_io, u32 data) writel_relaxed(data, ctrl_io->base + DP_STATE_CTRL); } +static void mdss_dp_get_extra_req_bytes(u64 result_valid, + int valid_bdary_link, + u64 value1, u64 value2, + bool *negative, u64 *result, + u64 compare) +{ + *negative = false; + if (result_valid >= compare) { + if (valid_bdary_link + >= compare) + *result = value1 + value2; + else { + if (value1 < value2) + *negative = true; + *result = (value1 >= value2) ? + (value1 - value2) : (value2 - value1); + } + } else { + if (valid_bdary_link + >= compare) { + if (value1 >= value2) + *negative = true; + *result = (value1 >= value2) ? + (value1 - value2) : (value2 - value1); + } else { + *result = value1 + value2; + *negative = true; + } + } +} + + +static void mdss_dp_calc_tu_parameters(u8 link_rate, u8 ln_cnt, + struct dp_vc_tu_mapping_table *tu_table, + struct mdss_panel_info *pinfo) +{ + u64 const multiplier = 1000000; + u64 pclk, lclk; + u8 bpp; + int run_idx = 0; + u32 lwidth, h_blank; + u32 fifo_empty = 0; + u32 ratio_scale = 1001, reminder; + u64 temp, ratio, original_ratio; + u64 temp2; + u64 temp3, temp4, result = 0; + + u64 err = multiplier; + u64 n_err = 0, n_n_err = 0; + bool n_err_neg, nn_err_neg; + u8 hblank_margin = 16; + + u8 tu_size, tu_size_desired, tu_size_minus1; + int valid_boundary_link; + u64 resulting_valid; + u64 total_valid; + u64 effective_valid; + u64 effective_valid_recorded; + int n_tus; + int n_tus_per_lane; + int paired_tus; + int remainder_tus; + int remainder_tus_upper, remainder_tus_lower; + int extra_bytes; + int filler_size; + int delay_start_link; + int boundary_moderation_en = 0; + int upper_bdry_cnt = 0; + int lower_bdry_cnt = 0; + int i_upper_bdry_cnt = 0; + int i_lower_bdry_cnt = 0; + int valid_lower_boundary_link = 0; + int even_distribution_bf = 0; + int even_distribution_legacy = 0; + int even_distribution = 0; + int min_hblank = 0; + int extra_pclk_cycles; + u8 extra_pclk_cycle_delay = 4; + int extra_pclk_cycles_in_link_clk; + u64 ratio_by_tu; + u64 average_valid2; + u64 extra_buffer_margin; + int new_valid_boundary_link; + + u64 resulting_valid_tmp; + u64 ratio_by_tu_tmp; + int n_tus_tmp; + int extra_pclk_cycles_tmp; + int extra_pclk_cycles_in_lclk_tmp; + int extra_req_bytes_new_tmp; + int filler_size_tmp; + int lower_filler_size_tmp; + int delay_start_link_tmp; + int min_hblank_tmp = 0; + bool extra_req_bytes_is_neg = false; + + u8 dp_brute_force = 1; + u64 brute_force_threshold = 10; + u64 diff_abs; + + bpp = pinfo->bpp; + lwidth = pinfo->xres; /* active width */ + h_blank = pinfo->lcdc.h_back_porch + pinfo->lcdc.h_front_porch + + pinfo->lcdc.h_pulse_width; + pclk = pinfo->clk_rate; + + boundary_moderation_en = 0; + upper_bdry_cnt = 0; + lower_bdry_cnt = 0; + i_upper_bdry_cnt = 0; + i_lower_bdry_cnt = 0; + valid_lower_boundary_link = 0; + even_distribution_bf = 0; + even_distribution_legacy = 0; + even_distribution = 0; + min_hblank = 0; + + lclk = link_rate * DP_LINK_RATE_MULTIPLIER; + + pr_debug("pclk=%lld, active_width=%d, h_blank=%d\n", + pclk, lwidth, h_blank); + pr_debug("lclk = %lld, ln_cnt = %d\n", lclk, ln_cnt); + ratio = div_u64_rem(pclk * bpp * multiplier, + 8 * ln_cnt * lclk, &reminder); + ratio = (pclk * bpp * multiplier) / (8 * ln_cnt * lclk); + original_ratio = ratio; + + extra_buffer_margin = roundup(extra_pclk_cycle_delay + * lclk * multiplier / pclk, multiplier); + extra_buffer_margin /= multiplier; + + /* To deal with cases where lines are not distributable */ + if (((lwidth % ln_cnt) != 0) && ratio < multiplier) { + ratio = ratio * ratio_scale; + ratio = ratio < (1000 * multiplier) + ? ratio : (1000 * multiplier); + } + pr_debug("ratio = %lld\n", ratio); + + for (tu_size = 32; tu_size <= 64; tu_size++) { + temp = ratio * tu_size; + temp2 = ((temp / multiplier) + 1) * multiplier; + n_err = roundup(temp, multiplier) - temp; + + if (n_err < err) { + err = n_err; + tu_size_desired = tu_size; + } + } + pr_debug("Info: tu_size_desired = %d\n", tu_size_desired); + + tu_size_minus1 = tu_size_desired - 1; + + valid_boundary_link = roundup(ratio * tu_size_desired, multiplier); + valid_boundary_link /= multiplier; + n_tus = rounddown((lwidth * bpp * multiplier) + / (8 * valid_boundary_link), multiplier) / multiplier; + even_distribution_legacy = n_tus % ln_cnt == 0 ? 1 : 0; + pr_debug("Info: n_symbol_per_tu=%d, number_of_tus=%d\n", + valid_boundary_link, n_tus); + + extra_bytes = roundup((n_tus + 1) + * ((valid_boundary_link * multiplier) + - (original_ratio * tu_size_desired)), multiplier); + extra_bytes /= multiplier; + extra_pclk_cycles = roundup(extra_bytes + * 8 * multiplier / bpp, multiplier); + extra_pclk_cycles /= multiplier; + extra_pclk_cycles_in_link_clk = roundup(extra_pclk_cycles + * lclk * multiplier / pclk, multiplier); + extra_pclk_cycles_in_link_clk /= multiplier; + filler_size = roundup((tu_size_desired - valid_boundary_link) + * multiplier, multiplier); + filler_size /= multiplier; + ratio_by_tu = (ratio * tu_size_desired) / multiplier; + + pr_debug("extra_pclk_cycles_in_link_clk=%d, extra_bytes=%d\n", + extra_pclk_cycles_in_link_clk, extra_bytes); + pr_debug("extra_pclk_cycles_in_link_clk=%d\n", + extra_pclk_cycles_in_link_clk); + pr_debug("filler_size=%d, extra_buffer_margin=%lld\n", + filler_size, extra_buffer_margin); + + delay_start_link = ((extra_bytes > extra_pclk_cycles_in_link_clk) + ? extra_bytes + : extra_pclk_cycles_in_link_clk) + + filler_size + extra_buffer_margin; + resulting_valid = valid_boundary_link; + pr_debug("Info: delay_start_link=%d, filler_size=%d\n", + delay_start_link, filler_size); + pr_debug("valid_boundary_link=%d ratio_by_tu=%lld\n", + valid_boundary_link, ratio_by_tu); + + diff_abs = (resulting_valid >= ratio_by_tu) + ? (resulting_valid - ratio_by_tu) + : (ratio_by_tu - resulting_valid); + + if (err != 0 && ((diff_abs > brute_force_threshold) + || (even_distribution_legacy == 0) + || (dp_brute_force == 1))) { + err = multiplier; + for (tu_size = 32; tu_size <= 64; tu_size++) { + for (i_upper_bdry_cnt = 1; i_upper_bdry_cnt <= 15; + i_upper_bdry_cnt++) { + for (i_lower_bdry_cnt = 1; + i_lower_bdry_cnt <= 15; + i_lower_bdry_cnt++) { + new_valid_boundary_link = + roundup(ratio + * tu_size, multiplier); + average_valid2 = + (u64)(i_upper_bdry_cnt + * new_valid_boundary_link + + i_lower_bdry_cnt + * (new_valid_boundary_link + - multiplier)) + / (i_upper_bdry_cnt + + i_lower_bdry_cnt); + n_tus = + rounddown(((u64)lwidth + * multiplier * multiplier + * (u64)bpp / 8) + / (u64)average_valid2, + multiplier); + n_tus /= multiplier; + n_tus_per_lane + = rounddown(n_tus + * multiplier + / ln_cnt, multiplier); + n_tus_per_lane /= multiplier; + paired_tus = + rounddown((n_tus_per_lane) + * multiplier + / (i_upper_bdry_cnt + + i_lower_bdry_cnt), + multiplier); + paired_tus /= multiplier; + remainder_tus = n_tus_per_lane + - paired_tus + * (i_upper_bdry_cnt + + i_lower_bdry_cnt); + if ((remainder_tus + - i_upper_bdry_cnt) > 0) { + remainder_tus_upper + = i_upper_bdry_cnt; + remainder_tus_lower = + remainder_tus + - i_upper_bdry_cnt; + } else { + remainder_tus_upper + = remainder_tus; + remainder_tus_lower = 0; + } + total_valid = paired_tus + * (i_upper_bdry_cnt + * new_valid_boundary_link + + i_lower_bdry_cnt + * (new_valid_boundary_link + - multiplier)) + + (remainder_tus_upper + * new_valid_boundary_link) + + (remainder_tus_lower + * (new_valid_boundary_link + - multiplier)); + n_err_neg = nn_err_neg = false; + effective_valid + = total_valid + / n_tus_per_lane; + n_n_err = (effective_valid + >= (ratio * tu_size)) + ? (effective_valid + - (ratio * tu_size)) + : ((ratio * tu_size) + - effective_valid); + if (effective_valid < (ratio * tu_size)) + nn_err_neg = true; + n_err = (average_valid2 + >= (ratio * tu_size)) + ? (average_valid2 + - (ratio * tu_size)) + : ((ratio * tu_size) + - average_valid2); + if (average_valid2 < (ratio * tu_size)) + n_err_neg = true; + even_distribution = + n_tus % ln_cnt == 0 ? 1 : 0; + diff_abs = + resulting_valid >= ratio_by_tu + ? (resulting_valid + - ratio_by_tu) + : (ratio_by_tu + - resulting_valid); + + resulting_valid_tmp = + (u64)(i_upper_bdry_cnt + * new_valid_boundary_link + + i_lower_bdry_cnt + * (new_valid_boundary_link + - multiplier)) + / (i_upper_bdry_cnt + + i_lower_bdry_cnt); + ratio_by_tu_tmp = + original_ratio * tu_size; + ratio_by_tu_tmp /= multiplier; + n_tus_tmp = rounddown(((u64)lwidth + * multiplier * multiplier + * (u64)bpp / 8) + / (u64)resulting_valid_tmp, + multiplier); + n_tus_tmp /= multiplier; + + temp3 = (resulting_valid_tmp + >= (original_ratio * tu_size)) + ? (resulting_valid_tmp + - original_ratio * tu_size) + : (original_ratio * tu_size) + - resulting_valid_tmp; + temp3 = (n_tus_tmp + 1) * temp3; + temp4 = (new_valid_boundary_link + >= (original_ratio * tu_size)) + ? (new_valid_boundary_link + - original_ratio + * tu_size) + : (original_ratio * tu_size) + - new_valid_boundary_link; + temp4 = (i_upper_bdry_cnt + * ln_cnt * temp4); + + temp3 = roundup(temp3, multiplier); + temp4 = roundup(temp4, multiplier); + mdss_dp_get_extra_req_bytes + (resulting_valid_tmp, + new_valid_boundary_link, + temp3, temp4, + &extra_req_bytes_is_neg, + &result, + (original_ratio * tu_size)); + extra_req_bytes_new_tmp + = result / multiplier; + if ((extra_req_bytes_is_neg) + && (extra_req_bytes_new_tmp + > 1)) + extra_req_bytes_new_tmp + = extra_req_bytes_new_tmp - 1; + if (extra_req_bytes_new_tmp == 0) + extra_req_bytes_new_tmp = 1; + extra_pclk_cycles_tmp = + (u64)(extra_req_bytes_new_tmp + * 8 * multiplier) / bpp; + extra_pclk_cycles_tmp /= multiplier; + + if (extra_pclk_cycles_tmp <= 0) + extra_pclk_cycles_tmp = 1; + extra_pclk_cycles_in_lclk_tmp = + roundup(extra_pclk_cycles_tmp + * lclk * multiplier + / pclk, multiplier); + extra_pclk_cycles_in_lclk_tmp + /= multiplier; + filler_size_tmp = + roundup((tu_size * multiplier + - new_valid_boundary_link), + multiplier); + filler_size_tmp /= multiplier; + lower_filler_size_tmp = + filler_size_tmp + 1; + if (extra_req_bytes_is_neg) + temp3 = (extra_req_bytes_new_tmp + > extra_pclk_cycles_in_lclk_tmp + ? extra_pclk_cycles_in_lclk_tmp + : extra_req_bytes_new_tmp); + else + temp3 = (extra_req_bytes_new_tmp + > extra_pclk_cycles_in_lclk_tmp + ? extra_req_bytes_new_tmp : + extra_pclk_cycles_in_lclk_tmp); + + temp4 = lower_filler_size_tmp + + extra_buffer_margin; + if (extra_req_bytes_is_neg) + delay_start_link_tmp + = (temp3 >= temp4) + ? (temp3 - temp4) + : (temp4 - temp3); + else + delay_start_link_tmp + = temp3 + temp4; + + min_hblank_tmp = (int)(roundup + (delay_start_link_tmp + * pclk * multiplier + / lclk, multiplier) + / multiplier) + + hblank_margin; + + if (((even_distribution == 1) + || ((even_distribution_bf == 0) + && (even_distribution_legacy + == 0))) + && !n_err_neg && !nn_err_neg + && n_n_err < err + && (n_n_err < diff_abs + || (dp_brute_force == 1)) + && (new_valid_boundary_link + - 1) > 0 + && (h_blank >= + (u32)min_hblank_tmp)) { + upper_bdry_cnt = + i_upper_bdry_cnt; + lower_bdry_cnt = + i_lower_bdry_cnt; + err = n_n_err; + boundary_moderation_en = 1; + tu_size_desired = tu_size; + valid_boundary_link = + new_valid_boundary_link; + effective_valid_recorded + = effective_valid; + delay_start_link + = delay_start_link_tmp; + filler_size = filler_size_tmp; + min_hblank = min_hblank_tmp; + n_tus = n_tus_tmp; + even_distribution_bf = 1; + + pr_debug("upper_bdry_cnt=%d, lower_boundary_cnt=%d, err=%lld, tu_size_desired=%d, valid_boundary_link=%d, effective_valid=%lld\n", + upper_bdry_cnt, + lower_bdry_cnt, err, + tu_size_desired, + valid_boundary_link, + effective_valid); + } + } + } + } + + if (boundary_moderation_en == 1) { + resulting_valid = (u64)(upper_bdry_cnt + *valid_boundary_link + lower_bdry_cnt + * (valid_boundary_link - 1)) + / (upper_bdry_cnt + lower_bdry_cnt); + ratio_by_tu = original_ratio * tu_size_desired; + valid_lower_boundary_link = + (valid_boundary_link / multiplier) - 1; + + tu_size_minus1 = tu_size_desired - 1; + even_distribution_bf = 1; + valid_boundary_link /= multiplier; + pr_debug("Info: Boundary_moderation enabled\n"); + } + } + + min_hblank = (int) roundup(delay_start_link * pclk + * multiplier / lclk, multiplier) + / multiplier + hblank_margin; + if (h_blank < (u32)min_hblank) { + pr_err(" WARNING: run_idx=%d Programmed h_blank %d is smaller than the min_hblank %d supported.\n", + run_idx, h_blank, min_hblank); + } + + if (fifo_empty) { + tu_size_minus1 = 31; + valid_boundary_link = 32; + delay_start_link = 0; + boundary_moderation_en = 0; + } + + pr_debug("tu_size_minus1=%d valid_boundary_link=%d delay_start_link=%d boundary_moderation_en=%d\n upper_boundary_cnt=%d lower_boundary_cnt=%d valid_lower_boundary_link=%d min_hblank=%d\n", + tu_size_minus1, valid_boundary_link, delay_start_link, + boundary_moderation_en, upper_bdry_cnt, lower_bdry_cnt, + valid_lower_boundary_link, min_hblank); + + tu_table->valid_boundary_link = valid_boundary_link; + tu_table->delay_start_link = delay_start_link; + tu_table->boundary_moderation_en = boundary_moderation_en; + tu_table->valid_lower_boundary_link = valid_lower_boundary_link; + tu_table->upper_boundary_count = upper_bdry_cnt; + tu_table->lower_boundary_count = lower_bdry_cnt; + tu_table->tu_size_minus1 = tu_size_minus1; +} + void mdss_dp_timing_cfg(struct dss_io_data *ctrl_io, struct mdss_panel_info *pinfo) { @@ -297,12 +778,13 @@ void mdss_dp_config_misc_settings(struct dss_io_data *ctrl_io, } void mdss_dp_setup_tr_unit(struct dss_io_data *ctrl_io, u8 link_rate, - u8 ln_cnt, u32 res) + u8 ln_cnt, u32 res, struct mdss_panel_info *pinfo) { u32 dp_tu = 0x0; u32 valid_boundary = 0x0; u32 valid_boundary2 = 0x0; struct dp_vc_tu_mapping_table const *tu_entry = tu_table; + struct dp_vc_tu_mapping_table tu_calc_table; for (; tu_entry != tu_table + ARRAY_SIZE(tu_table); ++tu_entry) { if ((tu_entry->vic == res) && @@ -314,18 +796,18 @@ void mdss_dp_setup_tr_unit(struct dss_io_data *ctrl_io, u8 link_rate, if (tu_entry == tu_table + ARRAY_SIZE(tu_table)) { pr_err("requested res=%d, ln_cnt=%d, lrate=0x%x not supported\n", res, ln_cnt, link_rate); - return; } - dp_tu |= tu_entry->tu_size_minus1; - valid_boundary |= tu_entry->valid_boundary_link; - valid_boundary |= (tu_entry->delay_start_link << 16); + mdss_dp_calc_tu_parameters(link_rate, ln_cnt, &tu_calc_table, pinfo); + dp_tu |= tu_calc_table.tu_size_minus1; + valid_boundary |= tu_calc_table.valid_boundary_link; + valid_boundary |= (tu_calc_table.delay_start_link << 16); - valid_boundary2 |= (tu_entry->valid_lower_boundary_link << 1); - valid_boundary2 |= (tu_entry->upper_boundary_count << 16); - valid_boundary2 |= (tu_entry->lower_boundary_count << 20); + valid_boundary2 |= (tu_calc_table.valid_lower_boundary_link << 1); + valid_boundary2 |= (tu_calc_table.upper_boundary_count << 16); + valid_boundary2 |= (tu_calc_table.lower_boundary_count << 20); - if (tu_entry->boundary_moderation_en) + if (tu_calc_table.boundary_moderation_en) valid_boundary2 |= BIT(0); writel_relaxed(valid_boundary, ctrl_io->base + DP_VALID_BOUNDARY); diff --git a/drivers/video/fbdev/msm/mdss_dp_util.h b/drivers/video/fbdev/msm/mdss_dp_util.h index c046deef48a3..fcb9a77db67c 100644 --- a/drivers/video/fbdev/msm/mdss_dp_util.h +++ b/drivers/video/fbdev/msm/mdss_dp_util.h @@ -284,7 +284,7 @@ void mdss_dp_phy_reset(struct dss_io_data *ctrl_io); void mdss_dp_switch_usb3_phy_to_dp_mode(struct dss_io_data *tcsr_reg_io); void mdss_dp_assert_phy_reset(struct dss_io_data *ctrl_io, bool assert); void mdss_dp_setup_tr_unit(struct dss_io_data *ctrl_io, u8 link_rate, - u8 ln_cnt, u32 res); + u8 ln_cnt, u32 res, struct mdss_panel_info *pinfo); void mdss_dp_config_misc_settings(struct dss_io_data *ctrl_io, struct mdss_panel_info *pinfo); void mdss_dp_phy_aux_setup(struct dss_io_data *phy_io); From 77ac4bf704bc94cda8e1710e582dc11215a7bc6f Mon Sep 17 00:00:00 2001 From: Aravind Venkateswaran Date: Wed, 21 Dec 2016 15:54:18 -0800 Subject: [PATCH 2/2] msm: mdss: dp: fix compilation issues for 32-bit architectures Commit 4216b747aa5d6ac0171ab584237cdaec1044e4e7 ("mdss: display-port: add support to configure transfer unit attributes") incorrectly handles 64-bit integer divisions which may lead to errors while compiling for 32-bit target architectures. Fix these errors. CRs-Fixed: 1086278 Change-Id: I1ae86f2ee72b85c78d34d5fa8a09e5c467bcde86 Signed-off-by: Aravind Venkateswaran --- drivers/video/fbdev/msm/mdss_dp_util.c | 114 ++++++++++++++----------- 1 file changed, 63 insertions(+), 51 deletions(-) diff --git a/drivers/video/fbdev/msm/mdss_dp_util.c b/drivers/video/fbdev/msm/mdss_dp_util.c index 39d82efdcde5..a7f42ba8c261 100644 --- a/drivers/video/fbdev/msm/mdss_dp_util.c +++ b/drivers/video/fbdev/msm/mdss_dp_util.c @@ -239,20 +239,33 @@ static void mdss_dp_get_extra_req_bytes(u64 result_valid, } } +static u64 roundup_u64(u64 x, u64 y) +{ + x += (y - 1); + return (div64_ul(x, y) * y); +} + +static u64 rounddown_u64(u64 x, u64 y) +{ + u64 rem; + + div64_u64_rem(x, y, &rem); + return (x - rem); +} static void mdss_dp_calc_tu_parameters(u8 link_rate, u8 ln_cnt, struct dp_vc_tu_mapping_table *tu_table, struct mdss_panel_info *pinfo) { - u64 const multiplier = 1000000; + u32 const multiplier = 1000000; u64 pclk, lclk; u8 bpp; int run_idx = 0; u32 lwidth, h_blank; u32 fifo_empty = 0; - u32 ratio_scale = 1001, reminder; + u32 ratio_scale = 1001; u64 temp, ratio, original_ratio; - u64 temp2; + u64 temp2, reminder; u64 temp3, temp4, result = 0; u64 err = multiplier; @@ -330,14 +343,14 @@ static void mdss_dp_calc_tu_parameters(u8 link_rate, u8 ln_cnt, pr_debug("pclk=%lld, active_width=%d, h_blank=%d\n", pclk, lwidth, h_blank); pr_debug("lclk = %lld, ln_cnt = %d\n", lclk, ln_cnt); - ratio = div_u64_rem(pclk * bpp * multiplier, + ratio = div64_u64_rem(pclk * bpp * multiplier, 8 * ln_cnt * lclk, &reminder); - ratio = (pclk * bpp * multiplier) / (8 * ln_cnt * lclk); + ratio = div64_u64((pclk * bpp * multiplier), (8 * ln_cnt * lclk)); original_ratio = ratio; - extra_buffer_margin = roundup(extra_pclk_cycle_delay - * lclk * multiplier / pclk, multiplier); - extra_buffer_margin /= multiplier; + extra_buffer_margin = roundup_u64(div64_u64(extra_pclk_cycle_delay + * lclk * multiplier, pclk), multiplier); + extra_buffer_margin = div64_u64(extra_buffer_margin, multiplier); /* To deal with cases where lines are not distributable */ if (((lwidth % ln_cnt) != 0) && ratio < multiplier) { @@ -350,7 +363,7 @@ static void mdss_dp_calc_tu_parameters(u8 link_rate, u8 ln_cnt, for (tu_size = 32; tu_size <= 64; tu_size++) { temp = ratio * tu_size; temp2 = ((temp / multiplier) + 1) * multiplier; - n_err = roundup(temp, multiplier) - temp; + n_err = roundup_u64(temp, multiplier) - temp; if (n_err < err) { err = n_err; @@ -361,7 +374,7 @@ static void mdss_dp_calc_tu_parameters(u8 link_rate, u8 ln_cnt, tu_size_minus1 = tu_size_desired - 1; - valid_boundary_link = roundup(ratio * tu_size_desired, multiplier); + valid_boundary_link = roundup_u64(ratio * tu_size_desired, multiplier); valid_boundary_link /= multiplier; n_tus = rounddown((lwidth * bpp * multiplier) / (8 * valid_boundary_link), multiplier) / multiplier; @@ -369,20 +382,20 @@ static void mdss_dp_calc_tu_parameters(u8 link_rate, u8 ln_cnt, pr_debug("Info: n_symbol_per_tu=%d, number_of_tus=%d\n", valid_boundary_link, n_tus); - extra_bytes = roundup((n_tus + 1) + extra_bytes = roundup_u64((n_tus + 1) * ((valid_boundary_link * multiplier) - (original_ratio * tu_size_desired)), multiplier); extra_bytes /= multiplier; - extra_pclk_cycles = roundup(extra_bytes - * 8 * multiplier / bpp, multiplier); + extra_pclk_cycles = roundup(extra_bytes * 8 * multiplier / bpp, + multiplier); extra_pclk_cycles /= multiplier; - extra_pclk_cycles_in_link_clk = roundup(extra_pclk_cycles - * lclk * multiplier / pclk, multiplier); + extra_pclk_cycles_in_link_clk = roundup_u64(div64_u64(extra_pclk_cycles + * lclk * multiplier, pclk), multiplier); extra_pclk_cycles_in_link_clk /= multiplier; - filler_size = roundup((tu_size_desired - valid_boundary_link) + filler_size = roundup_u64((tu_size_desired - valid_boundary_link) * multiplier, multiplier); filler_size /= multiplier; - ratio_by_tu = (ratio * tu_size_desired) / multiplier; + ratio_by_tu = div64_u64(ratio * tu_size_desired, multiplier); pr_debug("extra_pclk_cycles_in_link_clk=%d, extra_bytes=%d\n", extra_pclk_cycles_in_link_clk, extra_bytes); @@ -416,21 +429,18 @@ static void mdss_dp_calc_tu_parameters(u8 link_rate, u8 ln_cnt, i_lower_bdry_cnt <= 15; i_lower_bdry_cnt++) { new_valid_boundary_link = - roundup(ratio + roundup_u64(ratio * tu_size, multiplier); - average_valid2 = - (u64)(i_upper_bdry_cnt + average_valid2 = (i_upper_bdry_cnt * new_valid_boundary_link + i_lower_bdry_cnt * (new_valid_boundary_link - multiplier)) / (i_upper_bdry_cnt + i_lower_bdry_cnt); - n_tus = - rounddown(((u64)lwidth + n_tus = rounddown_u64(div64_u64(lwidth * multiplier * multiplier - * (u64)bpp / 8) - / (u64)average_valid2, + * (bpp / 8), average_valid2), multiplier); n_tus /= multiplier; n_tus_per_lane @@ -474,8 +484,8 @@ static void mdss_dp_calc_tu_parameters(u8 link_rate, u8 ln_cnt, - multiplier)); n_err_neg = nn_err_neg = false; effective_valid - = total_valid - / n_tus_per_lane; + = div_u64(total_valid, + n_tus_per_lane); n_n_err = (effective_valid >= (ratio * tu_size)) ? (effective_valid @@ -501,21 +511,22 @@ static void mdss_dp_calc_tu_parameters(u8 link_rate, u8 ln_cnt, : (ratio_by_tu - resulting_valid); - resulting_valid_tmp = - (u64)(i_upper_bdry_cnt + resulting_valid_tmp = div64_u64( + (i_upper_bdry_cnt * new_valid_boundary_link + i_lower_bdry_cnt * (new_valid_boundary_link - - multiplier)) - / (i_upper_bdry_cnt - + i_lower_bdry_cnt); + - multiplier)), + (i_upper_bdry_cnt + + i_lower_bdry_cnt)); ratio_by_tu_tmp = original_ratio * tu_size; ratio_by_tu_tmp /= multiplier; - n_tus_tmp = rounddown(((u64)lwidth + n_tus_tmp = rounddown_u64( + div64_u64(lwidth * multiplier * multiplier - * (u64)bpp / 8) - / (u64)resulting_valid_tmp, + * bpp / 8, + resulting_valid_tmp), multiplier); n_tus_tmp /= multiplier; @@ -536,8 +547,8 @@ static void mdss_dp_calc_tu_parameters(u8 link_rate, u8 ln_cnt, temp4 = (i_upper_bdry_cnt * ln_cnt * temp4); - temp3 = roundup(temp3, multiplier); - temp4 = roundup(temp4, multiplier); + temp3 = roundup_u64(temp3, multiplier); + temp4 = roundup_u64(temp4, multiplier); mdss_dp_get_extra_req_bytes (resulting_valid_tmp, new_valid_boundary_link, @@ -546,7 +557,7 @@ static void mdss_dp_calc_tu_parameters(u8 link_rate, u8 ln_cnt, &result, (original_ratio * tu_size)); extra_req_bytes_new_tmp - = result / multiplier; + = div64_ul(result, multiplier); if ((extra_req_bytes_is_neg) && (extra_req_bytes_new_tmp > 1)) @@ -562,15 +573,16 @@ static void mdss_dp_calc_tu_parameters(u8 link_rate, u8 ln_cnt, if (extra_pclk_cycles_tmp <= 0) extra_pclk_cycles_tmp = 1; extra_pclk_cycles_in_lclk_tmp = - roundup(extra_pclk_cycles_tmp - * lclk * multiplier - / pclk, multiplier); + roundup_u64(div64_u64( + extra_pclk_cycles_tmp + * lclk * multiplier, + pclk), multiplier); extra_pclk_cycles_in_lclk_tmp /= multiplier; - filler_size_tmp = - roundup((tu_size * multiplier - - new_valid_boundary_link), - multiplier); + filler_size_tmp = roundup_u64( + (tu_size * multiplier * + new_valid_boundary_link), + multiplier); filler_size_tmp /= multiplier; lower_filler_size_tmp = filler_size_tmp + 1; @@ -596,11 +608,11 @@ static void mdss_dp_calc_tu_parameters(u8 link_rate, u8 ln_cnt, delay_start_link_tmp = temp3 + temp4; - min_hblank_tmp = (int)(roundup - (delay_start_link_tmp - * pclk * multiplier - / lclk, multiplier) - / multiplier) + min_hblank_tmp = (int)div64_u64( + roundup_u64( + div64_u64(delay_start_link_tmp + * pclk * multiplier, lclk), + multiplier), multiplier) + hblank_margin; if (((even_distribution == 1) @@ -660,8 +672,8 @@ static void mdss_dp_calc_tu_parameters(u8 link_rate, u8 ln_cnt, } } - min_hblank = (int) roundup(delay_start_link * pclk - * multiplier / lclk, multiplier) + min_hblank = ((int) roundup_u64(div64_u64(delay_start_link * pclk + * multiplier, lclk), multiplier)) / multiplier + hblank_margin; if (h_blank < (u32)min_hblank) { pr_err(" WARNING: run_idx=%d Programmed h_blank %d is smaller than the min_hblank %d supported.\n",