diff options
Diffstat (limited to 'drivers/gpu/drm/i915')
-rw-r--r-- | drivers/gpu/drm/i915/i915_debugfs.c | 16 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_dma.c | 45 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.c | 11 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 32 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_irq.c | 80 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/i915_suspend.c | 19 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 118 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_overlay.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_ringbuffer.h | 2 |
9 files changed, 199 insertions, 141 deletions
diff --git a/drivers/gpu/drm/i915/i915_debugfs.c b/drivers/gpu/drm/i915/i915_debugfs.c index 4d46441cbe2d..0a893f7400fa 100644 --- a/drivers/gpu/drm/i915/i915_debugfs.c +++ b/drivers/gpu/drm/i915/i915_debugfs.c | |||
@@ -1207,13 +1207,17 @@ static int i915_context_status(struct seq_file *m, void *unused) | |||
1207 | if (ret) | 1207 | if (ret) |
1208 | return ret; | 1208 | return ret; |
1209 | 1209 | ||
1210 | seq_printf(m, "power context "); | 1210 | if (dev_priv->pwrctx) { |
1211 | describe_obj(m, dev_priv->pwrctx); | 1211 | seq_printf(m, "power context "); |
1212 | seq_printf(m, "\n"); | 1212 | describe_obj(m, dev_priv->pwrctx); |
1213 | seq_printf(m, "\n"); | ||
1214 | } | ||
1213 | 1215 | ||
1214 | seq_printf(m, "render context "); | 1216 | if (dev_priv->renderctx) { |
1215 | describe_obj(m, dev_priv->renderctx); | 1217 | seq_printf(m, "render context "); |
1216 | seq_printf(m, "\n"); | 1218 | describe_obj(m, dev_priv->renderctx); |
1219 | seq_printf(m, "\n"); | ||
1220 | } | ||
1217 | 1221 | ||
1218 | mutex_unlock(&dev->mode_config.mutex); | 1222 | mutex_unlock(&dev->mode_config.mutex); |
1219 | 1223 | ||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 2b79588541e7..296fbd66f0e1 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1266,30 +1266,6 @@ static int i915_load_modeset_init(struct drm_device *dev) | |||
1266 | 1266 | ||
1267 | intel_modeset_gem_init(dev); | 1267 | intel_modeset_gem_init(dev); |
1268 | 1268 | ||
1269 | if (IS_IVYBRIDGE(dev)) { | ||
1270 | /* Share pre & uninstall handlers with ILK/SNB */ | ||
1271 | dev->driver->irq_handler = ivybridge_irq_handler; | ||
1272 | dev->driver->irq_preinstall = ironlake_irq_preinstall; | ||
1273 | dev->driver->irq_postinstall = ivybridge_irq_postinstall; | ||
1274 | dev->driver->irq_uninstall = ironlake_irq_uninstall; | ||
1275 | dev->driver->enable_vblank = ivybridge_enable_vblank; | ||
1276 | dev->driver->disable_vblank = ivybridge_disable_vblank; | ||
1277 | } else if (HAS_PCH_SPLIT(dev)) { | ||
1278 | dev->driver->irq_handler = ironlake_irq_handler; | ||
1279 | dev->driver->irq_preinstall = ironlake_irq_preinstall; | ||
1280 | dev->driver->irq_postinstall = ironlake_irq_postinstall; | ||
1281 | dev->driver->irq_uninstall = ironlake_irq_uninstall; | ||
1282 | dev->driver->enable_vblank = ironlake_enable_vblank; | ||
1283 | dev->driver->disable_vblank = ironlake_disable_vblank; | ||
1284 | } else { | ||
1285 | dev->driver->irq_preinstall = i915_driver_irq_preinstall; | ||
1286 | dev->driver->irq_postinstall = i915_driver_irq_postinstall; | ||
1287 | dev->driver->irq_uninstall = i915_driver_irq_uninstall; | ||
1288 | dev->driver->irq_handler = i915_driver_irq_handler; | ||
1289 | dev->driver->enable_vblank = i915_enable_vblank; | ||
1290 | dev->driver->disable_vblank = i915_disable_vblank; | ||
1291 | } | ||
1292 | |||
1293 | ret = drm_irq_install(dev); | 1269 | ret = drm_irq_install(dev); |
1294 | if (ret) | 1270 | if (ret) |
1295 | goto cleanup_gem; | 1271 | goto cleanup_gem; |
@@ -1967,7 +1943,7 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1967 | if (!dev_priv->mm.gtt) { | 1943 | if (!dev_priv->mm.gtt) { |
1968 | DRM_ERROR("Failed to initialize GTT\n"); | 1944 | DRM_ERROR("Failed to initialize GTT\n"); |
1969 | ret = -ENODEV; | 1945 | ret = -ENODEV; |
1970 | goto out_iomapfree; | 1946 | goto out_rmmap; |
1971 | } | 1947 | } |
1972 | 1948 | ||
1973 | agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; | 1949 | agp_size = dev_priv->mm.gtt->gtt_mappable_entries << PAGE_SHIFT; |
@@ -2011,18 +1987,13 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2011 | if (dev_priv->wq == NULL) { | 1987 | if (dev_priv->wq == NULL) { |
2012 | DRM_ERROR("Failed to create our workqueue.\n"); | 1988 | DRM_ERROR("Failed to create our workqueue.\n"); |
2013 | ret = -ENOMEM; | 1989 | ret = -ENOMEM; |
2014 | goto out_iomapfree; | 1990 | goto out_mtrrfree; |
2015 | } | 1991 | } |
2016 | 1992 | ||
2017 | /* enable GEM by default */ | 1993 | /* enable GEM by default */ |
2018 | dev_priv->has_gem = 1; | 1994 | dev_priv->has_gem = 1; |
2019 | 1995 | ||
2020 | dev->driver->get_vblank_counter = i915_get_vblank_counter; | 1996 | intel_irq_init(dev); |
2021 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ | ||
2022 | if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev) || IS_IVYBRIDGE(dev)) { | ||
2023 | dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */ | ||
2024 | dev->driver->get_vblank_counter = gm45_get_vblank_counter; | ||
2025 | } | ||
2026 | 1997 | ||
2027 | /* Try to make sure MCHBAR is enabled before poking at it */ | 1998 | /* Try to make sure MCHBAR is enabled before poking at it */ |
2028 | intel_setup_mchbar(dev); | 1999 | intel_setup_mchbar(dev); |
@@ -2103,13 +2074,21 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
2103 | return 0; | 2074 | return 0; |
2104 | 2075 | ||
2105 | out_gem_unload: | 2076 | out_gem_unload: |
2077 | if (dev_priv->mm.inactive_shrinker.shrink) | ||
2078 | unregister_shrinker(&dev_priv->mm.inactive_shrinker); | ||
2079 | |||
2106 | if (dev->pdev->msi_enabled) | 2080 | if (dev->pdev->msi_enabled) |
2107 | pci_disable_msi(dev->pdev); | 2081 | pci_disable_msi(dev->pdev); |
2108 | 2082 | ||
2109 | intel_teardown_gmbus(dev); | 2083 | intel_teardown_gmbus(dev); |
2110 | intel_teardown_mchbar(dev); | 2084 | intel_teardown_mchbar(dev); |
2111 | destroy_workqueue(dev_priv->wq); | 2085 | destroy_workqueue(dev_priv->wq); |
2112 | out_iomapfree: | 2086 | out_mtrrfree: |
2087 | if (dev_priv->mm.gtt_mtrr >= 0) { | ||
2088 | mtrr_del(dev_priv->mm.gtt_mtrr, dev->agp->base, | ||
2089 | dev->agp->agp_info.aper_size * 1024 * 1024); | ||
2090 | dev_priv->mm.gtt_mtrr = -1; | ||
2091 | } | ||
2113 | io_mapping_free(dev_priv->mm.gtt_mapping); | 2092 | io_mapping_free(dev_priv->mm.gtt_mapping); |
2114 | out_rmmap: | 2093 | out_rmmap: |
2115 | pci_iounmap(dev->pdev, dev_priv->regs); | 2094 | pci_iounmap(dev->pdev, dev_priv->regs); |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index 609358faaa90..eb91e2dd7914 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -52,7 +52,7 @@ module_param_named(powersave, i915_powersave, int, 0600); | |||
52 | unsigned int i915_semaphores = 0; | 52 | unsigned int i915_semaphores = 0; |
53 | module_param_named(semaphores, i915_semaphores, int, 0600); | 53 | module_param_named(semaphores, i915_semaphores, int, 0600); |
54 | 54 | ||
55 | unsigned int i915_enable_rc6 = 1; | 55 | unsigned int i915_enable_rc6 = 0; |
56 | module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); | 56 | module_param_named(i915_enable_rc6, i915_enable_rc6, int, 0600); |
57 | 57 | ||
58 | unsigned int i915_enable_fbc = 0; | 58 | unsigned int i915_enable_fbc = 0; |
@@ -577,6 +577,7 @@ int i915_reset(struct drm_device *dev, u8 flags) | |||
577 | if (get_seconds() - dev_priv->last_gpu_reset < 5) { | 577 | if (get_seconds() - dev_priv->last_gpu_reset < 5) { |
578 | DRM_ERROR("GPU hanging too fast, declaring wedged!\n"); | 578 | DRM_ERROR("GPU hanging too fast, declaring wedged!\n"); |
579 | } else switch (INTEL_INFO(dev)->gen) { | 579 | } else switch (INTEL_INFO(dev)->gen) { |
580 | case 7: | ||
580 | case 6: | 581 | case 6: |
581 | ret = gen6_do_reset(dev, flags); | 582 | ret = gen6_do_reset(dev, flags); |
582 | /* If reset with a user forcewake, try to restore */ | 583 | /* If reset with a user forcewake, try to restore */ |
@@ -765,14 +766,6 @@ static struct drm_driver driver = { | |||
765 | .resume = i915_resume, | 766 | .resume = i915_resume, |
766 | 767 | ||
767 | .device_is_agp = i915_driver_device_is_agp, | 768 | .device_is_agp = i915_driver_device_is_agp, |
768 | .enable_vblank = i915_enable_vblank, | ||
769 | .disable_vblank = i915_disable_vblank, | ||
770 | .get_vblank_timestamp = i915_get_vblank_timestamp, | ||
771 | .get_scanout_position = i915_get_crtc_scanoutpos, | ||
772 | .irq_preinstall = i915_driver_irq_preinstall, | ||
773 | .irq_postinstall = i915_driver_irq_postinstall, | ||
774 | .irq_uninstall = i915_driver_irq_uninstall, | ||
775 | .irq_handler = i915_driver_irq_handler, | ||
776 | .reclaim_buffers = drm_core_reclaim_buffers, | 769 | .reclaim_buffers = drm_core_reclaim_buffers, |
777 | .master_create = i915_master_create, | 770 | .master_create = i915_master_create, |
778 | .master_destroy = i915_master_destroy, | 771 | .master_destroy = i915_master_destroy, |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index eddabf68e97a..f245c588ae95 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -997,8 +997,6 @@ extern unsigned int i915_enable_fbc; | |||
997 | 997 | ||
998 | extern int i915_suspend(struct drm_device *dev, pm_message_t state); | 998 | extern int i915_suspend(struct drm_device *dev, pm_message_t state); |
999 | extern int i915_resume(struct drm_device *dev); | 999 | extern int i915_resume(struct drm_device *dev); |
1000 | extern void i915_save_display(struct drm_device *dev); | ||
1001 | extern void i915_restore_display(struct drm_device *dev); | ||
1002 | extern int i915_master_create(struct drm_device *dev, struct drm_master *master); | 1000 | extern int i915_master_create(struct drm_device *dev, struct drm_master *master); |
1003 | extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master); | 1001 | extern void i915_master_destroy(struct drm_device *dev, struct drm_master *master); |
1004 | 1002 | ||
@@ -1033,33 +1031,12 @@ extern int i915_irq_emit(struct drm_device *dev, void *data, | |||
1033 | extern int i915_irq_wait(struct drm_device *dev, void *data, | 1031 | extern int i915_irq_wait(struct drm_device *dev, void *data, |
1034 | struct drm_file *file_priv); | 1032 | struct drm_file *file_priv); |
1035 | 1033 | ||
1036 | extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS); | 1034 | extern void intel_irq_init(struct drm_device *dev); |
1037 | extern void i915_driver_irq_preinstall(struct drm_device * dev); | ||
1038 | extern int i915_driver_irq_postinstall(struct drm_device *dev); | ||
1039 | extern void i915_driver_irq_uninstall(struct drm_device * dev); | ||
1040 | |||
1041 | extern irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS); | ||
1042 | extern void ironlake_irq_preinstall(struct drm_device *dev); | ||
1043 | extern int ironlake_irq_postinstall(struct drm_device *dev); | ||
1044 | extern void ironlake_irq_uninstall(struct drm_device *dev); | ||
1045 | |||
1046 | extern irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS); | ||
1047 | extern void ivybridge_irq_preinstall(struct drm_device *dev); | ||
1048 | extern int ivybridge_irq_postinstall(struct drm_device *dev); | ||
1049 | extern void ivybridge_irq_uninstall(struct drm_device *dev); | ||
1050 | 1035 | ||
1051 | extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, | 1036 | extern int i915_vblank_pipe_set(struct drm_device *dev, void *data, |
1052 | struct drm_file *file_priv); | 1037 | struct drm_file *file_priv); |
1053 | extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, | 1038 | extern int i915_vblank_pipe_get(struct drm_device *dev, void *data, |
1054 | struct drm_file *file_priv); | 1039 | struct drm_file *file_priv); |
1055 | extern int i915_enable_vblank(struct drm_device *dev, int crtc); | ||
1056 | extern void i915_disable_vblank(struct drm_device *dev, int crtc); | ||
1057 | extern int ironlake_enable_vblank(struct drm_device *dev, int crtc); | ||
1058 | extern void ironlake_disable_vblank(struct drm_device *dev, int crtc); | ||
1059 | extern int ivybridge_enable_vblank(struct drm_device *dev, int crtc); | ||
1060 | extern void ivybridge_disable_vblank(struct drm_device *dev, int crtc); | ||
1061 | extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc); | ||
1062 | extern u32 gm45_get_vblank_counter(struct drm_device *dev, int crtc); | ||
1063 | extern int i915_vblank_swap(struct drm_device *dev, void *data, | 1040 | extern int i915_vblank_swap(struct drm_device *dev, void *data, |
1064 | struct drm_file *file_priv); | 1041 | struct drm_file *file_priv); |
1065 | 1042 | ||
@@ -1070,13 +1047,6 @@ void | |||
1070 | i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); | 1047 | i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask); |
1071 | 1048 | ||
1072 | void intel_enable_asle (struct drm_device *dev); | 1049 | void intel_enable_asle (struct drm_device *dev); |
1073 | int i915_get_vblank_timestamp(struct drm_device *dev, int crtc, | ||
1074 | int *max_error, | ||
1075 | struct timeval *vblank_time, | ||
1076 | unsigned flags); | ||
1077 | |||
1078 | int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, | ||
1079 | int *vpos, int *hpos); | ||
1080 | 1050 | ||
1081 | #ifdef CONFIG_DEBUG_FS | 1051 | #ifdef CONFIG_DEBUG_FS |
1082 | extern void i915_destroy_error_state(struct drm_device *dev); | 1052 | extern void i915_destroy_error_state(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index ae2b49969b99..3b03f85ea627 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -152,7 +152,7 @@ i915_pipe_enabled(struct drm_device *dev, int pipe) | |||
152 | /* Called from drm generic code, passed a 'crtc', which | 152 | /* Called from drm generic code, passed a 'crtc', which |
153 | * we use as a pipe index | 153 | * we use as a pipe index |
154 | */ | 154 | */ |
155 | u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) | 155 | static u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) |
156 | { | 156 | { |
157 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 157 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
158 | unsigned long high_frame; | 158 | unsigned long high_frame; |
@@ -184,7 +184,7 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe) | |||
184 | return (high1 << 8) | low; | 184 | return (high1 << 8) | low; |
185 | } | 185 | } |
186 | 186 | ||
187 | u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) | 187 | static u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) |
188 | { | 188 | { |
189 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 189 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
190 | int reg = PIPE_FRMCOUNT_GM45(pipe); | 190 | int reg = PIPE_FRMCOUNT_GM45(pipe); |
@@ -198,7 +198,7 @@ u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe) | |||
198 | return I915_READ(reg); | 198 | return I915_READ(reg); |
199 | } | 199 | } |
200 | 200 | ||
201 | int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, | 201 | static int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, |
202 | int *vpos, int *hpos) | 202 | int *vpos, int *hpos) |
203 | { | 203 | { |
204 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 204 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
@@ -264,7 +264,7 @@ int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe, | |||
264 | return ret; | 264 | return ret; |
265 | } | 265 | } |
266 | 266 | ||
267 | int i915_get_vblank_timestamp(struct drm_device *dev, int pipe, | 267 | static int i915_get_vblank_timestamp(struct drm_device *dev, int pipe, |
268 | int *max_error, | 268 | int *max_error, |
269 | struct timeval *vblank_time, | 269 | struct timeval *vblank_time, |
270 | unsigned flags) | 270 | unsigned flags) |
@@ -462,7 +462,7 @@ static void pch_irq_handler(struct drm_device *dev) | |||
462 | DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n"); | 462 | DRM_DEBUG_DRIVER("PCH transcoder A underrun interrupt\n"); |
463 | } | 463 | } |
464 | 464 | ||
465 | irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) | 465 | static irqreturn_t ivybridge_irq_handler(DRM_IRQ_ARGS) |
466 | { | 466 | { |
467 | struct drm_device *dev = (struct drm_device *) arg; | 467 | struct drm_device *dev = (struct drm_device *) arg; |
468 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 468 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
@@ -550,7 +550,7 @@ done: | |||
550 | return ret; | 550 | return ret; |
551 | } | 551 | } |
552 | 552 | ||
553 | irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) | 553 | static irqreturn_t ironlake_irq_handler(DRM_IRQ_ARGS) |
554 | { | 554 | { |
555 | struct drm_device *dev = (struct drm_device *) arg; | 555 | struct drm_device *dev = (struct drm_device *) arg; |
556 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 556 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
@@ -1209,7 +1209,7 @@ static void i915_pageflip_stall_check(struct drm_device *dev, int pipe) | |||
1209 | } | 1209 | } |
1210 | } | 1210 | } |
1211 | 1211 | ||
1212 | irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) | 1212 | static irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS) |
1213 | { | 1213 | { |
1214 | struct drm_device *dev = (struct drm_device *) arg; | 1214 | struct drm_device *dev = (struct drm_device *) arg; |
1215 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1215 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
@@ -1454,7 +1454,7 @@ int i915_irq_wait(struct drm_device *dev, void *data, | |||
1454 | /* Called from drm generic code, passed 'crtc' which | 1454 | /* Called from drm generic code, passed 'crtc' which |
1455 | * we use as a pipe index | 1455 | * we use as a pipe index |
1456 | */ | 1456 | */ |
1457 | int i915_enable_vblank(struct drm_device *dev, int pipe) | 1457 | static int i915_enable_vblank(struct drm_device *dev, int pipe) |
1458 | { | 1458 | { |
1459 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1459 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1460 | unsigned long irqflags; | 1460 | unsigned long irqflags; |
@@ -1478,7 +1478,7 @@ int i915_enable_vblank(struct drm_device *dev, int pipe) | |||
1478 | return 0; | 1478 | return 0; |
1479 | } | 1479 | } |
1480 | 1480 | ||
1481 | int ironlake_enable_vblank(struct drm_device *dev, int pipe) | 1481 | static int ironlake_enable_vblank(struct drm_device *dev, int pipe) |
1482 | { | 1482 | { |
1483 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1483 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1484 | unsigned long irqflags; | 1484 | unsigned long irqflags; |
@@ -1494,7 +1494,7 @@ int ironlake_enable_vblank(struct drm_device *dev, int pipe) | |||
1494 | return 0; | 1494 | return 0; |
1495 | } | 1495 | } |
1496 | 1496 | ||
1497 | int ivybridge_enable_vblank(struct drm_device *dev, int pipe) | 1497 | static int ivybridge_enable_vblank(struct drm_device *dev, int pipe) |
1498 | { | 1498 | { |
1499 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1499 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1500 | unsigned long irqflags; | 1500 | unsigned long irqflags; |
@@ -1513,7 +1513,7 @@ int ivybridge_enable_vblank(struct drm_device *dev, int pipe) | |||
1513 | /* Called from drm generic code, passed 'crtc' which | 1513 | /* Called from drm generic code, passed 'crtc' which |
1514 | * we use as a pipe index | 1514 | * we use as a pipe index |
1515 | */ | 1515 | */ |
1516 | void i915_disable_vblank(struct drm_device *dev, int pipe) | 1516 | static void i915_disable_vblank(struct drm_device *dev, int pipe) |
1517 | { | 1517 | { |
1518 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1518 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1519 | unsigned long irqflags; | 1519 | unsigned long irqflags; |
@@ -1529,7 +1529,7 @@ void i915_disable_vblank(struct drm_device *dev, int pipe) | |||
1529 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 1529 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
1530 | } | 1530 | } |
1531 | 1531 | ||
1532 | void ironlake_disable_vblank(struct drm_device *dev, int pipe) | 1532 | static void ironlake_disable_vblank(struct drm_device *dev, int pipe) |
1533 | { | 1533 | { |
1534 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1534 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1535 | unsigned long irqflags; | 1535 | unsigned long irqflags; |
@@ -1540,7 +1540,7 @@ void ironlake_disable_vblank(struct drm_device *dev, int pipe) | |||
1540 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); | 1540 | spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags); |
1541 | } | 1541 | } |
1542 | 1542 | ||
1543 | void ivybridge_disable_vblank(struct drm_device *dev, int pipe) | 1543 | static void ivybridge_disable_vblank(struct drm_device *dev, int pipe) |
1544 | { | 1544 | { |
1545 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1545 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1546 | unsigned long irqflags; | 1546 | unsigned long irqflags; |
@@ -1728,7 +1728,7 @@ repeat: | |||
1728 | 1728 | ||
1729 | /* drm_dma.h hooks | 1729 | /* drm_dma.h hooks |
1730 | */ | 1730 | */ |
1731 | void ironlake_irq_preinstall(struct drm_device *dev) | 1731 | static void ironlake_irq_preinstall(struct drm_device *dev) |
1732 | { | 1732 | { |
1733 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1733 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1734 | 1734 | ||
@@ -1740,7 +1740,7 @@ void ironlake_irq_preinstall(struct drm_device *dev) | |||
1740 | INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); | 1740 | INIT_WORK(&dev_priv->rps_work, gen6_pm_rps_work); |
1741 | 1741 | ||
1742 | I915_WRITE(HWSTAM, 0xeffe); | 1742 | I915_WRITE(HWSTAM, 0xeffe); |
1743 | if (IS_GEN6(dev)) { | 1743 | if (IS_GEN6(dev) || IS_GEN7(dev)) { |
1744 | /* Workaround stalls observed on Sandy Bridge GPUs by | 1744 | /* Workaround stalls observed on Sandy Bridge GPUs by |
1745 | * making the blitter command streamer generate a | 1745 | * making the blitter command streamer generate a |
1746 | * write to the Hardware Status Page for | 1746 | * write to the Hardware Status Page for |
@@ -1769,7 +1769,7 @@ void ironlake_irq_preinstall(struct drm_device *dev) | |||
1769 | POSTING_READ(SDEIER); | 1769 | POSTING_READ(SDEIER); |
1770 | } | 1770 | } |
1771 | 1771 | ||
1772 | int ironlake_irq_postinstall(struct drm_device *dev) | 1772 | static int ironlake_irq_postinstall(struct drm_device *dev) |
1773 | { | 1773 | { |
1774 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1774 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1775 | /* enable kind of interrupts always enabled */ | 1775 | /* enable kind of interrupts always enabled */ |
@@ -1841,7 +1841,7 @@ int ironlake_irq_postinstall(struct drm_device *dev) | |||
1841 | return 0; | 1841 | return 0; |
1842 | } | 1842 | } |
1843 | 1843 | ||
1844 | int ivybridge_irq_postinstall(struct drm_device *dev) | 1844 | static int ivybridge_irq_postinstall(struct drm_device *dev) |
1845 | { | 1845 | { |
1846 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1846 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1847 | /* enable kind of interrupts always enabled */ | 1847 | /* enable kind of interrupts always enabled */ |
@@ -1891,7 +1891,7 @@ int ivybridge_irq_postinstall(struct drm_device *dev) | |||
1891 | return 0; | 1891 | return 0; |
1892 | } | 1892 | } |
1893 | 1893 | ||
1894 | void i915_driver_irq_preinstall(struct drm_device * dev) | 1894 | static void i915_driver_irq_preinstall(struct drm_device * dev) |
1895 | { | 1895 | { |
1896 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1896 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1897 | int pipe; | 1897 | int pipe; |
@@ -1918,7 +1918,7 @@ void i915_driver_irq_preinstall(struct drm_device * dev) | |||
1918 | * Must be called after intel_modeset_init or hotplug interrupts won't be | 1918 | * Must be called after intel_modeset_init or hotplug interrupts won't be |
1919 | * enabled correctly. | 1919 | * enabled correctly. |
1920 | */ | 1920 | */ |
1921 | int i915_driver_irq_postinstall(struct drm_device *dev) | 1921 | static int i915_driver_irq_postinstall(struct drm_device *dev) |
1922 | { | 1922 | { |
1923 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1923 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
1924 | u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; | 1924 | u32 enable_mask = I915_INTERRUPT_ENABLE_FIX | I915_INTERRUPT_ENABLE_VAR; |
@@ -1994,7 +1994,7 @@ int i915_driver_irq_postinstall(struct drm_device *dev) | |||
1994 | return 0; | 1994 | return 0; |
1995 | } | 1995 | } |
1996 | 1996 | ||
1997 | void ironlake_irq_uninstall(struct drm_device *dev) | 1997 | static void ironlake_irq_uninstall(struct drm_device *dev) |
1998 | { | 1998 | { |
1999 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 1999 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2000 | 2000 | ||
@@ -2014,7 +2014,7 @@ void ironlake_irq_uninstall(struct drm_device *dev) | |||
2014 | I915_WRITE(GTIIR, I915_READ(GTIIR)); | 2014 | I915_WRITE(GTIIR, I915_READ(GTIIR)); |
2015 | } | 2015 | } |
2016 | 2016 | ||
2017 | void i915_driver_irq_uninstall(struct drm_device * dev) | 2017 | static void i915_driver_irq_uninstall(struct drm_device * dev) |
2018 | { | 2018 | { |
2019 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; | 2019 | drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private; |
2020 | int pipe; | 2020 | int pipe; |
@@ -2040,3 +2040,41 @@ void i915_driver_irq_uninstall(struct drm_device * dev) | |||
2040 | I915_READ(PIPESTAT(pipe)) & 0x8000ffff); | 2040 | I915_READ(PIPESTAT(pipe)) & 0x8000ffff); |
2041 | I915_WRITE(IIR, I915_READ(IIR)); | 2041 | I915_WRITE(IIR, I915_READ(IIR)); |
2042 | } | 2042 | } |
2043 | |||
2044 | void intel_irq_init(struct drm_device *dev) | ||
2045 | { | ||
2046 | dev->driver->get_vblank_counter = i915_get_vblank_counter; | ||
2047 | dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */ | ||
2048 | if (IS_G4X(dev) || IS_GEN5(dev) || IS_GEN6(dev) || IS_IVYBRIDGE(dev)) { | ||
2049 | dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */ | ||
2050 | dev->driver->get_vblank_counter = gm45_get_vblank_counter; | ||
2051 | } | ||
2052 | |||
2053 | |||
2054 | dev->driver->get_vblank_timestamp = i915_get_vblank_timestamp; | ||
2055 | dev->driver->get_scanout_position = i915_get_crtc_scanoutpos; | ||
2056 | |||
2057 | if (IS_IVYBRIDGE(dev)) { | ||
2058 | /* Share pre & uninstall handlers with ILK/SNB */ | ||
2059 | dev->driver->irq_handler = ivybridge_irq_handler; | ||
2060 | dev->driver->irq_preinstall = ironlake_irq_preinstall; | ||
2061 | dev->driver->irq_postinstall = ivybridge_irq_postinstall; | ||
2062 | dev->driver->irq_uninstall = ironlake_irq_uninstall; | ||
2063 | dev->driver->enable_vblank = ivybridge_enable_vblank; | ||
2064 | dev->driver->disable_vblank = ivybridge_disable_vblank; | ||
2065 | } else if (HAS_PCH_SPLIT(dev)) { | ||
2066 | dev->driver->irq_handler = ironlake_irq_handler; | ||
2067 | dev->driver->irq_preinstall = ironlake_irq_preinstall; | ||
2068 | dev->driver->irq_postinstall = ironlake_irq_postinstall; | ||
2069 | dev->driver->irq_uninstall = ironlake_irq_uninstall; | ||
2070 | dev->driver->enable_vblank = ironlake_enable_vblank; | ||
2071 | dev->driver->disable_vblank = ironlake_disable_vblank; | ||
2072 | } else { | ||
2073 | dev->driver->irq_preinstall = i915_driver_irq_preinstall; | ||
2074 | dev->driver->irq_postinstall = i915_driver_irq_postinstall; | ||
2075 | dev->driver->irq_uninstall = i915_driver_irq_uninstall; | ||
2076 | dev->driver->irq_handler = i915_driver_irq_handler; | ||
2077 | dev->driver->enable_vblank = i915_enable_vblank; | ||
2078 | dev->driver->disable_vblank = i915_disable_vblank; | ||
2079 | } | ||
2080 | } | ||
diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c index e8152d23d5b6..5257cfc34c35 100644 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ b/drivers/gpu/drm/i915/i915_suspend.c | |||
@@ -597,7 +597,7 @@ static void i915_restore_modeset_reg(struct drm_device *dev) | |||
597 | return; | 597 | return; |
598 | } | 598 | } |
599 | 599 | ||
600 | void i915_save_display(struct drm_device *dev) | 600 | static void i915_save_display(struct drm_device *dev) |
601 | { | 601 | { |
602 | struct drm_i915_private *dev_priv = dev->dev_private; | 602 | struct drm_i915_private *dev_priv = dev->dev_private; |
603 | 603 | ||
@@ -678,7 +678,6 @@ void i915_save_display(struct drm_device *dev) | |||
678 | } | 678 | } |
679 | 679 | ||
680 | /* VGA state */ | 680 | /* VGA state */ |
681 | mutex_lock(&dev->struct_mutex); | ||
682 | dev_priv->saveVGA0 = I915_READ(VGA0); | 681 | dev_priv->saveVGA0 = I915_READ(VGA0); |
683 | dev_priv->saveVGA1 = I915_READ(VGA1); | 682 | dev_priv->saveVGA1 = I915_READ(VGA1); |
684 | dev_priv->saveVGA_PD = I915_READ(VGA_PD); | 683 | dev_priv->saveVGA_PD = I915_READ(VGA_PD); |
@@ -688,10 +687,9 @@ void i915_save_display(struct drm_device *dev) | |||
688 | dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); | 687 | dev_priv->saveVGACNTRL = I915_READ(VGACNTRL); |
689 | 688 | ||
690 | i915_save_vga(dev); | 689 | i915_save_vga(dev); |
691 | mutex_unlock(&dev->struct_mutex); | ||
692 | } | 690 | } |
693 | 691 | ||
694 | void i915_restore_display(struct drm_device *dev) | 692 | static void i915_restore_display(struct drm_device *dev) |
695 | { | 693 | { |
696 | struct drm_i915_private *dev_priv = dev->dev_private; | 694 | struct drm_i915_private *dev_priv = dev->dev_private; |
697 | 695 | ||
@@ -783,7 +781,6 @@ void i915_restore_display(struct drm_device *dev) | |||
783 | else | 781 | else |
784 | I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); | 782 | I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL); |
785 | 783 | ||
786 | mutex_lock(&dev->struct_mutex); | ||
787 | I915_WRITE(VGA0, dev_priv->saveVGA0); | 784 | I915_WRITE(VGA0, dev_priv->saveVGA0); |
788 | I915_WRITE(VGA1, dev_priv->saveVGA1); | 785 | I915_WRITE(VGA1, dev_priv->saveVGA1); |
789 | I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); | 786 | I915_WRITE(VGA_PD, dev_priv->saveVGA_PD); |
@@ -791,7 +788,6 @@ void i915_restore_display(struct drm_device *dev) | |||
791 | udelay(150); | 788 | udelay(150); |
792 | 789 | ||
793 | i915_restore_vga(dev); | 790 | i915_restore_vga(dev); |
794 | mutex_unlock(&dev->struct_mutex); | ||
795 | } | 791 | } |
796 | 792 | ||
797 | int i915_save_state(struct drm_device *dev) | 793 | int i915_save_state(struct drm_device *dev) |
@@ -801,6 +797,8 @@ int i915_save_state(struct drm_device *dev) | |||
801 | 797 | ||
802 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); | 798 | pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB); |
803 | 799 | ||
800 | mutex_lock(&dev->struct_mutex); | ||
801 | |||
804 | /* Hardware status page */ | 802 | /* Hardware status page */ |
805 | dev_priv->saveHWS = I915_READ(HWS_PGA); | 803 | dev_priv->saveHWS = I915_READ(HWS_PGA); |
806 | 804 | ||
@@ -840,6 +838,8 @@ int i915_save_state(struct drm_device *dev) | |||
840 | for (i = 0; i < 3; i++) | 838 | for (i = 0; i < 3; i++) |
841 | dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); | 839 | dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2)); |
842 | 840 | ||
841 | mutex_unlock(&dev->struct_mutex); | ||
842 | |||
843 | return 0; | 843 | return 0; |
844 | } | 844 | } |
845 | 845 | ||
@@ -850,6 +850,8 @@ int i915_restore_state(struct drm_device *dev) | |||
850 | 850 | ||
851 | pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); | 851 | pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB); |
852 | 852 | ||
853 | mutex_lock(&dev->struct_mutex); | ||
854 | |||
853 | /* Hardware status page */ | 855 | /* Hardware status page */ |
854 | I915_WRITE(HWS_PGA, dev_priv->saveHWS); | 856 | I915_WRITE(HWS_PGA, dev_priv->saveHWS); |
855 | 857 | ||
@@ -867,6 +869,7 @@ int i915_restore_state(struct drm_device *dev) | |||
867 | I915_WRITE(IER, dev_priv->saveIER); | 869 | I915_WRITE(IER, dev_priv->saveIER); |
868 | I915_WRITE(IMR, dev_priv->saveIMR); | 870 | I915_WRITE(IMR, dev_priv->saveIMR); |
869 | } | 871 | } |
872 | mutex_unlock(&dev->struct_mutex); | ||
870 | 873 | ||
871 | intel_init_clock_gating(dev); | 874 | intel_init_clock_gating(dev); |
872 | 875 | ||
@@ -878,6 +881,8 @@ int i915_restore_state(struct drm_device *dev) | |||
878 | if (IS_GEN6(dev)) | 881 | if (IS_GEN6(dev)) |
879 | gen6_enable_rps(dev_priv); | 882 | gen6_enable_rps(dev_priv); |
880 | 883 | ||
884 | mutex_lock(&dev->struct_mutex); | ||
885 | |||
881 | /* Cache mode state */ | 886 | /* Cache mode state */ |
882 | I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); | 887 | I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000); |
883 | 888 | ||
@@ -891,6 +896,8 @@ int i915_restore_state(struct drm_device *dev) | |||
891 | for (i = 0; i < 3; i++) | 896 | for (i = 0; i < 3; i++) |
892 | I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); | 897 | I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]); |
893 | 898 | ||
899 | mutex_unlock(&dev->struct_mutex); | ||
900 | |||
894 | intel_i2c_reset(dev); | 901 | intel_i2c_reset(dev); |
895 | 902 | ||
896 | return 0; | 903 | return 0; |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 391b55f1cc74..e2aced6eec4c 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -50,7 +50,6 @@ struct intel_dp { | |||
50 | bool has_audio; | 50 | bool has_audio; |
51 | int force_audio; | 51 | int force_audio; |
52 | uint32_t color_range; | 52 | uint32_t color_range; |
53 | int dpms_mode; | ||
54 | uint8_t link_bw; | 53 | uint8_t link_bw; |
55 | uint8_t lane_count; | 54 | uint8_t lane_count; |
56 | uint8_t dpcd[4]; | 55 | uint8_t dpcd[4]; |
@@ -138,8 +137,8 @@ intel_dp_max_lane_count(struct intel_dp *intel_dp) | |||
138 | { | 137 | { |
139 | int max_lane_count = 4; | 138 | int max_lane_count = 4; |
140 | 139 | ||
141 | if (intel_dp->dpcd[0] >= 0x11) { | 140 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) { |
142 | max_lane_count = intel_dp->dpcd[2] & 0x1f; | 141 | max_lane_count = intel_dp->dpcd[DP_MAX_LANE_COUNT] & 0x1f; |
143 | switch (max_lane_count) { | 142 | switch (max_lane_count) { |
144 | case 1: case 2: case 4: | 143 | case 1: case 2: case 4: |
145 | break; | 144 | break; |
@@ -153,7 +152,7 @@ intel_dp_max_lane_count(struct intel_dp *intel_dp) | |||
153 | static int | 152 | static int |
154 | intel_dp_max_link_bw(struct intel_dp *intel_dp) | 153 | intel_dp_max_link_bw(struct intel_dp *intel_dp) |
155 | { | 154 | { |
156 | int max_link_bw = intel_dp->dpcd[1]; | 155 | int max_link_bw = intel_dp->dpcd[DP_MAX_LINK_RATE]; |
157 | 156 | ||
158 | switch (max_link_bw) { | 157 | switch (max_link_bw) { |
159 | case DP_LINK_BW_1_62: | 158 | case DP_LINK_BW_1_62: |
@@ -774,7 +773,8 @@ intel_dp_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, | |||
774 | /* | 773 | /* |
775 | * Check for DPCD version > 1.1 and enhanced framing support | 774 | * Check for DPCD version > 1.1 and enhanced framing support |
776 | */ | 775 | */ |
777 | if (intel_dp->dpcd[0] >= 0x11 && (intel_dp->dpcd[2] & DP_ENHANCED_FRAME_CAP)) { | 776 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11 && |
777 | (intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_ENHANCED_FRAME_CAP)) { | ||
778 | intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; | 778 | intel_dp->link_configuration[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; |
779 | intel_dp->DP |= DP_ENHANCED_FRAMING; | 779 | intel_dp->DP |= DP_ENHANCED_FRAMING; |
780 | } | 780 | } |
@@ -942,11 +942,44 @@ static void ironlake_edp_pll_off(struct drm_encoder *encoder) | |||
942 | udelay(200); | 942 | udelay(200); |
943 | } | 943 | } |
944 | 944 | ||
945 | /* If the sink supports it, try to set the power state appropriately */ | ||
946 | static void intel_dp_sink_dpms(struct intel_dp *intel_dp, int mode) | ||
947 | { | ||
948 | int ret, i; | ||
949 | |||
950 | /* Should have a valid DPCD by this point */ | ||
951 | if (intel_dp->dpcd[DP_DPCD_REV] < 0x11) | ||
952 | return; | ||
953 | |||
954 | if (mode != DRM_MODE_DPMS_ON) { | ||
955 | ret = intel_dp_aux_native_write_1(intel_dp, DP_SET_POWER, | ||
956 | DP_SET_POWER_D3); | ||
957 | if (ret != 1) | ||
958 | DRM_DEBUG_DRIVER("failed to write sink power state\n"); | ||
959 | } else { | ||
960 | /* | ||
961 | * When turning on, we need to retry for 1ms to give the sink | ||
962 | * time to wake up. | ||
963 | */ | ||
964 | for (i = 0; i < 3; i++) { | ||
965 | ret = intel_dp_aux_native_write_1(intel_dp, | ||
966 | DP_SET_POWER, | ||
967 | DP_SET_POWER_D0); | ||
968 | if (ret == 1) | ||
969 | break; | ||
970 | msleep(1); | ||
971 | } | ||
972 | } | ||
973 | } | ||
974 | |||
945 | static void intel_dp_prepare(struct drm_encoder *encoder) | 975 | static void intel_dp_prepare(struct drm_encoder *encoder) |
946 | { | 976 | { |
947 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); | 977 | struct intel_dp *intel_dp = enc_to_intel_dp(encoder); |
948 | struct drm_device *dev = encoder->dev; | 978 | struct drm_device *dev = encoder->dev; |
949 | 979 | ||
980 | /* Wake up the sink first */ | ||
981 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); | ||
982 | |||
950 | if (is_edp(intel_dp)) { | 983 | if (is_edp(intel_dp)) { |
951 | ironlake_edp_backlight_off(dev); | 984 | ironlake_edp_backlight_off(dev); |
952 | ironlake_edp_panel_off(dev); | 985 | ironlake_edp_panel_off(dev); |
@@ -990,6 +1023,7 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
990 | if (mode != DRM_MODE_DPMS_ON) { | 1023 | if (mode != DRM_MODE_DPMS_ON) { |
991 | if (is_edp(intel_dp)) | 1024 | if (is_edp(intel_dp)) |
992 | ironlake_edp_backlight_off(dev); | 1025 | ironlake_edp_backlight_off(dev); |
1026 | intel_dp_sink_dpms(intel_dp, mode); | ||
993 | intel_dp_link_down(intel_dp); | 1027 | intel_dp_link_down(intel_dp); |
994 | if (is_edp(intel_dp)) | 1028 | if (is_edp(intel_dp)) |
995 | ironlake_edp_panel_off(dev); | 1029 | ironlake_edp_panel_off(dev); |
@@ -998,6 +1032,7 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
998 | } else { | 1032 | } else { |
999 | if (is_edp(intel_dp)) | 1033 | if (is_edp(intel_dp)) |
1000 | ironlake_edp_panel_vdd_on(intel_dp); | 1034 | ironlake_edp_panel_vdd_on(intel_dp); |
1035 | intel_dp_sink_dpms(intel_dp, mode); | ||
1001 | if (!(dp_reg & DP_PORT_EN)) { | 1036 | if (!(dp_reg & DP_PORT_EN)) { |
1002 | intel_dp_start_link_train(intel_dp); | 1037 | intel_dp_start_link_train(intel_dp); |
1003 | if (is_edp(intel_dp)) { | 1038 | if (is_edp(intel_dp)) { |
@@ -1009,7 +1044,31 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
1009 | if (is_edp(intel_dp)) | 1044 | if (is_edp(intel_dp)) |
1010 | ironlake_edp_backlight_on(dev); | 1045 | ironlake_edp_backlight_on(dev); |
1011 | } | 1046 | } |
1012 | intel_dp->dpms_mode = mode; | 1047 | } |
1048 | |||
1049 | /* | ||
1050 | * Native read with retry for link status and receiver capability reads for | ||
1051 | * cases where the sink may still be asleep. | ||
1052 | */ | ||
1053 | static bool | ||
1054 | intel_dp_aux_native_read_retry(struct intel_dp *intel_dp, uint16_t address, | ||
1055 | uint8_t *recv, int recv_bytes) | ||
1056 | { | ||
1057 | int ret, i; | ||
1058 | |||
1059 | /* | ||
1060 | * Sinks are *supposed* to come up within 1ms from an off state, | ||
1061 | * but we're also supposed to retry 3 times per the spec. | ||
1062 | */ | ||
1063 | for (i = 0; i < 3; i++) { | ||
1064 | ret = intel_dp_aux_native_read(intel_dp, address, recv, | ||
1065 | recv_bytes); | ||
1066 | if (ret == recv_bytes) | ||
1067 | return true; | ||
1068 | msleep(1); | ||
1069 | } | ||
1070 | |||
1071 | return false; | ||
1013 | } | 1072 | } |
1014 | 1073 | ||
1015 | /* | 1074 | /* |
@@ -1019,14 +1078,10 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
1019 | static bool | 1078 | static bool |
1020 | intel_dp_get_link_status(struct intel_dp *intel_dp) | 1079 | intel_dp_get_link_status(struct intel_dp *intel_dp) |
1021 | { | 1080 | { |
1022 | int ret; | 1081 | return intel_dp_aux_native_read_retry(intel_dp, |
1023 | 1082 | DP_LANE0_1_STATUS, | |
1024 | ret = intel_dp_aux_native_read(intel_dp, | 1083 | intel_dp->link_status, |
1025 | DP_LANE0_1_STATUS, | 1084 | DP_LINK_STATUS_SIZE); |
1026 | intel_dp->link_status, DP_LINK_STATUS_SIZE); | ||
1027 | if (ret != DP_LINK_STATUS_SIZE) | ||
1028 | return false; | ||
1029 | return true; | ||
1030 | } | 1085 | } |
1031 | 1086 | ||
1032 | static uint8_t | 1087 | static uint8_t |
@@ -1515,6 +1570,8 @@ intel_dp_link_down(struct intel_dp *intel_dp) | |||
1515 | static void | 1570 | static void |
1516 | intel_dp_check_link_status(struct intel_dp *intel_dp) | 1571 | intel_dp_check_link_status(struct intel_dp *intel_dp) |
1517 | { | 1572 | { |
1573 | int ret; | ||
1574 | |||
1518 | if (!intel_dp->base.base.crtc) | 1575 | if (!intel_dp->base.base.crtc) |
1519 | return; | 1576 | return; |
1520 | 1577 | ||
@@ -1523,6 +1580,15 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) | |||
1523 | return; | 1580 | return; |
1524 | } | 1581 | } |
1525 | 1582 | ||
1583 | /* Try to read receiver status if the link appears to be up */ | ||
1584 | ret = intel_dp_aux_native_read(intel_dp, | ||
1585 | 0x000, intel_dp->dpcd, | ||
1586 | sizeof (intel_dp->dpcd)); | ||
1587 | if (ret != sizeof(intel_dp->dpcd)) { | ||
1588 | intel_dp_link_down(intel_dp); | ||
1589 | return; | ||
1590 | } | ||
1591 | |||
1526 | if (!intel_channel_eq_ok(intel_dp)) { | 1592 | if (!intel_channel_eq_ok(intel_dp)) { |
1527 | intel_dp_start_link_train(intel_dp); | 1593 | intel_dp_start_link_train(intel_dp); |
1528 | intel_dp_complete_link_train(intel_dp); | 1594 | intel_dp_complete_link_train(intel_dp); |
@@ -1533,6 +1599,7 @@ static enum drm_connector_status | |||
1533 | ironlake_dp_detect(struct intel_dp *intel_dp) | 1599 | ironlake_dp_detect(struct intel_dp *intel_dp) |
1534 | { | 1600 | { |
1535 | enum drm_connector_status status; | 1601 | enum drm_connector_status status; |
1602 | bool ret; | ||
1536 | 1603 | ||
1537 | /* Can't disconnect eDP, but you can close the lid... */ | 1604 | /* Can't disconnect eDP, but you can close the lid... */ |
1538 | if (is_edp(intel_dp)) { | 1605 | if (is_edp(intel_dp)) { |
@@ -1543,13 +1610,11 @@ ironlake_dp_detect(struct intel_dp *intel_dp) | |||
1543 | } | 1610 | } |
1544 | 1611 | ||
1545 | status = connector_status_disconnected; | 1612 | status = connector_status_disconnected; |
1546 | if (intel_dp_aux_native_read(intel_dp, | 1613 | ret = intel_dp_aux_native_read_retry(intel_dp, |
1547 | 0x000, intel_dp->dpcd, | 1614 | 0x000, intel_dp->dpcd, |
1548 | sizeof (intel_dp->dpcd)) | 1615 | sizeof (intel_dp->dpcd)); |
1549 | == sizeof(intel_dp->dpcd)) { | 1616 | if (ret && intel_dp->dpcd[DP_DPCD_REV] != 0) |
1550 | if (intel_dp->dpcd[0] != 0) | 1617 | status = connector_status_connected; |
1551 | status = connector_status_connected; | ||
1552 | } | ||
1553 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0], | 1618 | DRM_DEBUG_KMS("DPCD: %hx%hx%hx%hx\n", intel_dp->dpcd[0], |
1554 | intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]); | 1619 | intel_dp->dpcd[1], intel_dp->dpcd[2], intel_dp->dpcd[3]); |
1555 | return status; | 1620 | return status; |
@@ -1586,7 +1651,7 @@ g4x_dp_detect(struct intel_dp *intel_dp) | |||
1586 | if (intel_dp_aux_native_read(intel_dp, 0x000, intel_dp->dpcd, | 1651 | if (intel_dp_aux_native_read(intel_dp, 0x000, intel_dp->dpcd, |
1587 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) | 1652 | sizeof (intel_dp->dpcd)) == sizeof (intel_dp->dpcd)) |
1588 | { | 1653 | { |
1589 | if (intel_dp->dpcd[0] != 0) | 1654 | if (intel_dp->dpcd[DP_DPCD_REV] != 0) |
1590 | status = connector_status_connected; | 1655 | status = connector_status_connected; |
1591 | } | 1656 | } |
1592 | 1657 | ||
@@ -1790,8 +1855,7 @@ intel_dp_hot_plug(struct intel_encoder *intel_encoder) | |||
1790 | { | 1855 | { |
1791 | struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); | 1856 | struct intel_dp *intel_dp = container_of(intel_encoder, struct intel_dp, base); |
1792 | 1857 | ||
1793 | if (intel_dp->dpms_mode == DRM_MODE_DPMS_ON) | 1858 | intel_dp_check_link_status(intel_dp); |
1794 | intel_dp_check_link_status(intel_dp); | ||
1795 | } | 1859 | } |
1796 | 1860 | ||
1797 | /* Return which DP Port should be selected for Transcoder DP control */ | 1861 | /* Return which DP Port should be selected for Transcoder DP control */ |
@@ -1859,7 +1923,6 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1859 | return; | 1923 | return; |
1860 | 1924 | ||
1861 | intel_dp->output_reg = output_reg; | 1925 | intel_dp->output_reg = output_reg; |
1862 | intel_dp->dpms_mode = -1; | ||
1863 | 1926 | ||
1864 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); | 1927 | intel_connector = kzalloc(sizeof(struct intel_connector), GFP_KERNEL); |
1865 | if (!intel_connector) { | 1928 | if (!intel_connector) { |
@@ -1954,8 +2017,9 @@ intel_dp_init(struct drm_device *dev, int output_reg) | |||
1954 | sizeof(intel_dp->dpcd)); | 2017 | sizeof(intel_dp->dpcd)); |
1955 | ironlake_edp_panel_vdd_off(intel_dp); | 2018 | ironlake_edp_panel_vdd_off(intel_dp); |
1956 | if (ret == sizeof(intel_dp->dpcd)) { | 2019 | if (ret == sizeof(intel_dp->dpcd)) { |
1957 | if (intel_dp->dpcd[0] >= 0x11) | 2020 | if (intel_dp->dpcd[DP_DPCD_REV] >= 0x11) |
1958 | dev_priv->no_aux_handshake = intel_dp->dpcd[3] & | 2021 | dev_priv->no_aux_handshake = |
2022 | intel_dp->dpcd[DP_MAX_DOWNSPREAD] & | ||
1959 | DP_NO_AUX_HANDSHAKE_LINK_TRAINING; | 2023 | DP_NO_AUX_HANDSHAKE_LINK_TRAINING; |
1960 | } else { | 2024 | } else { |
1961 | /* if this fails, presume the device is a ghost */ | 2025 | /* if this fails, presume the device is a ghost */ |
diff --git a/drivers/gpu/drm/i915/intel_overlay.c b/drivers/gpu/drm/i915/intel_overlay.c index 56a8e2aea19c..9e2959bc91cd 100644 --- a/drivers/gpu/drm/i915/intel_overlay.c +++ b/drivers/gpu/drm/i915/intel_overlay.c | |||
@@ -1409,6 +1409,11 @@ void intel_setup_overlay(struct drm_device *dev) | |||
1409 | overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL); | 1409 | overlay = kzalloc(sizeof(struct intel_overlay), GFP_KERNEL); |
1410 | if (!overlay) | 1410 | if (!overlay) |
1411 | return; | 1411 | return; |
1412 | |||
1413 | mutex_lock(&dev->struct_mutex); | ||
1414 | if (WARN_ON(dev_priv->overlay)) | ||
1415 | goto out_free; | ||
1416 | |||
1412 | overlay->dev = dev; | 1417 | overlay->dev = dev; |
1413 | 1418 | ||
1414 | reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE); | 1419 | reg_bo = i915_gem_alloc_object(dev, PAGE_SIZE); |
@@ -1416,8 +1421,6 @@ void intel_setup_overlay(struct drm_device *dev) | |||
1416 | goto out_free; | 1421 | goto out_free; |
1417 | overlay->reg_bo = reg_bo; | 1422 | overlay->reg_bo = reg_bo; |
1418 | 1423 | ||
1419 | mutex_lock(&dev->struct_mutex); | ||
1420 | |||
1421 | if (OVERLAY_NEEDS_PHYSICAL(dev)) { | 1424 | if (OVERLAY_NEEDS_PHYSICAL(dev)) { |
1422 | ret = i915_gem_attach_phys_object(dev, reg_bo, | 1425 | ret = i915_gem_attach_phys_object(dev, reg_bo, |
1423 | I915_GEM_PHYS_OVERLAY_REGS, | 1426 | I915_GEM_PHYS_OVERLAY_REGS, |
@@ -1442,8 +1445,6 @@ void intel_setup_overlay(struct drm_device *dev) | |||
1442 | } | 1445 | } |
1443 | } | 1446 | } |
1444 | 1447 | ||
1445 | mutex_unlock(&dev->struct_mutex); | ||
1446 | |||
1447 | /* init all values */ | 1448 | /* init all values */ |
1448 | overlay->color_key = 0x0101fe; | 1449 | overlay->color_key = 0x0101fe; |
1449 | overlay->brightness = -19; | 1450 | overlay->brightness = -19; |
@@ -1452,7 +1453,7 @@ void intel_setup_overlay(struct drm_device *dev) | |||
1452 | 1453 | ||
1453 | regs = intel_overlay_map_regs(overlay); | 1454 | regs = intel_overlay_map_regs(overlay); |
1454 | if (!regs) | 1455 | if (!regs) |
1455 | goto out_free_bo; | 1456 | goto out_unpin_bo; |
1456 | 1457 | ||
1457 | memset(regs, 0, sizeof(struct overlay_registers)); | 1458 | memset(regs, 0, sizeof(struct overlay_registers)); |
1458 | update_polyphase_filter(regs); | 1459 | update_polyphase_filter(regs); |
@@ -1461,15 +1462,17 @@ void intel_setup_overlay(struct drm_device *dev) | |||
1461 | intel_overlay_unmap_regs(overlay, regs); | 1462 | intel_overlay_unmap_regs(overlay, regs); |
1462 | 1463 | ||
1463 | dev_priv->overlay = overlay; | 1464 | dev_priv->overlay = overlay; |
1465 | mutex_unlock(&dev->struct_mutex); | ||
1464 | DRM_INFO("initialized overlay support\n"); | 1466 | DRM_INFO("initialized overlay support\n"); |
1465 | return; | 1467 | return; |
1466 | 1468 | ||
1467 | out_unpin_bo: | 1469 | out_unpin_bo: |
1468 | i915_gem_object_unpin(reg_bo); | 1470 | if (!OVERLAY_NEEDS_PHYSICAL(dev)) |
1471 | i915_gem_object_unpin(reg_bo); | ||
1469 | out_free_bo: | 1472 | out_free_bo: |
1470 | drm_gem_object_unreference(®_bo->base); | 1473 | drm_gem_object_unreference(®_bo->base); |
1471 | mutex_unlock(&dev->struct_mutex); | ||
1472 | out_free: | 1474 | out_free: |
1475 | mutex_unlock(&dev->struct_mutex); | ||
1473 | kfree(overlay); | 1476 | kfree(overlay); |
1474 | return; | 1477 | return; |
1475 | } | 1478 | } |
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.h b/drivers/gpu/drm/i915/intel_ringbuffer.h index c0e0ee63fbf4..39ac2b634ae5 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.h +++ b/drivers/gpu/drm/i915/intel_ringbuffer.h | |||
@@ -165,7 +165,7 @@ void intel_cleanup_ring_buffer(struct intel_ring_buffer *ring); | |||
165 | int __must_check intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n); | 165 | int __must_check intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n); |
166 | static inline int intel_wait_ring_idle(struct intel_ring_buffer *ring) | 166 | static inline int intel_wait_ring_idle(struct intel_ring_buffer *ring) |
167 | { | 167 | { |
168 | return intel_wait_ring_buffer(ring, ring->space - 8); | 168 | return intel_wait_ring_buffer(ring, ring->size - 8); |
169 | } | 169 | } |
170 | 170 | ||
171 | int __must_check intel_ring_begin(struct intel_ring_buffer *ring, int n); | 171 | int __must_check intel_ring_begin(struct intel_ring_buffer *ring, int n); |