DF-3828 / fix.diff
--- a/sys/dev/drm/amd/amdgpu/dce_v11_0.c +++ b/sys/dev/drm/amd/amdgpu/dce_v11_0.c @@ -905,18 +905,27 @@ /* First calculate the latency in ns */ u32 mc_latency = 2000; /* 2000 ns. */ u32 available_bandwidth = dce_v11_0_available_bandwidth(wm); - u32 worst_chunk_return_time = (512 * 8 * 1000) / available_bandwidth; - u32 cursor_line_pair_return_time = (128 * 4 * 1000) / available_bandwidth; - u32 dc_latency = 40000000 / wm->disp_clk; /* dc pipe latency */ - u32 other_heads_data_return_time = ((wm->num_heads + 1) * worst_chunk_return_time) + - (wm->num_heads * cursor_line_pair_return_time); - u32 latency = mc_latency + other_heads_data_return_time + dc_latency; + u32 worst_chunk_return_time, cursor_line_pair_return_time, dc_latency; + u32 other_heads_data_return_time, latency; u32 max_src_lines_per_dst_line, lb_fill_bw, line_fill_time; u32 tmp, dmif_size = 12288; fixed20_12 a, b, c; if (wm->num_heads == 0) return 0; + /* Zero clocks (e.g. VBIOS reporting ulDefaultEngineClock == 0 with + * DPM disabled) collapse the bandwidth terms to 0; dividing would + * take a #DE and panic the kernel. Bail out with the conservative + * watermark used for the no-heads case. */ + if (!available_bandwidth || !wm->disp_clk) + return 0; + + worst_chunk_return_time = (512 * 8 * 1000) / available_bandwidth; + cursor_line_pair_return_time = (128 * 4 * 1000) / available_bandwidth; + dc_latency = 40000000 / wm->disp_clk; /* dc pipe latency */ + other_heads_data_return_time = ((wm->num_heads + 1) * worst_chunk_return_time) + + (wm->num_heads * cursor_line_pair_return_time); + latency = mc_latency + other_heads_data_return_time + dc_latency; a.full = dfixed_const(2); b.full = dfixed_const(1); @@ -1048,6 +1057,8 @@ u32 tmp, wm_mask, lb_vblank_lead_lines = 0; if (amdgpu_crtc->base.enabled && num_heads && mode) { + if (!mode->clock) + return; active_time = (u32) div_u64((u64)mode->crtc_hdisplay * 1000000, (u32)mode->clock); line_time = (u32) div_u64((u64)mode->crtc_htotal * 1000000, --- a/sys/dev/drm/amd/amdgpu/amdgpu_atombios.c +++ b/sys/dev/drm/amd/amdgpu/amdgpu_atombios.c @@ -678,6 +678,13 @@ le32_to_cpu(firmware_info->info.ulDefaultEngineClock); adev->clock.default_mclk = le32_to_cpu(firmware_info->info.ulDefaultMemoryClock); + /* Mirror the guards applied to every other clock field in + * this parser: a zero default engine/memory clock collapses + * the DCE watermark bandwidth terms to a divide-by-zero. */ + if (adev->clock.default_sclk == 0) + adev->clock.default_sclk = 10000; /* 100 MHz sanity min */ + if (adev->clock.default_mclk == 0) + adev->clock.default_mclk = 10000; /* 100 MHz sanity min */ mpll->min_post_div = 1; mpll->max_post_div = 1; |