Rev 6937 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 6937 | Rev 7144 | ||
---|---|---|---|
Line 399... | Line 399... | ||
399 | I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) & |
399 | I915_WRITE(gen6_pm_ier(dev_priv), I915_READ(gen6_pm_ier(dev_priv)) & |
400 | ~dev_priv->pm_rps_events); |
400 | ~dev_priv->pm_rps_events); |
Line 401... | Line 401... | ||
401 | 401 | ||
Line -... | Line 402... | ||
- | 402 | spin_unlock_irq(&dev_priv->irq_lock); |
|
402 | spin_unlock_irq(&dev_priv->irq_lock); |
403 | |
Line 403... | Line 404... | ||
403 | 404 | synchronize_irq(dev->irq); |
|
404 | } |
405 | } |
405 | 406 | ||
Line 1633... | Line 1634... | ||
1633 | struct drm_i915_private *dev_priv = dev->dev_private; |
1634 | struct drm_i915_private *dev_priv = dev->dev_private; |
1634 | u32 pipe_stats[I915_MAX_PIPES] = { }; |
1635 | u32 pipe_stats[I915_MAX_PIPES] = { }; |
1635 | int pipe; |
1636 | int pipe; |
Line 1636... | Line 1637... | ||
1636 | 1637 | ||
- | 1638 | spin_lock(&dev_priv->irq_lock); |
|
- | 1639 | ||
- | 1640 | if (!dev_priv->display_irqs_enabled) { |
|
- | 1641 | spin_unlock(&dev_priv->irq_lock); |
|
- | 1642 | return; |
|
- | 1643 | } |
|
1637 | spin_lock(&dev_priv->irq_lock); |
1644 | |
1638 | for_each_pipe(dev_priv, pipe) { |
1645 | for_each_pipe(dev_priv, pipe) { |
1639 | i915_reg_t reg; |
1646 | i915_reg_t reg; |
Line 1640... | Line 1647... | ||
1640 | u32 mask, iir_bit = 0; |
1647 | u32 mask, iir_bit = 0; |
Line 2170... | Line 2177... | ||
2170 | return IRQ_NONE; |
2177 | return IRQ_NONE; |
Line 2171... | Line 2178... | ||
2171 | 2178 | ||
2172 | /* IRQs are synced during runtime_suspend, we don't require a wakeref */ |
2179 | /* IRQs are synced during runtime_suspend, we don't require a wakeref */ |
Line 2173... | Line -... | ||
2173 | disable_rpm_wakeref_asserts(dev_priv); |
- | |
2174 | - | ||
2175 | /* We get interrupts on unclaimed registers, so check for this before we |
- | |
2176 | * do any I915_{READ,WRITE}. */ |
- | |
2177 | intel_uncore_check_errors(dev); |
2180 | disable_rpm_wakeref_asserts(dev_priv); |
2178 | 2181 | ||
2179 | /* disable master interrupt before clearing iir */ |
2182 | /* disable master interrupt before clearing iir */ |
2180 | de_ier = I915_READ(DEIER); |
2183 | de_ier = I915_READ(DEIER); |
Line 2250... | Line 2253... | ||
2250 | bxt_port_hotplug_long_detect); |
2253 | bxt_port_hotplug_long_detect); |
Line 2251... | Line 2254... | ||
2251 | 2254 | ||
2252 | intel_hpd_irq_handler(dev, pin_mask, long_mask); |
2255 | intel_hpd_irq_handler(dev, pin_mask, long_mask); |
Line -... | Line 2256... | ||
- | 2256 | } |
|
2253 | } |
2257 | |
2254 | 2258 | static irqreturn_t |
|
2255 | static irqreturn_t gen8_irq_handler(int irq, void *arg) |
2259 | gen8_de_irq_handler(struct drm_i915_private *dev_priv, u32 master_ctl) |
2256 | { |
- | |
2257 | struct drm_device *dev = arg; |
- | |
2258 | struct drm_i915_private *dev_priv = dev->dev_private; |
2260 | { |
2259 | u32 master_ctl; |
2261 | struct drm_device *dev = dev_priv->dev; |
2260 | irqreturn_t ret = IRQ_NONE; |
2262 | irqreturn_t ret = IRQ_NONE; |
2261 | uint32_t tmp = 0; |
- | |
2262 | enum pipe pipe; |
- | |
2263 | u32 aux_mask = GEN8_AUX_CHANNEL_A; |
- | |
2264 | - | ||
2265 | if (!intel_irqs_enabled(dev_priv)) |
- | |
2266 | return IRQ_NONE; |
- | |
2267 | - | ||
2268 | /* IRQs are synced during runtime_suspend, we don't require a wakeref */ |
- | |
2269 | disable_rpm_wakeref_asserts(dev_priv); |
- | |
2270 | - | ||
2271 | if (INTEL_INFO(dev_priv)->gen >= 9) |
- | |
2272 | aux_mask |= GEN9_AUX_CHANNEL_B | GEN9_AUX_CHANNEL_C | |
- | |
2273 | GEN9_AUX_CHANNEL_D; |
- | |
2274 | - | ||
2275 | master_ctl = I915_READ_FW(GEN8_MASTER_IRQ); |
- | |
2276 | master_ctl &= ~GEN8_MASTER_IRQ_CONTROL; |
- | |
2277 | if (!master_ctl) |
- | |
2278 | goto out; |
- | |
2279 | - | ||
2280 | I915_WRITE_FW(GEN8_MASTER_IRQ, 0); |
- | |
2281 | - | ||
2282 | /* Find, clear, then process each source of interrupt */ |
- | |
Line 2283... | Line 2263... | ||
2283 | 2263 | u32 iir; |
|
2284 | ret = gen8_gt_irq_handler(dev_priv, master_ctl); |
2264 | enum pipe pipe; |
2285 | 2265 | ||
2286 | if (master_ctl & GEN8_DE_MISC_IRQ) { |
2266 | if (master_ctl & GEN8_DE_MISC_IRQ) { |
2287 | tmp = I915_READ(GEN8_DE_MISC_IIR); |
2267 | iir = I915_READ(GEN8_DE_MISC_IIR); |
2288 | if (tmp) { |
2268 | if (iir) { |
2289 | I915_WRITE(GEN8_DE_MISC_IIR, tmp); |
2269 | I915_WRITE(GEN8_DE_MISC_IIR, iir); |
2290 | ret = IRQ_HANDLED; |
2270 | ret = IRQ_HANDLED; |
2291 | if (tmp & GEN8_DE_MISC_GSE) |
2271 | if (iir & GEN8_DE_MISC_GSE) |
2292 | intel_opregion_asle_intr(dev); |
2272 | intel_opregion_asle_intr(dev); |
2293 | else |
2273 | else |
2294 | DRM_ERROR("Unexpected DE Misc interrupt\n"); |
2274 | DRM_ERROR("Unexpected DE Misc interrupt\n"); |
2295 | } |
2275 | } |
Line 2296... | Line 2276... | ||
2296 | else |
2276 | else |
2297 | DRM_ERROR("The master control interrupt lied (DE MISC)!\n"); |
2277 | DRM_ERROR("The master control interrupt lied (DE MISC)!\n"); |
2298 | } |
2278 | } |
- | 2279 | ||
2299 | 2280 | if (master_ctl & GEN8_DE_PORT_IRQ) { |
|
2300 | if (master_ctl & GEN8_DE_PORT_IRQ) { |
- | |
Line 2301... | Line -... | ||
2301 | tmp = I915_READ(GEN8_DE_PORT_IIR); |
- | |
2302 | if (tmp) { |
- | |
2303 | bool found = false; |
- | |
2304 | u32 hotplug_trigger = 0; |
- | |
2305 | - | ||
2306 | if (IS_BROXTON(dev_priv)) |
2281 | iir = I915_READ(GEN8_DE_PORT_IIR); |
2307 | hotplug_trigger = tmp & BXT_DE_PORT_HOTPLUG_MASK; |
2282 | if (iir) { |
Line -... | Line 2283... | ||
- | 2283 | u32 tmp_mask; |
|
- | 2284 | bool found = false; |
|
- | 2285 | ||
- | 2286 | I915_WRITE(GEN8_DE_PORT_IIR, iir); |
|
- | 2287 | ret = IRQ_HANDLED; |
|
- | 2288 | ||
2308 | else if (IS_BROADWELL(dev_priv)) |
2289 | tmp_mask = GEN8_AUX_CHANNEL_A; |
2309 | hotplug_trigger = tmp & GEN8_PORT_DP_A_HOTPLUG; |
2290 | if (INTEL_INFO(dev_priv)->gen >= 9) |
2310 | 2291 | tmp_mask |= GEN9_AUX_CHANNEL_B | |
|
2311 | I915_WRITE(GEN8_DE_PORT_IIR, tmp); |
2292 | GEN9_AUX_CHANNEL_C | |
Line 2312... | Line 2293... | ||
2312 | ret = IRQ_HANDLED; |
2293 | GEN9_AUX_CHANNEL_D; |
- | 2294 | ||
2313 | 2295 | if (iir & tmp_mask) { |
|
2314 | if (tmp & aux_mask) { |
2296 | dp_aux_irq_handler(dev); |
- | 2297 | found = true; |
|
2315 | dp_aux_irq_handler(dev); |
2298 | } |
- | 2299 | ||
- | 2300 | if (IS_BROXTON(dev_priv)) { |
|
- | 2301 | tmp_mask = iir & BXT_DE_PORT_HOTPLUG_MASK; |
|
2316 | found = true; |
2302 | if (tmp_mask) { |
2317 | } |
2303 | bxt_hpd_irq_handler(dev, tmp_mask, hpd_bxt); |
2318 | 2304 | found = true; |
|
- | 2305 | } |
|
Line 2319... | Line 2306... | ||
2319 | if (hotplug_trigger) { |
2306 | } else if (IS_BROADWELL(dev_priv)) { |
2320 | if (IS_BROXTON(dev)) |
2307 | tmp_mask = iir & GEN8_PORT_DP_A_HOTPLUG; |
2321 | bxt_hpd_irq_handler(dev, hotplug_trigger, hpd_bxt); |
2308 | if (tmp_mask) { |
2322 | else |
2309 | ilk_hpd_irq_handler(dev, tmp_mask, hpd_bdw); |
Line 2323... | Line 2310... | ||
2323 | ilk_hpd_irq_handler(dev, hotplug_trigger, hpd_bdw); |
2310 | found = true; |
Line 2335... | Line 2322... | ||
2335 | else |
2322 | else |
2336 | DRM_ERROR("The master control interrupt lied (DE PORT)!\n"); |
2323 | DRM_ERROR("The master control interrupt lied (DE PORT)!\n"); |
2337 | } |
2324 | } |
Line 2338... | Line 2325... | ||
2338 | 2325 | ||
2339 | for_each_pipe(dev_priv, pipe) { |
2326 | for_each_pipe(dev_priv, pipe) { |
Line 2340... | Line 2327... | ||
2340 | uint32_t pipe_iir, flip_done = 0, fault_errors = 0; |
2327 | u32 flip_done, fault_errors; |
2341 | 2328 | ||
Line 2342... | Line 2329... | ||
2342 | if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe))) |
2329 | if (!(master_ctl & GEN8_DE_PIPE_IRQ(pipe))) |
2343 | continue; |
2330 | continue; |
- | 2331 | ||
- | 2332 | iir = I915_READ(GEN8_DE_PIPE_IIR(pipe)); |
|
- | 2333 | if (!iir) { |
|
- | 2334 | DRM_ERROR("The master control interrupt lied (DE PIPE)!\n"); |
|
2344 | 2335 | continue; |
|
2345 | pipe_iir = I915_READ(GEN8_DE_PIPE_IIR(pipe)); |
2336 | } |
Line 2346... | Line 2337... | ||
2346 | if (pipe_iir) { |
2337 | |
2347 | ret = IRQ_HANDLED; |
2338 | ret = IRQ_HANDLED; |
2348 | I915_WRITE(GEN8_DE_PIPE_IIR(pipe), pipe_iir); |
2339 | I915_WRITE(GEN8_DE_PIPE_IIR(pipe), iir); |
Line -... | Line 2340... | ||
- | 2340 | ||
2349 | 2341 | if (iir & GEN8_PIPE_VBLANK && |
|
2350 | if (pipe_iir & GEN8_PIPE_VBLANK && |
2342 | intel_pipe_handle_vblank(dev, pipe)) |
2351 | intel_pipe_handle_vblank(dev, pipe)) |
2343 | intel_check_page_flip(dev, pipe); |
2352 | intel_check_page_flip(dev, pipe); |
2344 | |
Line 2353... | Line 2345... | ||
2353 | 2345 | flip_done = iir; |
|
2354 | if (INTEL_INFO(dev_priv)->gen >= 9) |
2346 | if (INTEL_INFO(dev_priv)->gen >= 9) |
2355 | flip_done = pipe_iir & GEN9_PIPE_PLANE1_FLIP_DONE; |
2347 | flip_done &= GEN9_PIPE_PLANE1_FLIP_DONE; |
2356 | else |
2348 | else |
Line 2357... | Line 2349... | ||
2357 | flip_done = pipe_iir & GEN8_PIPE_PRIMARY_FLIP_DONE; |
2349 | flip_done &= GEN8_PIPE_PRIMARY_FLIP_DONE; |
2358 | 2350 | ||
Line 2359... | Line 2351... | ||
2359 | if (flip_done) { |
2351 | if (flip_done) { |
2360 | intel_prepare_page_flip(dev, pipe); |
2352 | intel_prepare_page_flip(dev, pipe); |
2361 | intel_finish_page_flip_plane(dev, pipe); |
- | |
2362 | } |
- | |
Line -... | Line 2353... | ||
- | 2353 | intel_finish_page_flip_plane(dev, pipe); |
|
2363 | 2354 | } |
|
2364 | if (pipe_iir & GEN8_PIPE_CDCLK_CRC_DONE) |
2355 | |
2365 | hsw_pipe_crc_irq_handler(dev, pipe); |
2356 | if (iir & GEN8_PIPE_CDCLK_CRC_DONE) |
2366 | 2357 | hsw_pipe_crc_irq_handler(dev, pipe); |
|
Line 2367... | Line 2358... | ||
2367 | if (pipe_iir & GEN8_PIPE_FIFO_UNDERRUN) |
2358 | |
2368 | intel_cpu_fifo_underrun_irq_handler(dev_priv, |
2359 | if (iir & GEN8_PIPE_FIFO_UNDERRUN) |
2369 | pipe); |
2360 | intel_cpu_fifo_underrun_irq_handler(dev_priv, pipe); |
2370 | - | ||
2371 | 2361 | ||
2372 | if (INTEL_INFO(dev_priv)->gen >= 9) |
- | |
2373 | fault_errors = pipe_iir & GEN9_DE_PIPE_IRQ_FAULT_ERRORS; |
2362 | fault_errors = iir; |
Line 2374... | Line 2363... | ||
2374 | else |
2363 | if (INTEL_INFO(dev_priv)->gen >= 9) |
2375 | fault_errors = pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS; |
2364 | fault_errors &= GEN9_DE_PIPE_IRQ_FAULT_ERRORS; |
2376 | 2365 | else |
|
2377 | if (fault_errors) |
2366 | fault_errors &= GEN8_DE_PIPE_IRQ_FAULT_ERRORS; |
2378 | DRM_ERROR("Fault errors on pipe %c\n: 0x%08x", |
2367 | |
2379 | pipe_name(pipe), |
2368 | if (fault_errors) |
2380 | pipe_iir & GEN8_DE_PIPE_IRQ_FAULT_ERRORS); |
2369 | DRM_ERROR("Fault errors on pipe %c\n: 0x%08x", |
2381 | } else |
2370 | pipe_name(pipe), |
2382 | DRM_ERROR("The master control interrupt lied (DE PIPE)!\n"); |
2371 | fault_errors); |
2383 | } |
2372 | } |
2384 | 2373 | ||
Line 2385... | Line 2374... | ||
2385 | if (HAS_PCH_SPLIT(dev) && !HAS_PCH_NOP(dev) && |
2374 | if (HAS_PCH_SPLIT(dev) && !HAS_PCH_NOP(dev) && |
2386 | master_ctl & GEN8_DE_PCH_IRQ) { |
2375 | master_ctl & GEN8_DE_PCH_IRQ) { |
2387 | /* |
2376 | /* |
2388 | * FIXME(BDW): Assume for now that the new interrupt handling |
2377 | * FIXME(BDW): Assume for now that the new interrupt handling |
2389 | * scheme also closed the SDE interrupt handling race we've seen |
2378 | * scheme also closed the SDE interrupt handling race we've seen |
2390 | * on older pch-split platforms. But this needs testing. |
2379 | * on older pch-split platforms. But this needs testing. |
2391 | */ |
2380 | */ |
2392 | u32 pch_iir = I915_READ(SDEIIR); |
2381 | iir = I915_READ(SDEIIR); |
2393 | if (pch_iir) { |
2382 | if (iir) { |
2394 | I915_WRITE(SDEIIR, pch_iir); |
2383 | I915_WRITE(SDEIIR, iir); |
2395 | ret = IRQ_HANDLED; |
2384 | ret = IRQ_HANDLED; |
2396 | 2385 | ||
Line -... | Line 2386... | ||
- | 2386 | if (HAS_PCH_SPT(dev_priv)) |
|
- | 2387 | spt_irq_handler(dev, iir); |
|
- | 2388 | else |
|
- | 2389 | cpt_irq_handler(dev, iir); |
|
- | 2390 | } else { |
|
- | 2391 | /* |
|
- | 2392 | * Like on previous PCH there seems to be something |
|
- | 2393 | * fishy going on with forwarding PCH interrupts. |
|
- | 2394 | */ |
|
- | 2395 | DRM_DEBUG_DRIVER("The master control interrupt lied (SDE)!\n"); |
|
- | 2396 | } |
|
- | 2397 | } |
|
- | 2398 | ||
- | 2399 | return ret; |
|
- | 2400 | } |
|
- | 2401 | ||
- | 2402 | static irqreturn_t gen8_irq_handler(int irq, void *arg) |
|
- | 2403 | { |
|
- | 2404 | struct drm_device *dev = arg; |
|
- | 2405 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 2406 | u32 master_ctl; |
|
- | 2407 | irqreturn_t ret; |
|
- | 2408 | ||
- | 2409 | if (!intel_irqs_enabled(dev_priv)) |
|
- | 2410 | return IRQ_NONE; |
|
- | 2411 | ||
- | 2412 | master_ctl = I915_READ_FW(GEN8_MASTER_IRQ); |
|
2397 | if (HAS_PCH_SPT(dev_priv)) |
2413 | master_ctl &= ~GEN8_MASTER_IRQ_CONTROL; |
2398 | spt_irq_handler(dev, pch_iir); |
2414 | if (!master_ctl) |
Line 2399... | Line -... | ||
2399 | else |
- | |
2400 | cpt_irq_handler(dev, pch_iir); |
2415 | return IRQ_NONE; |
Line 2401... | Line 2416... | ||
2401 | } else { |
2416 | |
2402 | /* |
2417 | I915_WRITE_FW(GEN8_MASTER_IRQ, 0); |
Line 2479... | Line 2494... | ||
2479 | * isn't the case at least when we get here by doing a |
2494 | * isn't the case at least when we get here by doing a |
2480 | * simulated reset via debugs, so get an RPM reference. |
2495 | * simulated reset via debugs, so get an RPM reference. |
2481 | */ |
2496 | */ |
2482 | intel_runtime_pm_get(dev_priv); |
2497 | intel_runtime_pm_get(dev_priv); |
Line -... | Line 2498... | ||
- | 2498 | ||
- | 2499 | intel_prepare_reset(dev); |
|
2483 | 2500 | ||
2484 | /* |
2501 | /* |
2485 | * All state reset _must_ be completed before we update the |
2502 | * All state reset _must_ be completed before we update the |
2486 | * reset counter, for otherwise waiters might miss the reset |
2503 | * reset counter, for otherwise waiters might miss the reset |
2487 | * pending state and not properly drop locks, resulting in |
2504 | * pending state and not properly drop locks, resulting in |
2488 | * deadlocks with the reset work. |
2505 | * deadlocks with the reset work. |
2489 | */ |
2506 | */ |
Line 2490... | Line 2507... | ||
2490 | // ret = i915_reset(dev); |
2507 | ret = i915_reset(dev); |
Line 2491... | Line 2508... | ||
2491 | 2508 | ||
Line 2492... | Line 2509... | ||
2492 | // intel_finish_reset(dev); |
2509 | intel_finish_reset(dev); |
2493 | 2510 | ||
Line 2630... | Line 2647... | ||
2630 | 2647 | ||
2631 | va_start(args, fmt); |
2648 | va_start(args, fmt); |
2632 | vscnprintf(error_msg, sizeof(error_msg), fmt, args); |
2649 | vscnprintf(error_msg, sizeof(error_msg), fmt, args); |
Line 2633... | Line 2650... | ||
2633 | va_end(args); |
2650 | va_end(args); |
2634 | 2651 | ||
Line 2635... | Line 2652... | ||
2635 | // i915_capture_error_state(dev); |
2652 | i915_capture_error_state(dev, wedged, error_msg); |
2636 | i915_report_and_clear_eir(dev); |
2653 | i915_report_and_clear_eir(dev); |
2637 | 2654 | ||
Line 2922... | Line 2939... | ||
2922 | 2939 | ||
2923 | for_each_ring(ring, dev_priv, i) |
2940 | for_each_ring(ring, dev_priv, i) |
2924 | ring->hangcheck.deadlock = 0; |
2941 | ring->hangcheck.deadlock = 0; |
Line 2925... | Line -... | ||
2925 | } |
- | |
2926 | 2942 | } |
|
2927 | static enum intel_ring_hangcheck_action |
2943 | |
- | 2944 | static bool subunits_stuck(struct intel_engine_cs *ring) |
|
- | 2945 | { |
|
- | 2946 | u32 instdone[I915_NUM_INSTDONE_REG]; |
|
- | 2947 | bool stuck; |
|
- | 2948 | int i; |
|
- | 2949 | ||
- | 2950 | if (ring->id != RCS) |
|
2928 | ring_stuck(struct intel_engine_cs *ring, u64 acthd) |
2951 | return true; |
- | 2952 | ||
2929 | { |
2953 | i915_get_extra_instdone(ring->dev, instdone); |
- | 2954 | ||
- | 2955 | /* There might be unstable subunit states even when |
|
- | 2956 | * actual head is not moving. Filter out the unstable ones by |
|
- | 2957 | * accumulating the undone -> done transitions and only |
|
2930 | struct drm_device *dev = ring->dev; |
2958 | * consider those as progress. |
- | 2959 | */ |
|
- | 2960 | stuck = true; |
|
- | 2961 | for (i = 0; i < I915_NUM_INSTDONE_REG; i++) { |
|
- | 2962 | const u32 tmp = instdone[i] | ring->hangcheck.instdone[i]; |
|
- | 2963 | ||
Line -... | Line 2964... | ||
- | 2964 | if (tmp != ring->hangcheck.instdone[i]) |
|
- | 2965 | stuck = false; |
|
- | 2966 | ||
- | 2967 | ring->hangcheck.instdone[i] |= tmp; |
|
- | 2968 | } |
|
- | 2969 | ||
- | 2970 | return stuck; |
|
- | 2971 | } |
|
- | 2972 | ||
2931 | struct drm_i915_private *dev_priv = dev->dev_private; |
2973 | static enum intel_ring_hangcheck_action |
- | 2974 | head_stuck(struct intel_engine_cs *ring, u64 acthd) |
|
- | 2975 | { |
|
- | 2976 | if (acthd != ring->hangcheck.acthd) { |
|
- | 2977 | ||
- | 2978 | /* Clear subunit states on head movement */ |
|
2932 | u32 tmp; |
2979 | memset(ring->hangcheck.instdone, 0, |
2933 | 2980 | sizeof(ring->hangcheck.instdone)); |
|
2934 | if (acthd != ring->hangcheck.acthd) { |
2981 | |
2935 | if (acthd > ring->hangcheck.max_acthd) { |
2982 | if (acthd > ring->hangcheck.max_acthd) { |
Line 2936... | Line 2983... | ||
2936 | ring->hangcheck.max_acthd = acthd; |
2983 | ring->hangcheck.max_acthd = acthd; |
2937 | return HANGCHECK_ACTIVE; |
2984 | return HANGCHECK_ACTIVE; |
Line -... | Line 2985... | ||
- | 2985 | } |
|
- | 2986 | ||
- | 2987 | return HANGCHECK_ACTIVE_LOOP; |
|
- | 2988 | } |
|
- | 2989 | ||
- | 2990 | if (!subunits_stuck(ring)) |
|
- | 2991 | return HANGCHECK_ACTIVE; |
|
- | 2992 | ||
- | 2993 | return HANGCHECK_HUNG; |
|
- | 2994 | } |
|
- | 2995 | ||
- | 2996 | static enum intel_ring_hangcheck_action |
|
- | 2997 | ring_stuck(struct intel_engine_cs *ring, u64 acthd) |
|
- | 2998 | { |
|
- | 2999 | struct drm_device *dev = ring->dev; |
|
- | 3000 | struct drm_i915_private *dev_priv = dev->dev_private; |
|
- | 3001 | enum intel_ring_hangcheck_action ha; |
|
- | 3002 | u32 tmp; |
|
2938 | } |
3003 | |
2939 | 3004 | ha = head_stuck(ring, acthd); |
|
Line 2940... | Line 3005... | ||
2940 | return HANGCHECK_ACTIVE_LOOP; |
3005 | if (ha != HANGCHECK_HUNG) |
2941 | } |
3006 | return ha; |
Line 3005... | Line 3070... | ||
3005 | * require a wakeref. TODO: instead of disabling the asserts make |
3070 | * require a wakeref. TODO: instead of disabling the asserts make |
3006 | * sure that we hold a reference when this work is running. |
3071 | * sure that we hold a reference when this work is running. |
3007 | */ |
3072 | */ |
3008 | DISABLE_RPM_WAKEREF_ASSERTS(dev_priv); |
3073 | DISABLE_RPM_WAKEREF_ASSERTS(dev_priv); |
Line -... | Line 3074... | ||
- | 3074 | ||
- | 3075 | /* As enabling the GPU requires fairly extensive mmio access, |
|
- | 3076 | * periodically arm the mmio checker to see if we are triggering |
|
- | 3077 | * any invalid access. |
|
- | 3078 | */ |
|
- | 3079 | intel_uncore_arm_unclaimed_mmio_detection(dev_priv); |
|
3009 | 3080 | ||
3010 | for_each_ring(ring, dev_priv, i) { |
3081 | for_each_ring(ring, dev_priv, i) { |
3011 | u64 acthd; |
3082 | u64 acthd; |
3012 | u32 seqno; |
3083 | u32 seqno; |
Line 3079... | Line 3150... | ||
3079 | * attempts across multiple batches. |
3150 | * attempts across multiple batches. |
3080 | */ |
3151 | */ |
3081 | if (ring->hangcheck.score > 0) |
3152 | if (ring->hangcheck.score > 0) |
3082 | ring->hangcheck.score--; |
3153 | ring->hangcheck.score--; |
Line -... | Line 3154... | ||
- | 3154 | ||
3083 | 3155 | /* Clear head and subunit states on seqno movement */ |
|
- | 3156 | ring->hangcheck.acthd = ring->hangcheck.max_acthd = 0; |
|
- | 3157 | ||
- | 3158 | memset(ring->hangcheck.instdone, 0, |
|
3084 | ring->hangcheck.acthd = ring->hangcheck.max_acthd = 0; |
3159 | sizeof(ring->hangcheck.instdone)); |
Line 3085... | Line 3160... | ||
3085 | } |
3160 | } |
3086 | 3161 | ||
3087 | ring->hangcheck.seqno = seqno; |
3162 | ring->hangcheck.seqno = seqno; |
Line 3096... | Line 3171... | ||
3096 | ring->name); |
3171 | ring->name); |
3097 | rings_hung++; |
3172 | rings_hung++; |
3098 | } |
3173 | } |
3099 | } |
3174 | } |
Line 3100... | Line 3175... | ||
3100 | 3175 | ||
3101 | // if (rings_hung) |
3176 | if (rings_hung) { |
- | 3177 | i915_handle_error(dev, true, "Ring hung"); |
|
- | 3178 | goto out; |
|
- | 3179 | } |
|
- | 3180 | ||
- | 3181 | if (busy_count) |
|
- | 3182 | /* Reset timer case chip hangs without another request |
|
- | 3183 | * being added */ |
|
Line -... | Line 3184... | ||
- | 3184 | i915_queue_hangcheck(dev); |
|
- | 3185 | ||
- | 3186 | out: |
|
- | 3187 | ENABLE_RPM_WAKEREF_ASSERTS(dev_priv); |
|
- | 3188 | } |
|
- | 3189 | ||
- | 3190 | void i915_queue_hangcheck(struct drm_device *dev) |
|
- | 3191 | { |
|
- | 3192 | struct i915_gpu_error *e = &to_i915(dev)->gpu_error; |
|
- | 3193 | ||
- | 3194 | if (!i915.enable_hangcheck) |
|
- | 3195 | return; |
|
- | 3196 | ||
- | 3197 | /* Don't continually defer the hangcheck so that it is always run at |
|
- | 3198 | * least once after work has been scheduled on any ring. Otherwise, |
|
- | 3199 | * we will ignore a hung ring if a second ring is kept busy. |
|
- | 3200 | */ |
|
- | 3201 | ||
3102 | // return i915_handle_error(dev, true); |
3202 | queue_delayed_work(e->hangcheck_wq, &e->hangcheck_work, |
Line 3103... | Line 3203... | ||
3103 | 3203 | round_jiffies_up_relative(DRM_I915_HANGCHECK_JIFFIES)); |
|
3104 | } |
3204 | } |
3105 | 3205 | ||
Line 3225... | Line 3325... | ||
3225 | 3325 | ||
3226 | void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, |
3326 | void gen8_irq_power_well_post_enable(struct drm_i915_private *dev_priv, |
3227 | unsigned int pipe_mask) |
3327 | unsigned int pipe_mask) |
3228 | { |
3328 | { |
- | 3329 | uint32_t extra_ier = GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN; |
|
- | 3330 | enum pipe pipe; |
|
- | 3331 | ||
- | 3332 | spin_lock_irq(&dev_priv->irq_lock); |
|
- | 3333 | for_each_pipe_masked(dev_priv, pipe, pipe_mask) |
|
- | 3334 | GEN8_IRQ_INIT_NDX(DE_PIPE, pipe, |
|
- | 3335 | dev_priv->de_irq_mask[pipe], |
|
- | 3336 | ~dev_priv->de_irq_mask[pipe] | extra_ier); |
|
- | 3337 | spin_unlock_irq(&dev_priv->irq_lock); |
|
- | 3338 | } |
|
- | 3339 | ||
- | 3340 | void gen8_irq_power_well_pre_disable(struct drm_i915_private *dev_priv, |
|
- | 3341 | unsigned int pipe_mask) |
|
- | 3342 | { |
|
Line 3229... | Line 3343... | ||
3229 | uint32_t extra_ier = GEN8_PIPE_VBLANK | GEN8_PIPE_FIFO_UNDERRUN; |
3343 | enum pipe pipe; |
3230 | - | ||
3231 | spin_lock_irq(&dev_priv->irq_lock); |
- | |
3232 | if (pipe_mask & 1 << PIPE_A) |
- | |
3233 | GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_A, |
- | |
3234 | dev_priv->de_irq_mask[PIPE_A], |
3344 | |
3235 | ~dev_priv->de_irq_mask[PIPE_A] | extra_ier); |
- | |
3236 | if (pipe_mask & 1 << PIPE_B) |
- | |
3237 | GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_B, |
- | |
3238 | dev_priv->de_irq_mask[PIPE_B], |
- | |
3239 | ~dev_priv->de_irq_mask[PIPE_B] | extra_ier); |
3345 | spin_lock_irq(&dev_priv->irq_lock); |
3240 | if (pipe_mask & 1 << PIPE_C) |
- | |
3241 | GEN8_IRQ_INIT_NDX(DE_PIPE, PIPE_C, |
- | |
3242 | dev_priv->de_irq_mask[PIPE_C], |
3346 | for_each_pipe_masked(dev_priv, pipe, pipe_mask) |
- | 3347 | GEN8_IRQ_RESET_NDX(DE_PIPE, pipe); |
|
- | 3348 | spin_unlock_irq(&dev_priv->irq_lock); |
|
- | 3349 | ||
3243 | ~dev_priv->de_irq_mask[PIPE_C] | extra_ier); |
3350 | /* make sure we're done processing display irqs */ |
Line 3244... | Line 3351... | ||
3244 | spin_unlock_irq(&dev_priv->irq_lock); |
3351 | synchronize_irq(dev_priv->dev->irq); |
3245 | } |
3352 | } |
3246 | 3353 | ||
Line 4567... | Line 4674... | ||
4567 | */ |
4674 | */ |
4568 | void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv) |
4675 | void intel_runtime_pm_disable_interrupts(struct drm_i915_private *dev_priv) |
4569 | { |
4676 | { |
4570 | dev_priv->dev->driver->irq_uninstall(dev_priv->dev); |
4677 | dev_priv->dev->driver->irq_uninstall(dev_priv->dev); |
4571 | dev_priv->pm.irqs_enabled = false; |
4678 | dev_priv->pm.irqs_enabled = false; |
- | 4679 | synchronize_irq(dev_priv->dev->irq); |
|
4572 | } |
4680 | } |
Line 4573... | Line 4681... | ||
4573 | 4681 | ||
4574 | /** |
4682 | /** |
4575 | * intel_runtime_pm_enable_interrupts - runtime interrupt enabling |
4683 | * intel_runtime_pm_enable_interrupts - runtime interrupt enabling |