aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c15
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c2
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h2
-rw-r--r--drivers/gpu/drm/i915/i915_irq.c63
-rw-r--r--drivers/gpu/drm/i915/intel_drv.h1
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c10
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);
1343void i915_handle_error(struct drm_device *dev, bool wedged); 1344void i915_handle_error(struct drm_device *dev, bool wedged);
1344 1345
1345extern void intel_irq_init(struct drm_device *dev); 1346extern void intel_irq_init(struct drm_device *dev);
1347extern void intel_hpd_init(struct drm_device *dev);
1346extern void intel_gt_init(struct drm_device *dev); 1348extern void intel_gt_init(struct drm_device *dev);
1347extern void intel_gt_reset(struct drm_device *dev); 1349extern 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
2062static 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
2077static void valleyview_irq_uninstall(struct drm_device *dev) 2086static 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
2331static 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
2342static irqreturn_t i915_irq_handler(int irq, void *arg) 2360static irqreturn_t i915_irq_handler(int irq, void *arg)
@@ -2496,7 +2514,6 @@ static void i965_irq_preinstall(struct drm_device * dev)
2496static int i965_irq_postinstall(struct drm_device *dev) 2514static 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
2566static 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
2581static irqreturn_t i965_irq_handler(int irq, void *arg) 2607static 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
2823void 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);
589extern int intel_fbdev_init(struct drm_device *dev); 589extern int intel_fbdev_init(struct drm_device *dev);
590extern void intel_fbdev_initial_config(struct drm_device *dev);
590extern void intel_fbdev_fini(struct drm_device *dev); 591extern void intel_fbdev_fini(struct drm_device *dev);
591extern void intel_fbdev_set_suspend(struct drm_device *dev, int state); 592extern void intel_fbdev_set_suspend(struct drm_device *dev, int state);
592extern void intel_prepare_page_flip(struct drm_device *dev, int plane); 593extern 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
250void 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
250void intel_fbdev_fini(struct drm_device *dev) 258void 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;