aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
authorVille Syrjälä <ville.syrjala@linux.intel.com>2014-11-24 11:28:11 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2014-12-03 03:29:38 -0500
commit7514747d27632f2d71dd2f1e6abd6e0451dcbf3f (patch)
treea8af68e60bd807b19b7e090fa26743ce3e0092a7 /drivers/gpu/drm/i915/intel_display.c
parent408d4b9e1f0159583e81e093b3e7fe12a9b1072f (diff)
drm/i915: Grab modeset locks for GPU rest on pre-ctg
On gen4 and earlier the GPU reset also resets the display, so we should protect against concurrent modeset operations. Grab all the modeset locks around the entire GPU reset dance, remebering first ti dislogde any pending page flip to make sure we don't deadlock. Any pageflip coming in between these two steps should fail anyway due to reset_in_progress, so this should be safe. This fixes a lot of failed asserts in the modeset code when there's a modeset racing with the reset. Naturally the asserts aren't happy when the expected state has disappeared. v2: Drop UMS checks, complete pending flips after the reset (Daniel) Cc: Daniel Vetter <daniel@ffwll.ch> Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c84
1 files changed, 68 insertions, 16 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 3218455a7ade..56664e63e10f 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2765,25 +2765,10 @@ intel_pipe_set_base_atomic(struct drm_crtc *crtc, struct drm_framebuffer *fb,
2765 return 0; 2765 return 0;
2766} 2766}
2767 2767
2768void intel_display_handle_reset(struct drm_device *dev) 2768static void intel_complete_page_flips(struct drm_device *dev)
2769{ 2769{
2770 struct drm_i915_private *dev_priv = dev->dev_private;
2771 struct drm_crtc *crtc; 2770 struct drm_crtc *crtc;
2772 2771
2773 /*
2774 * Flips in the rings have been nuked by the reset,
2775 * so complete all pending flips so that user space
2776 * will get its events and not get stuck.
2777 *
2778 * Also update the base address of all primary
2779 * planes to the the last fb to make sure we're
2780 * showing the correct fb after a reset.
2781 *
2782 * Need to make two loops over the crtcs so that we
2783 * don't try to grab a crtc mutex before the
2784 * pending_flip_queue really got woken up.
2785 */
2786
2787 for_each_crtc(dev, crtc) { 2772 for_each_crtc(dev, crtc) {
2788 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 2773 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
2789 enum plane plane = intel_crtc->plane; 2774 enum plane plane = intel_crtc->plane;
@@ -2791,6 +2776,12 @@ void intel_display_handle_reset(struct drm_device *dev)
2791 intel_prepare_page_flip(dev, plane); 2776 intel_prepare_page_flip(dev, plane);
2792 intel_finish_page_flip_plane(dev, plane); 2777 intel_finish_page_flip_plane(dev, plane);
2793 } 2778 }
2779}
2780
2781static void intel_update_primary_planes(struct drm_device *dev)
2782{
2783 struct drm_i915_private *dev_priv = dev->dev_private;
2784 struct drm_crtc *crtc;
2794 2785
2795 for_each_crtc(dev, crtc) { 2786 for_each_crtc(dev, crtc) {
2796 struct intel_crtc *intel_crtc = to_intel_crtc(crtc); 2787 struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
@@ -2810,6 +2801,67 @@ void intel_display_handle_reset(struct drm_device *dev)
2810 } 2801 }
2811} 2802}
2812 2803
2804void intel_prepare_reset(struct drm_device *dev)
2805{
2806 /* no reset support for gen2 */
2807 if (IS_GEN2(dev))
2808 return;
2809
2810 /* reset doesn't touch the display */
2811 if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev))
2812 return;
2813
2814 drm_modeset_lock_all(dev);
2815}
2816
2817void intel_finish_reset(struct drm_device *dev)
2818{
2819 struct drm_i915_private *dev_priv = to_i915(dev);
2820
2821 /*
2822 * Flips in the rings will be nuked by the reset,
2823 * so complete all pending flips so that user space
2824 * will get its events and not get stuck.
2825 */
2826 intel_complete_page_flips(dev);
2827
2828 /* no reset support for gen2 */
2829 if (IS_GEN2(dev))
2830 return;
2831
2832 /* reset doesn't touch the display */
2833 if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev)) {
2834 /*
2835 * Flips in the rings have been nuked by the reset,
2836 * so update the base address of all primary
2837 * planes to the the last fb to make sure we're
2838 * showing the correct fb after a reset.
2839 */
2840 intel_update_primary_planes(dev);
2841 return;
2842 }
2843
2844 /*
2845 * The display has been reset as well,
2846 * so need a full re-initialization.
2847 */
2848 intel_runtime_pm_disable_interrupts(dev_priv);
2849 intel_runtime_pm_enable_interrupts(dev_priv);
2850
2851 intel_modeset_init_hw(dev);
2852
2853 spin_lock_irq(&dev_priv->irq_lock);
2854 if (dev_priv->display.hpd_irq_setup)
2855 dev_priv->display.hpd_irq_setup(dev);
2856 spin_unlock_irq(&dev_priv->irq_lock);
2857
2858 intel_modeset_setup_hw_state(dev, true);
2859
2860 intel_hpd_init(dev_priv);
2861
2862 drm_modeset_unlock_all(dev);
2863}
2864
2813static int 2865static int
2814intel_finish_fb(struct drm_framebuffer *old_fb) 2866intel_finish_fb(struct drm_framebuffer *old_fb)
2815{ 2867{