Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

drm/amd/display: Fix 64 bit divisions on 32 bit platforms by using div64 API

[why]
Synchronization displays with different timings feature uses division
operator for 64 bit division, which is not supported by 32 bit platforms

[how]
Use div64 API for 64 bit division

Signed-off-by: Vladimir Stempen <vladimir.stempen@amd.com>
Tested-by: Bindu Ramamurthy<bindu.r@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

authored by

Vladimir Stempen and committed by
Alex Deucher
783bf403 640a28b5

+21 -20
+7 -7
drivers/gpu/drm/amd/display/dc/core/dc_resource.c
··· 424 424 uint32_t base60_refresh_rates[] = {10, 20, 5}; 425 425 uint8_t i; 426 426 uint8_t rr_count = sizeof(base60_refresh_rates)/sizeof(base60_refresh_rates[0]); 427 - int64_t frame_time_diff; 427 + uint64_t frame_time_diff; 428 428 429 429 if (stream1->ctx->dc->config.vblank_alignment_dto_params && 430 430 stream1->ctx->dc->config.vblank_alignment_max_frame_time_diff > 0 && ··· 441 441 if (stream2->timing.pix_clk_100hz*100/stream2->timing.h_total/ 442 442 stream2->timing.v_total > 60) 443 443 return false; 444 - frame_time_diff = (int64_t)10000 * 444 + frame_time_diff = (uint64_t)10000 * 445 445 stream1->timing.h_total * 446 446 stream1->timing.v_total * 447 - stream2->timing.pix_clk_100hz / 448 - stream1->timing.pix_clk_100hz / 449 - stream2->timing.h_total / 450 - stream2->timing.v_total; 447 + stream2->timing.pix_clk_100hz; 448 + frame_time_diff = div_u64(frame_time_diff, stream1->timing.pix_clk_100hz); 449 + frame_time_diff = div_u64(frame_time_diff, stream2->timing.h_total); 450 + frame_time_diff = div_u64(frame_time_diff, stream2->timing.v_total); 451 451 for (i = 0; i < rr_count; i++) { 452 - int64_t diff = (frame_time_diff * base60_refresh_rates[i]) / 10 - 10000; 452 + int64_t diff = (int64_t)div_u64(frame_time_diff * base60_refresh_rates[i], 10) - 10000; 453 453 454 454 if (diff < 0) 455 455 diff = -diff;
+3 -3
drivers/gpu/drm/amd/display/dc/dce/dce_clock_source.c
··· 1013 1013 * not be programmed equal to DPREFCLK 1014 1014 */ 1015 1015 modulo_hz = REG_READ(MODULO[inst]); 1016 - *pixel_clk_khz = ((uint64_t)clock_hz* 1017 - clock_source->ctx->dc->clk_mgr->dprefclk_khz*10)/ 1018 - modulo_hz; 1016 + *pixel_clk_khz = div_u64((uint64_t)clock_hz* 1017 + clock_source->ctx->dc->clk_mgr->dprefclk_khz*10, 1018 + modulo_hz); 1019 1019 } else { 1020 1020 /* NOTE: There is agreement with VBIOS here that MODULO is 1021 1021 * programmed equal to DPREFCLK, in which case PHASE will be
+4 -4
drivers/gpu/drm/amd/display/dc/dcn10/dcn10_hw_sequencer.c
··· 1900 1900 } 1901 1901 while (num % prime_numbers[i] == 0 && 1902 1902 denom % prime_numbers[i] == 0) { 1903 - num /= prime_numbers[i]; 1904 - denom /= prime_numbers[i]; 1903 + num = div_u64(num, prime_numbers[i]); 1904 + denom = div_u64(denom, prime_numbers[i]); 1905 1905 } 1906 1906 } 1907 1907 *numerator = num; ··· 1987 1987 1988 1988 phase[i] = (uint64_t)embedded_pix_clk_100hz* 1989 1989 hw_crtc_timing[i].h_total* 1990 - hw_crtc_timing[i].v_total/ 1991 - get_clock_divider(grouped_pipes[i], true); 1990 + hw_crtc_timing[i].v_total; 1991 + phase[i] = div_u64(phase[i], get_clock_divider(grouped_pipes[i], true)); 1992 1992 modulo[i] = (uint64_t)dp_ref_clk_100hz* 1993 1993 embedded_h_total* 1994 1994 embedded_v_total;
+7 -6
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_optc.c
··· 323 323 uint32_t master_v_active = 0; 324 324 uint32_t master_h_total = 0; 325 325 uint32_t slave_h_total = 0; 326 - uint64_t L, XY, p = 10000; 327 - uint32_t X, Y; 326 + uint64_t L, XY; 327 + uint32_t X, Y, p = 10000; 328 328 uint32_t master_update_lock; 329 329 330 330 /* disable slave OTG */ ··· 355 355 REG_GET(OTG_H_TOTAL, OTG_H_TOTAL, &master_h_total); 356 356 357 357 /* calculate when to enable slave OTG */ 358 - L = p * slave_h_total * master_pixel_clock_100Hz / 359 - master_h_total / slave_pixel_clock_100Hz; 360 - XY = L / p; 358 + L = (uint64_t)p * slave_h_total * master_pixel_clock_100Hz; 359 + L = div_u64(L, master_h_total); 360 + L = div_u64(L, slave_pixel_clock_100Hz); 361 + XY = div_u64(L, p); 361 362 Y = master_v_active - XY - 1; 362 - X = ((XY + 1) * p - L) * master_h_total / master_clock_divider / p; 363 + X = div_u64(((XY + 1) * p - L) * master_h_total, p * master_clock_divider); 363 364 364 365 /* 365 366 * set master OTG to unlock when V/H