--- a/sys/dev/drm/radeon/rs690.c +++ b/sys/dev/drm/radeon/rs690.c @@ -365,10 +365,24 @@ static void rs690_crtc_bandwidth_compute(struct radeon_device *rdev, /* Maximun bandwidth is the minimun bandwidth of all component */ max_bandwidth = core_bandwidth; if (rdev->mc.igp_sideport_enabled) { if (max_bandwidth.full > rdev->pm.sideport_bandwidth.full && rdev->pm.sideport_bandwidth.full) max_bandwidth = rdev->pm.sideport_bandwidth; + /* + * igp_sideport_mclk comes straight from the VBIOS + * IntegratedSystemInfo table (rs690_pm_info): a zero + * ulBootUpSidePortClock/ulBootUpMemoryClock makes b.full + * zero and dfixed_div() panics with an integer divide + * fault. Treat a zero sideport clock like "no sideport". + */ + if (rdev->pm.igp_sideport_mclk.full == 0) { + read_delay_latency.full = dfixed_const(5000); + goto have_latency; + } read_delay_latency.full = dfixed_const(370 * 800); a.full = dfixed_const(1000); b.full = dfixed_div(rdev->pm.igp_sideport_mclk, a); read_delay_latency.full = dfixed_div(read_delay_latency, b); read_delay_latency.full = dfixed_mul(read_delay_latency, a); @@ -383,9 +397,18 @@ static void rs690_crtc_bandwidth_compute(struct radeon_device *rdev, read_delay_latency.full = dfixed_const(5000); } +have_latency: /* sclk = system clocks(ns) = 1000 / max_bandwidth / 16 */ a.full = dfixed_const(16); sclk.full = dfixed_mul(max_bandwidth, a); a.full = dfixed_const(1000); + /* + * max_bandwidth is zero when every bandwidth component parsed from + * the VBIOS is zero (e.g. ulDefaultEngineClock == 0 gives + * rdev->pm.sclk == 0 and core_bandwidth == 0; the guards above + * never replace a zero maximum). Bail instead of dividing by 0. + */ + if (sclk.full == 0) { + wm->lb_request_fifo_depth = 4; + return; + } sclk.full = dfixed_div(a, sclk); /* Determine chunk time * ChunkTime = the time it takes the DCP to send one chunk of data