aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_display.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/i915/intel_display.c')
-rw-r--r--drivers/gpu/drm/i915/intel_display.c151
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
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,79 @@ 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 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
2829void 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
2813static int 2877static int
2814intel_finish_fb(struct drm_framebuffer *old_fb) 2878intel_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
10156static 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
10092static struct intel_crtc_config * 10198static struct intel_crtc_config *
10093intel_modeset_pipe_config(struct drm_crtc *crtc, 10199intel_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
10912out: 11022out:
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 }