summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/cik.c
diff options
context:
space:
mode:
authorMario Kleiner <mario.kleiner.de@gmail.com>2017-04-24 01:33:08 +0200
committerAlex Deucher <alexander.deucher@amd.com>2017-04-28 17:33:03 -0400
commitae45bbc2ba8f92b5a773fece6f5792f497c89282 (patch)
tree18464c5502b6fcca42218b81296436221c04a8a1 /drivers/gpu/drm/radeon/cik.c
parenteffaf848b957fbf72a3b6a1ad87f5e031eda0b75 (diff)
downloadlinux-stable-ae45bbc2ba8f92b5a773fece6f5792f497c89282.tar.gz
linux-stable-ae45bbc2ba8f92b5a773fece6f5792f497c89282.tar.bz2
linux-stable-ae45bbc2ba8f92b5a773fece6f5792f497c89282.zip
drm/radeon: Avoid overflows/divide-by-zero in latency_watermark calculations.
At dot clocks > approx. 250 Mhz, some of these calcs will overflow and cause miscalculation of latency watermarks, and for some overflows also divide-by-zero driver crash. Make calcs more overflow resistant. This is a direct port of the corresponding patch from amdgpu-kms, copy-paste for cik from dce-8 and si from dce-6, with a slightly simpler variant for evergreen dce-4/5. Only tested on DCE-4 evergreen with a Radeon HD-5770. Signed-off-by: Mario Kleiner <mario.kleiner.de@gmail.com> Cc: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/cik.c')
-rw-r--r--drivers/gpu/drm/radeon/cik.c19
1 files changed, 3 insertions, 16 deletions
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 53710dd7d5dd..4f034cbc4a6a 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -9150,23 +9150,10 @@ static u32 dce8_latency_watermark(struct dce8_wm_params *wm)
a.full = dfixed_const(available_bandwidth);
b.full = dfixed_const(wm->num_heads);
a.full = dfixed_div(a, b);
+ tmp = div_u64((u64) dmif_size * (u64) wm->disp_clk, mc_latency + 512);
+ tmp = min(dfixed_trunc(a), tmp);
- b.full = dfixed_const(mc_latency + 512);
- c.full = dfixed_const(wm->disp_clk);
- b.full = dfixed_div(b, c);
-
- c.full = dfixed_const(dmif_size);
- b.full = dfixed_div(c, b);
-
- tmp = min(dfixed_trunc(a), dfixed_trunc(b));
-
- b.full = dfixed_const(1000);
- c.full = dfixed_const(wm->disp_clk);
- b.full = dfixed_div(c, b);
- c.full = dfixed_const(wm->bytes_per_pixel);
- b.full = dfixed_mul(b, c);
-
- lb_fill_bw = min(tmp, dfixed_trunc(b));
+ lb_fill_bw = min(tmp, wm->disp_clk * wm->bytes_per_pixel / 1000);
a.full = dfixed_const(max_src_lines_per_dst_line * wm->src_width * wm->bytes_per_pixel);
b.full = dfixed_const(1000);