diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 15 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 63 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_fb.c | 10 |
6 files changed, 79 insertions, 14 deletions
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 93630669c6dc..0c2ab40ab2ed 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1319,6 +1319,21 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
1319 | goto cleanup_gem; | 1319 | goto cleanup_gem; |
1320 | 1320 | ||
1321 | /* Only enable hotplug handling once the fbdev is fully set up. */ | 1321 | /* Only enable hotplug handling once the fbdev is fully set up. */ |
1322 | intel_hpd_init(dev); | ||
1323 | |||
1324 | /* | ||
1325 | * Some ports require correctly set-up hpd registers for detection to | ||
1326 | * work properly (leading to ghost connected connector status), e.g. VGA | ||
1327 | * on gm45. Hence we can only set up the initial fbdev config after hpd | ||
1328 | * irqs are fully enabled. Now we should scan for the initial config | ||
1329 | * only once hotplug handling is enabled, but due to screwed-up locking | ||
1330 | * around kms/fbdev init we can't protect the fdbev initial config | ||
1331 | * scanning against hotplug events. Hence do this first and ignore the | ||
1332 | * tiny window where we will loose hotplug notifactions. | ||
1333 | */ | ||
1334 | intel_fbdev_initial_config(dev); | ||
1335 | |||
1336 | /* Only enable hotplug handling once the fbdev is fully set up. */ | ||
1322 | dev_priv->enable_hotplug_processing = true; | 1337 | dev_priv->enable_hotplug_processing = true; |
1323 | 1338 | ||
1324 | drm_kms_helper_poll_init(dev); | 1339 | drm_kms_helper_poll_init(dev); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index a12921892446..fbd0b28b7200 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -566,6 +566,7 @@ static int __i915_drm_thaw(struct drm_device *dev) | |||
566 | intel_modeset_init_hw(dev); | 566 | intel_modeset_init_hw(dev); |
567 | intel_modeset_setup_hw_state(dev, false); | 567 | intel_modeset_setup_hw_state(dev, false); |
568 | drm_irq_install(dev); | 568 | drm_irq_install(dev); |
569 | intel_hpd_init(dev); | ||
569 | } | 570 | } |
570 | 571 | ||
571 | intel_opregion_init(dev); | 572 | intel_opregion_init(dev); |
@@ -871,6 +872,7 @@ int i915_reset(struct drm_device *dev) | |||
871 | 872 | ||
872 | drm_irq_uninstall(dev); | 873 | drm_irq_uninstall(dev); |
873 | drm_irq_install(dev); | 874 | drm_irq_install(dev); |
875 | intel_hpd_init(dev); | ||
874 | } else { | 876 | } else { |
875 | mutex_unlock(&dev->struct_mutex); | 877 | mutex_unlock(&dev->struct_mutex); |
876 | } | 878 | } |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 9da67824dde3..e55303e2f74e 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -297,6 +297,7 @@ struct drm_i915_display_funcs { | |||
297 | struct drm_i915_gem_object *obj); | 297 | struct drm_i915_gem_object *obj); |
298 | int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb, | 298 | int (*update_plane)(struct drm_crtc *crtc, struct drm_framebuffer *fb, |
299 | int x, int y); | 299 | int x, int y); |
300 | void (*hpd_irq_setup)(struct drm_device *dev); | ||
300 | /* clock updates for mode set */ | 301 | /* clock updates for mode set */ |
301 | /* cursor updates */ | 302 | /* cursor updates */ |
302 | /* render clock increase/decrease */ | 303 | /* render clock increase/decrease */ |
@@ -1343,6 +1344,7 @@ void i915_hangcheck_elapsed(unsigned long data); | |||
1343 | void i915_handle_error(struct drm_device *dev, bool wedged); | 1344 | void i915_handle_error(struct drm_device *dev, bool wedged); |
1344 | 1345 | ||
1345 | extern void intel_irq_init(struct drm_device *dev); | 1346 | extern void intel_irq_init(struct drm_device *dev); |
1347 | extern void intel_hpd_init(struct drm_device *dev); | ||
1346 | extern void intel_gt_init(struct drm_device *dev); | 1348 | extern void intel_gt_init(struct drm_device *dev); |
1347 | extern void intel_gt_reset(struct drm_device *dev); | 1349 | extern void intel_gt_reset(struct drm_device *dev); |
1348 | 1350 | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 914ecf4acfa6..551f370657b7 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -1995,7 +1995,6 @@ static int valleyview_irq_postinstall(struct drm_device *dev) | |||
1995 | { | 1995 | { |
1996 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1996 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1997 | u32 enable_mask; | 1997 | u32 enable_mask; |
1998 | u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); | ||
1999 | u32 pipestat_enable = PLANE_FLIP_DONE_INT_EN_VLV; | 1998 | u32 pipestat_enable = PLANE_FLIP_DONE_INT_EN_VLV; |
2000 | u32 render_irqs; | 1999 | u32 render_irqs; |
2001 | u16 msid; | 2000 | u16 msid; |
@@ -2024,6 +2023,9 @@ static int valleyview_irq_postinstall(struct drm_device *dev) | |||
2024 | msid |= (1<<14); | 2023 | msid |= (1<<14); |
2025 | pci_write_config_word(dev_priv->dev->pdev, 0x98, msid); | 2024 | pci_write_config_word(dev_priv->dev->pdev, 0x98, msid); |
2026 | 2025 | ||
2026 | I915_WRITE(PORT_HOTPLUG_EN, 0); | ||
2027 | POSTING_READ(PORT_HOTPLUG_EN); | ||
2028 | |||
2027 | I915_WRITE(VLV_IMR, dev_priv->irq_mask); | 2029 | I915_WRITE(VLV_IMR, dev_priv->irq_mask); |
2028 | I915_WRITE(VLV_IER, enable_mask); | 2030 | I915_WRITE(VLV_IER, enable_mask); |
2029 | I915_WRITE(VLV_IIR, 0xffffffff); | 2031 | I915_WRITE(VLV_IIR, 0xffffffff); |
@@ -2053,6 +2055,15 @@ static int valleyview_irq_postinstall(struct drm_device *dev) | |||
2053 | #endif | 2055 | #endif |
2054 | 2056 | ||
2055 | I915_WRITE(VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE); | 2057 | I915_WRITE(VLV_MASTER_IER, MASTER_INTERRUPT_ENABLE); |
2058 | |||
2059 | return 0; | ||
2060 | } | ||
2061 | |||
2062 | static void valleyview_hpd_irq_setup(struct drm_device *dev) | ||
2063 | { | ||
2064 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
2065 | u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); | ||
2066 | |||
2056 | /* Note HDMI and DP share bits */ | 2067 | /* Note HDMI and DP share bits */ |
2057 | if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) | 2068 | if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) |
2058 | hotplug_en |= HDMIB_HOTPLUG_INT_EN; | 2069 | hotplug_en |= HDMIB_HOTPLUG_INT_EN; |
@@ -2070,8 +2081,6 @@ static int valleyview_irq_postinstall(struct drm_device *dev) | |||
2070 | } | 2081 | } |
2071 | 2082 | ||
2072 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); | 2083 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); |
2073 | |||
2074 | return 0; | ||
2075 | } | 2084 | } |
2076 | 2085 | ||
2077 | static void valleyview_irq_uninstall(struct drm_device *dev) | 2086 | static void valleyview_irq_uninstall(struct drm_device *dev) |
@@ -2301,6 +2310,9 @@ static int i915_irq_postinstall(struct drm_device *dev) | |||
2301 | I915_USER_INTERRUPT; | 2310 | I915_USER_INTERRUPT; |
2302 | 2311 | ||
2303 | if (I915_HAS_HOTPLUG(dev)) { | 2312 | if (I915_HAS_HOTPLUG(dev)) { |
2313 | I915_WRITE(PORT_HOTPLUG_EN, 0); | ||
2314 | POSTING_READ(PORT_HOTPLUG_EN); | ||
2315 | |||
2304 | /* Enable in IER... */ | 2316 | /* Enable in IER... */ |
2305 | enable_mask |= I915_DISPLAY_PORT_INTERRUPT; | 2317 | enable_mask |= I915_DISPLAY_PORT_INTERRUPT; |
2306 | /* and unmask in IMR */ | 2318 | /* and unmask in IMR */ |
@@ -2311,8 +2323,18 @@ static int i915_irq_postinstall(struct drm_device *dev) | |||
2311 | I915_WRITE(IER, enable_mask); | 2323 | I915_WRITE(IER, enable_mask); |
2312 | POSTING_READ(IER); | 2324 | POSTING_READ(IER); |
2313 | 2325 | ||
2326 | intel_opregion_enable_asle(dev); | ||
2327 | |||
2328 | return 0; | ||
2329 | } | ||
2330 | |||
2331 | static void i915_hpd_irq_setup(struct drm_device *dev) | ||
2332 | { | ||
2333 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
2334 | u32 hotplug_en; | ||
2335 | |||
2314 | if (I915_HAS_HOTPLUG(dev)) { | 2336 | if (I915_HAS_HOTPLUG(dev)) { |
2315 | u32 hotplug_en = I915_READ(PORT_HOTPLUG_EN); | 2337 | hotplug_en = I915_READ(PORT_HOTPLUG_EN); |
2316 | 2338 | ||
2317 | if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) | 2339 | if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) |
2318 | hotplug_en |= HDMIB_HOTPLUG_INT_EN; | 2340 | hotplug_en |= HDMIB_HOTPLUG_INT_EN; |
@@ -2333,10 +2355,6 @@ static int i915_irq_postinstall(struct drm_device *dev) | |||
2333 | 2355 | ||
2334 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); | 2356 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); |
2335 | } | 2357 | } |
2336 | |||
2337 | intel_opregion_enable_asle(dev); | ||
2338 | |||
2339 | return 0; | ||
2340 | } | 2358 | } |
2341 | 2359 | ||
2342 | static irqreturn_t i915_irq_handler(int irq, void *arg) | 2360 | static irqreturn_t i915_irq_handler(int irq, void *arg) |
@@ -2496,7 +2514,6 @@ static void i965_irq_preinstall(struct drm_device * dev) | |||
2496 | static int i965_irq_postinstall(struct drm_device *dev) | 2514 | static int i965_irq_postinstall(struct drm_device *dev) |
2497 | { | 2515 | { |
2498 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 2516 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2499 | u32 hotplug_en; | ||
2500 | u32 enable_mask; | 2517 | u32 enable_mask; |
2501 | u32 error_mask; | 2518 | u32 error_mask; |
2502 | 2519 | ||
@@ -2538,6 +2555,19 @@ static int i965_irq_postinstall(struct drm_device *dev) | |||
2538 | I915_WRITE(IER, enable_mask); | 2555 | I915_WRITE(IER, enable_mask); |
2539 | POSTING_READ(IER); | 2556 | POSTING_READ(IER); |
2540 | 2557 | ||
2558 | I915_WRITE(PORT_HOTPLUG_EN, 0); | ||
2559 | POSTING_READ(PORT_HOTPLUG_EN); | ||
2560 | |||
2561 | intel_opregion_enable_asle(dev); | ||
2562 | |||
2563 | return 0; | ||
2564 | } | ||
2565 | |||
2566 | static void i965_hpd_irq_setup(struct drm_device *dev) | ||
2567 | { | ||
2568 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | ||
2569 | u32 hotplug_en; | ||
2570 | |||
2541 | /* Note HDMI and DP share hotplug bits */ | 2571 | /* Note HDMI and DP share hotplug bits */ |
2542 | hotplug_en = 0; | 2572 | hotplug_en = 0; |
2543 | if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) | 2573 | if (dev_priv->hotplug_supported_mask & HDMIB_HOTPLUG_INT_STATUS) |
@@ -2572,10 +2602,6 @@ static int i965_irq_postinstall(struct drm_device *dev) | |||
2572 | /* Ignore TV since it's buggy */ | 2602 | /* Ignore TV since it's buggy */ |
2573 | 2603 | ||
2574 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); | 2604 | I915_WRITE(PORT_HOTPLUG_EN, hotplug_en); |
2575 | |||
2576 | intel_opregion_enable_asle(dev); | ||
2577 | |||
2578 | return 0; | ||
2579 | } | 2605 | } |
2580 | 2606 | ||
2581 | static irqreturn_t i965_irq_handler(int irq, void *arg) | 2607 | static irqreturn_t i965_irq_handler(int irq, void *arg) |
@@ -2754,6 +2780,7 @@ void intel_irq_init(struct drm_device *dev) | |||
2754 | dev->driver->irq_uninstall = valleyview_irq_uninstall; | 2780 | dev->driver->irq_uninstall = valleyview_irq_uninstall; |
2755 | dev->driver->enable_vblank = valleyview_enable_vblank; | 2781 | dev->driver->enable_vblank = valleyview_enable_vblank; |
2756 | dev->driver->disable_vblank = valleyview_disable_vblank; | 2782 | dev->driver->disable_vblank = valleyview_disable_vblank; |
2783 | dev_priv->display.hpd_irq_setup = valleyview_hpd_irq_setup; | ||
2757 | } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { | 2784 | } else if (IS_IVYBRIDGE(dev) || IS_HASWELL(dev)) { |
2758 | /* Share pre & uninstall handlers with ILK/SNB */ | 2785 | /* Share pre & uninstall handlers with ILK/SNB */ |
2759 | dev->driver->irq_handler = ivybridge_irq_handler; | 2786 | dev->driver->irq_handler = ivybridge_irq_handler; |
@@ -2780,13 +2807,23 @@ void intel_irq_init(struct drm_device *dev) | |||
2780 | dev->driver->irq_postinstall = i915_irq_postinstall; | 2807 | dev->driver->irq_postinstall = i915_irq_postinstall; |
2781 | dev->driver->irq_uninstall = i915_irq_uninstall; | 2808 | dev->driver->irq_uninstall = i915_irq_uninstall; |
2782 | dev->driver->irq_handler = i915_irq_handler; | 2809 | dev->driver->irq_handler = i915_irq_handler; |
2810 | dev_priv->display.hpd_irq_setup = i915_hpd_irq_setup; | ||
2783 | } else { | 2811 | } else { |
2784 | dev->driver->irq_preinstall = i965_irq_preinstall; | 2812 | dev->driver->irq_preinstall = i965_irq_preinstall; |
2785 | dev->driver->irq_postinstall = i965_irq_postinstall; | 2813 | dev->driver->irq_postinstall = i965_irq_postinstall; |
2786 | dev->driver->irq_uninstall = i965_irq_uninstall; | 2814 | dev->driver->irq_uninstall = i965_irq_uninstall; |
2787 | dev->driver->irq_handler = i965_irq_handler; | 2815 | dev->driver->irq_handler = i965_irq_handler; |
2816 | dev_priv->display.hpd_irq_setup = i965_hpd_irq_setup; | ||
2788 | } | 2817 | } |
2789 | dev->driver->enable_vblank = i915_enable_vblank; | 2818 | dev->driver->enable_vblank = i915_enable_vblank; |
2790 | dev->driver->disable_vblank = i915_disable_vblank; | 2819 | dev->driver->disable_vblank = i915_disable_vblank; |
2791 | } | 2820 | } |
2792 | } | 2821 | } |
2822 | |||
2823 | void intel_hpd_init(struct drm_device *dev) | ||
2824 | { | ||
2825 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
2826 | |||
2827 | if (dev_priv->display.hpd_irq_setup) | ||
2828 | dev_priv->display.hpd_irq_setup(dev); | ||
2829 | } | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 7ca7772eaccd..22728f2c1d83 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -587,6 +587,7 @@ extern int intel_framebuffer_init(struct drm_device *dev, | |||
587 | struct drm_mode_fb_cmd2 *mode_cmd, | 587 | struct drm_mode_fb_cmd2 *mode_cmd, |
588 | struct drm_i915_gem_object *obj); | 588 | struct drm_i915_gem_object *obj); |
589 | extern int intel_fbdev_init(struct drm_device *dev); | 589 | extern int intel_fbdev_init(struct drm_device *dev); |
590 | extern void intel_fbdev_initial_config(struct drm_device *dev); | ||
590 | extern void intel_fbdev_fini(struct drm_device *dev); | 591 | extern void intel_fbdev_fini(struct drm_device *dev); |
591 | extern void intel_fbdev_set_suspend(struct drm_device *dev, int state); | 592 | extern void intel_fbdev_set_suspend(struct drm_device *dev, int state); |
592 | extern void intel_prepare_page_flip(struct drm_device *dev, int plane); | 593 | extern void intel_prepare_page_flip(struct drm_device *dev, int plane); |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index b7773e548911..822896782cd0 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -243,10 +243,18 @@ int intel_fbdev_init(struct drm_device *dev) | |||
243 | } | 243 | } |
244 | 244 | ||
245 | drm_fb_helper_single_add_all_connectors(&ifbdev->helper); | 245 | drm_fb_helper_single_add_all_connectors(&ifbdev->helper); |
246 | drm_fb_helper_initial_config(&ifbdev->helper, 32); | 246 | |
247 | return 0; | 247 | return 0; |
248 | } | 248 | } |
249 | 249 | ||
250 | void intel_fbdev_initial_config(struct drm_device *dev) | ||
251 | { | ||
252 | drm_i915_private_t *dev_priv = dev->dev_private; | ||
253 | |||
254 | /* Due to peculiar init order wrt to hpd handling this is separate. */ | ||
255 | drm_fb_helper_initial_config(&dev_priv->fbdev->helper, 32); | ||
256 | } | ||
257 | |||
250 | void intel_fbdev_fini(struct drm_device *dev) | 258 | void intel_fbdev_fini(struct drm_device *dev) |
251 | { | 259 | { |
252 | drm_i915_private_t *dev_priv = dev->dev_private; | 260 | drm_i915_private_t *dev_priv = dev->dev_private; |