diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 151 |
1 files changed, 132 insertions, 19 deletions
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 853697fc4d4b..6289babd03b0 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 | ||
2768 | void intel_display_handle_reset(struct drm_device *dev) | 2768 | static 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 | |||
2781 | static 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,79 @@ void intel_display_handle_reset(struct drm_device *dev) | |||
2810 | } | 2801 | } |
2811 | } | 2802 | } |
2812 | 2803 | ||
2804 | void intel_prepare_reset(struct drm_device *dev) | ||
2805 | { | ||
2806 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
2807 | struct intel_crtc *crtc; | ||
2808 | |||
2809 | /* no reset support for gen2 */ | ||
2810 | if (IS_GEN2(dev)) | ||
2811 | return; | ||
2812 | |||
2813 | /* reset doesn't touch the display */ | ||
2814 | if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev)) | ||
2815 | return; | ||
2816 | |||
2817 | drm_modeset_lock_all(dev); | ||
2818 | |||
2819 | /* | ||
2820 | * Disabling the crtcs gracefully seems nicer. Also the | ||
2821 | * g33 docs say we should at least disable all the planes. | ||
2822 | */ | ||
2823 | for_each_intel_crtc(dev, crtc) { | ||
2824 | if (crtc->active) | ||
2825 | dev_priv->display.crtc_disable(&crtc->base); | ||
2826 | } | ||
2827 | } | ||
2828 | |||
2829 | void intel_finish_reset(struct drm_device *dev) | ||
2830 | { | ||
2831 | struct drm_i915_private *dev_priv = to_i915(dev); | ||
2832 | |||
2833 | /* | ||
2834 | * Flips in the rings will be nuked by the reset, | ||
2835 | * so complete all pending flips so that user space | ||
2836 | * will get its events and not get stuck. | ||
2837 | */ | ||
2838 | intel_complete_page_flips(dev); | ||
2839 | |||
2840 | /* no reset support for gen2 */ | ||
2841 | if (IS_GEN2(dev)) | ||
2842 | return; | ||
2843 | |||
2844 | /* reset doesn't touch the display */ | ||
2845 | if (INTEL_INFO(dev)->gen >= 5 || IS_G4X(dev)) { | ||
2846 | /* | ||
2847 | * Flips in the rings have been nuked by the reset, | ||
2848 | * so update the base address of all primary | ||
2849 | * planes to the the last fb to make sure we're | ||
2850 | * showing the correct fb after a reset. | ||
2851 | */ | ||
2852 | intel_update_primary_planes(dev); | ||
2853 | return; | ||
2854 | } | ||
2855 | |||
2856 | /* | ||
2857 | * The display has been reset as well, | ||
2858 | * so need a full re-initialization. | ||
2859 | */ | ||
2860 | intel_runtime_pm_disable_interrupts(dev_priv); | ||
2861 | intel_runtime_pm_enable_interrupts(dev_priv); | ||
2862 | |||
2863 | intel_modeset_init_hw(dev); | ||
2864 | |||
2865 | spin_lock_irq(&dev_priv->irq_lock); | ||
2866 | if (dev_priv->display.hpd_irq_setup) | ||
2867 | dev_priv->display.hpd_irq_setup(dev); | ||
2868 | spin_unlock_irq(&dev_priv->irq_lock); | ||
2869 | |||
2870 | intel_modeset_setup_hw_state(dev, true); | ||
2871 | |||
2872 | intel_hpd_init(dev_priv); | ||
2873 | |||
2874 | drm_modeset_unlock_all(dev); | ||
2875 | } | ||
2876 | |||
2813 | static int | 2877 | static int |
2814 | intel_finish_fb(struct drm_framebuffer *old_fb) | 2878 | intel_finish_fb(struct drm_framebuffer *old_fb) |
2815 | { | 2879 | { |
@@ -10089,6 +10153,48 @@ static bool check_encoder_cloning(struct intel_crtc *crtc) | |||
10089 | return true; | 10153 | return true; |
10090 | } | 10154 | } |
10091 | 10155 | ||
10156 | static bool check_digital_port_conflicts(struct drm_device *dev) | ||
10157 | { | ||
10158 | struct intel_connector *connector; | ||
10159 | unsigned int used_ports = 0; | ||
10160 | |||
10161 | /* | ||
10162 | * Walk the connector list instead of the encoder | ||
10163 | * list to detect the problem on ddi platforms | ||
10164 | * where there's just one encoder per digital port. | ||
10165 | */ | ||
10166 | list_for_each_entry(connector, | ||
10167 | &dev->mode_config.connector_list, base.head) { | ||
10168 | struct intel_encoder *encoder = connector->new_encoder; | ||
10169 | |||
10170 | if (!encoder) | ||
10171 | continue; | ||
10172 | |||
10173 | WARN_ON(!encoder->new_crtc); | ||
10174 | |||
10175 | switch (encoder->type) { | ||
10176 | unsigned int port_mask; | ||
10177 | case INTEL_OUTPUT_UNKNOWN: | ||
10178 | if (WARN_ON(!HAS_DDI(dev))) | ||
10179 | break; | ||
10180 | case INTEL_OUTPUT_DISPLAYPORT: | ||
10181 | case INTEL_OUTPUT_HDMI: | ||
10182 | case INTEL_OUTPUT_EDP: | ||
10183 | port_mask = 1 << enc_to_dig_port(&encoder->base)->port; | ||
10184 | |||
10185 | /* the same port mustn't appear more than once */ | ||
10186 | if (used_ports & port_mask) | ||
10187 | return false; | ||
10188 | |||
10189 | used_ports |= port_mask; | ||
10190 | default: | ||
10191 | break; | ||
10192 | } | ||
10193 | } | ||
10194 | |||
10195 | return true; | ||
10196 | } | ||
10197 | |||
10092 | static struct intel_crtc_config * | 10198 | static struct intel_crtc_config * |
10093 | intel_modeset_pipe_config(struct drm_crtc *crtc, | 10199 | intel_modeset_pipe_config(struct drm_crtc *crtc, |
10094 | struct drm_framebuffer *fb, | 10200 | struct drm_framebuffer *fb, |
@@ -10105,6 +10211,11 @@ intel_modeset_pipe_config(struct drm_crtc *crtc, | |||
10105 | return ERR_PTR(-EINVAL); | 10211 | return ERR_PTR(-EINVAL); |
10106 | } | 10212 | } |
10107 | 10213 | ||
10214 | if (!check_digital_port_conflicts(dev)) { | ||
10215 | DRM_DEBUG_KMS("rejecting conflicting digital port configuration\n"); | ||
10216 | return ERR_PTR(-EINVAL); | ||
10217 | } | ||
10218 | |||
10108 | pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL); | 10219 | pipe_config = kzalloc(sizeof(*pipe_config), GFP_KERNEL); |
10109 | if (!pipe_config) | 10220 | if (!pipe_config) |
10110 | return ERR_PTR(-ENOMEM); | 10221 | return ERR_PTR(-ENOMEM); |
@@ -10907,7 +11018,6 @@ intel_modeset_compute_config(struct drm_crtc *crtc, | |||
10907 | } | 11018 | } |
10908 | intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config, | 11019 | intel_dump_pipe_config(to_intel_crtc(crtc), pipe_config, |
10909 | "[modeset]"); | 11020 | "[modeset]"); |
10910 | to_intel_crtc(crtc)->new_config = pipe_config; | ||
10911 | 11021 | ||
10912 | out: | 11022 | out: |
10913 | return pipe_config; | 11023 | return pipe_config; |
@@ -10933,6 +11043,9 @@ static int __intel_set_mode(struct drm_crtc *crtc, | |||
10933 | 11043 | ||
10934 | *saved_mode = crtc->mode; | 11044 | *saved_mode = crtc->mode; |
10935 | 11045 | ||
11046 | if (modeset_pipes) | ||
11047 | to_intel_crtc(crtc)->new_config = pipe_config; | ||
11048 | |||
10936 | /* | 11049 | /* |
10937 | * See if the config requires any additional preparation, e.g. | 11050 | * See if the config requires any additional preparation, e.g. |
10938 | * to adjust global state with pipes off. We need to do this | 11051 | * to adjust global state with pipes off. We need to do this |
@@ -11466,12 +11579,12 @@ static int intel_crtc_set_config(struct drm_mode_set *set) | |||
11466 | ret = PTR_ERR(pipe_config); | 11579 | ret = PTR_ERR(pipe_config); |
11467 | goto fail; | 11580 | goto fail; |
11468 | } else if (pipe_config) { | 11581 | } else if (pipe_config) { |
11469 | if (to_intel_crtc(set->crtc)->new_config->has_audio != | 11582 | if (pipe_config->has_audio != |
11470 | to_intel_crtc(set->crtc)->config.has_audio) | 11583 | to_intel_crtc(set->crtc)->config.has_audio) |
11471 | config->mode_changed = true; | 11584 | config->mode_changed = true; |
11472 | 11585 | ||
11473 | /* Force mode sets for any infoframe stuff */ | 11586 | /* Force mode sets for any infoframe stuff */ |
11474 | if (to_intel_crtc(set->crtc)->new_config->has_infoframe || | 11587 | if (pipe_config->has_infoframe || |
11475 | to_intel_crtc(set->crtc)->config.has_infoframe) | 11588 | to_intel_crtc(set->crtc)->config.has_infoframe) |
11476 | config->mode_changed = true; | 11589 | config->mode_changed = true; |
11477 | } | 11590 | } |