diff options
Diffstat (limited to 'drivers/gpu/drm/i915/i915_irq.c')
| -rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 76 |
1 files changed, 45 insertions, 31 deletions
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 2479be001e40..dba53d4b9fb3 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
| @@ -940,22 +940,30 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | |||
| 940 | if (HAS_BSD(dev) && (iir & I915_BSD_USER_INTERRUPT)) | 940 | if (HAS_BSD(dev) && (iir & I915_BSD_USER_INTERRUPT)) |
| 941 | DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); | 941 | DRM_WAKEUP(&dev_priv->bsd_ring.irq_queue); |
| 942 | 942 | ||
| 943 | if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) | 943 | if (iir & I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT) { |
| 944 | intel_prepare_page_flip(dev, 0); | 944 | intel_prepare_page_flip(dev, 0); |
| 945 | if (dev_priv->flip_pending_is_done) | ||
| 946 | intel_finish_page_flip_plane(dev, 0); | ||
| 947 | } | ||
| 945 | 948 | ||
| 946 | if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT) | 949 | if (iir & I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT) { |
| 947 | intel_prepare_page_flip(dev, 1); | 950 | intel_prepare_page_flip(dev, 1); |
| 951 | if (dev_priv->flip_pending_is_done) | ||
| 952 | intel_finish_page_flip_plane(dev, 1); | ||
| 953 | } | ||
| 948 | 954 | ||
| 949 | if (pipea_stats & vblank_status) { | 955 | if (pipea_stats & vblank_status) { |
| 950 | vblank++; | 956 | vblank++; |
| 951 | drm_handle_vblank(dev, 0); | 957 | drm_handle_vblank(dev, 0); |
| 952 | intel_finish_page_flip(dev, 0); | 958 | if (!dev_priv->flip_pending_is_done) |
| 959 | intel_finish_page_flip(dev, 0); | ||
| 953 | } | 960 | } |
| 954 | 961 | ||
| 955 | if (pipeb_stats & vblank_status) { | 962 | if (pipeb_stats & vblank_status) { |
| 956 | vblank++; | 963 | vblank++; |
| 957 | drm_handle_vblank(dev, 1); | 964 | drm_handle_vblank(dev, 1); |
| 958 | intel_finish_page_flip(dev, 1); | 965 | if (!dev_priv->flip_pending_is_done) |
| 966 | intel_finish_page_flip(dev, 1); | ||
| 959 | } | 967 | } |
| 960 | 968 | ||
| 961 | if ((pipea_stats & I915_LEGACY_BLC_EVENT_STATUS) || | 969 | if ((pipea_stats & I915_LEGACY_BLC_EVENT_STATUS) || |
| @@ -1387,29 +1395,10 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
| 1387 | dev_priv->pipestat[1] = 0; | 1395 | dev_priv->pipestat[1] = 0; |
| 1388 | 1396 | ||
| 1389 | if (I915_HAS_HOTPLUG(dev)) { | 1397 | if (I915_HAS_HOTPLUG(dev)) { |
| 1390 | u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); | ||
| 1391 | |||
| 1392 | /* Note HDMI and DP share bits */ | ||
| 1393 | if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) | ||
| 1394 | hotplug_en |= HDMIB_HOTPLUG_INT_EN; | ||
| 1395 | if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS) | ||
| 1396 | hotplug_en |= HDMIC_HOTPLUG_INT_EN; | ||
| 1397 | if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) | ||
| 1398 | hotplug_en |= HDMID_HOTPLUG_INT_EN; | ||
| 1399 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS) | ||
| 1400 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; | ||
| 1401 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS) | ||
| 1402 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; | ||
| 1403 | if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) | ||
| 1404 | hotplug_en |= CRT_HOTPLUG_INT_EN; | ||
| 1405 | /* Ignore TV since it's buggy */ | ||
| 1406 | |||
| 1407 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); | ||
| 1408 | |||
| 1409 | /* Enable in IER... */ | 1398 | /* Enable in IER... */ |
| 1410 | enable_mask |= I915_DISPLAY_PORT_INTERRUPT; | 1399 | enable_mask |= I915_DISPLAY_PORT_INTERRUPT; |
| 1411 | /* and unmask in IMR */ | 1400 | /* and unmask in IMR */ |
| 1412 | i915_enable_irq(dev_priv, I915_DISPLAY_PORT_INTERRUPT); | 1401 | dev_priv->irq_mask_reg &= ~I915_DISPLAY_PORT_INTERRUPT; |
| 1413 | } | 1402 | } |
| 1414 | 1403 | ||
| 1415 | /* | 1404 | /* |
| @@ -1427,16 +1416,41 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
| 1427 | } | 1416 | } |
| 1428 | I915_WRITE(EMR, error_mask); | 1417 | I915_WRITE(EMR, error_mask); |
| 1429 | 1418 | ||
| 1430 | /* Disable pipe interrupt enables, clear pending pipe status */ | ||
| 1431 | I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff); | ||
| 1432 | I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff); | ||
| 1433 | /* Clear pending interrupt status */ | ||
| 1434 | I915_WRITE(IIR, I915_READ(IIR)); | ||
| 1435 | |||
| 1436 | I915_WRITE(IER, enable_mask); | ||
| 1437 | I915_WRITE(IMR, dev_priv->irq_mask_reg); | 1419 | I915_WRITE(IMR, dev_priv->irq_mask_reg); |
| 1420 | I915_WRITE(IER, enable_mask); | ||
| 1438 | (void) I915_READ(IER); | 1421 | (void) I915_READ(IER); |
| 1439 | 1422 | ||
| 1423 | if (I915_HAS_HOTPLUG(dev)) { | ||
| 1424 | u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); | ||
| 1425 | |||
| 1426 | /* Note HDMI and DP share bits */ | ||
| 1427 | if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) | ||
| 1428 | hotplug_en |= HDMIB_HOTPLUG_INT_EN; | ||
| 1429 | if (dev_priv->hotplug_supported_mask & HDMIC_HOTPLUG_INT_STATUS) | ||
| 1430 | hotplug_en |= HDMIC_HOTPLUG_INT_EN; | ||
| 1431 | if (dev_priv->hotplug_supported_mask & HDMID_HOTPLUG_INT_STATUS) | ||
| 1432 | hotplug_en |= HDMID_HOTPLUG_INT_EN; | ||
| 1433 | if (dev_priv->hotplug_supported_mask & SDVOC_HOTPLUG_INT_STATUS) | ||
| 1434 | hotplug_en |= SDVOC_HOTPLUG_INT_EN; | ||
| 1435 | if (dev_priv->hotplug_supported_mask & SDVOB_HOTPLUG_INT_STATUS) | ||
| 1436 | hotplug_en |= SDVOB_HOTPLUG_INT_EN; | ||
| 1437 | if (dev_priv->hotplug_supported_mask & CRT_HOTPLUG_INT_STATUS) { | ||
| 1438 | hotplug_en |= CRT_HOTPLUG_INT_EN; | ||
| 1439 | |||
| 1440 | /* Programming the CRT detection parameters tends | ||
| 1441 | to generate a spurious hotplug event about three | ||
| 1442 | seconds later. So just do it once. | ||
| 1443 | */ | ||
| 1444 | if (IS_G4X(dev)) | ||
| 1445 | hotplug_en |= CRT_HOTPLUG_ACTIVATION_PERIOD_64; | ||
| 1446 | hotplug_en |= CRT_HOTPLUG_VOLTAGE_COMPARE_50; | ||
| 1447 | } | ||
| 1448 | |||
| 1449 | /* Ignore TV since it's buggy */ | ||
| 1450 | |||
| 1451 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); | ||
| 1452 | } | ||
| 1453 | |||
| 1440 | opregion_enable_asle(dev); | 1454 | opregion_enable_asle(dev); |
| 1441 | 1455 | ||
| 1442 | return 0; | 1456 | return 0; |
