Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel...
authorDave Airlie <airlied@redhat.com>
Tue, 16 Oct 2012 00:11:29 +0000 (10:11 +1000)
committerDave Airlie <airlied@redhat.com>
Tue, 16 Oct 2012 00:11:59 +0000 (10:11 +1000)
Daniel writes:
"- some register magic to fix hsw crw (Paulo&Ben)
- fix backlight destruction for cpu edp (Jani)
- fix gen ch7xxx dvo ->get_hw_state
- fixup the plane->pipe fixup code, the broken version massively angers
  the modeset sanity checks
- kill pipe A quirk for i855gm, otherwise I get a black screen with the
  above patch
- fixup for gem_get_page helper (Chris)
- fixup guardband clipping w/a (Ken), without this mesa master can erronously
  drop vertices on snb, mesa 9.0 has the optimization reverted
- another pageflip vs. modeset fix
- kill bogus BUG_ON which broke ums+gem from Willy Tarreau (gasp, people
  are still using this!)"

* 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel:
  drm/i915: fix non-DP-D eDP backlight cleanup and module reload
  drm/i915: HSW CRW stability magic
  drm/i915/dvo-ch7xxx: fix get_hw_state
  drm/i915: fixup the plane->pipe fixup code
  drm/i915: rip out the pipe A quirk for i855gm
  drm/i915: disable wc gtt pte mappings on gen2
  drm/i915: fixup i915_gem_object_get_page inline helper
  drm/i915: Disallow preallocation of requests
  drm/i915: Set guardband clipping workaround bit in the right register.
  drm/i915: paper over a pipe-enable vs pageflip race
  drm/i915: remove useless BUG_ON which caused a regression in 3.5.

1  2 
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_overlay.c

index 19dbdd7dd5648e93b48062c54fd9bc3f6100e425,bb941f8cd55645adfb37ef10419abf5042d4228c..d33d02d13c9678a7dd64b1fb4c9e9c5f9682d223
@@@ -25,8 -25,9 +25,8 @@@
   *
   */
  
 -#include "drmP.h"
 -#include "drm.h"
 -#include "i915_drm.h"
 +#include <drm/drmP.h>
 +#include <drm/i915_drm.h>
  #include "i915_drv.h"
  #include "i915_trace.h"
  #include "intel_drv.h"
@@@ -1955,11 -1956,12 +1955,12 @@@ i915_gem_next_request_seqno(struct inte
  int
  i915_add_request(struct intel_ring_buffer *ring,
                 struct drm_file *file,
-                struct drm_i915_gem_request *request)
+                u32 *out_seqno)
  {
        drm_i915_private_t *dev_priv = ring->dev->dev_private;
-       uint32_t seqno;
+       struct drm_i915_gem_request *request;
        u32 request_ring_position;
+       u32 seqno;
        int was_empty;
        int ret;
  
        if (ret)
                return ret;
  
-       if (request == NULL) {
-               request = kmalloc(sizeof(*request), GFP_KERNEL);
-               if (request == NULL)
-                       return -ENOMEM;
-       }
+       request = kmalloc(sizeof(*request), GFP_KERNEL);
+       if (request == NULL)
+               return -ENOMEM;
  
        seqno = i915_gem_next_request_seqno(ring);
  
                }
        }
  
+       if (out_seqno)
+               *out_seqno = seqno;
        return 0;
  }
  
@@@ -3959,6 -3961,9 +3960,9 @@@ i915_gem_init_hw(struct drm_device *dev
        if (!intel_enable_gtt())
                return -EIO;
  
+       if (IS_HASWELL(dev) && (I915_READ(0x120010) == 1))
+               I915_WRITE(0x9008, I915_READ(0x9008) | 0xf0000);
        i915_gem_l3_remap(dev);
  
        i915_gem_init_swizzling(dev);
@@@ -4098,7 -4103,6 +4102,6 @@@ i915_gem_entervt_ioctl(struct drm_devic
        }
  
        BUG_ON(!list_empty(&dev_priv->mm.active_list));
-       BUG_ON(!list_empty(&dev_priv->mm.inactive_list));
        mutex_unlock(&dev->struct_mutex);
  
        ret = drm_irq_install(dev);
index 2b6ce9b2674a9d899dd34a6e2b6e2622dc08c631,3511effa01ec534e6adb105c7d4ec22f424ef8c1..682bd3729baf62369fc66d23434f058a643ffc78
  #include <linux/slab.h>
  #include <linux/vgaarb.h>
  #include <drm/drm_edid.h>
 -#include "drmP.h"
 +#include <drm/drmP.h>
  #include "intel_drv.h"
 -#include "i915_drm.h"
 +#include <drm/i915_drm.h>
  #include "i915_drv.h"
  #include "i915_trace.h"
 -#include "drm_dp_helper.h"
 -#include "drm_crtc_helper.h"
 +#include <drm/drm_dp_helper.h>
 +#include <drm/drm_crtc_helper.h>
  #include <linux/dma_remapping.h>
  
  #define HAS_eDP (intel_pipe_has_type(crtc, INTEL_OUTPUT_EDP))
@@@ -3253,6 -3253,16 +3253,16 @@@ static void ironlake_crtc_enable(struc
  
        if (HAS_PCH_CPT(dev))
                intel_cpt_verify_modeset(dev, intel_crtc->pipe);
+       /*
+        * There seems to be a race in PCH platform hw (at least on some
+        * outputs) where an enabled pipe still completes any pageflip right
+        * away (as if the pipe is off) instead of waiting for vblank. As soon
+        * as the first vblank happend, everything works as expected. Hence just
+        * wait for one vblank before returning to avoid strange things
+        * happening.
+        */
+       intel_wait_for_vblank(dev, intel_crtc->pipe);
  }
  
  static void ironlake_crtc_disable(struct drm_crtc *crtc)
@@@ -7892,8 -7902,7 +7902,7 @@@ static struct intel_quirk intel_quirks[
        /* ThinkPad T60 needs pipe A force quirk (bug #16494) */
        { 0x2782, 0x17aa, 0x201a, quirk_pipea_force },
  
-       /* 855 & before need to leave pipe A & dpll A up */
-       { 0x3582, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
+       /* 830/845 need to leave pipe A & dpll A up */
        { 0x2562, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
        { 0x3577, PCI_ANY_ID, PCI_ANY_ID, quirk_pipea_force },
  
@@@ -8049,29 -8058,42 +8058,42 @@@ static void intel_enable_pipe_a(struct 
  
  }
  
+ static bool
+ intel_check_plane_mapping(struct intel_crtc *crtc)
+ {
+       struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
+       u32 reg, val;
+       if (dev_priv->num_pipe == 1)
+               return true;
+       reg = DSPCNTR(!crtc->plane);
+       val = I915_READ(reg);
+       if ((val & DISPLAY_PLANE_ENABLE) &&
+           (!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe))
+               return false;
+       return true;
+ }
  static void intel_sanitize_crtc(struct intel_crtc *crtc)
  {
        struct drm_device *dev = crtc->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       u32 reg, val;
+       u32 reg;
  
        /* Clear any frame start delays used for debugging left by the BIOS */
        reg = PIPECONF(crtc->pipe);
        I915_WRITE(reg, I915_READ(reg) & ~PIPECONF_FRAME_START_DELAY_MASK);
  
        /* We need to sanitize the plane -> pipe mapping first because this will
-        * disable the crtc (and hence change the state) if it is wrong. */
-       if (!HAS_PCH_SPLIT(dev)) {
+        * disable the crtc (and hence change the state) if it is wrong. Note
+        * that gen4+ has a fixed plane -> pipe mapping.  */
+       if (INTEL_INFO(dev)->gen < 4 && !intel_check_plane_mapping(crtc)) {
                struct intel_connector *connector;
                bool plane;
  
-               reg = DSPCNTR(crtc->plane);
-               val = I915_READ(reg);
-               if ((val & DISPLAY_PLANE_ENABLE) == 0 &&
-                   (!!(val & DISPPLANE_SEL_PIPE_MASK) == crtc->pipe))
-                       goto ok;
                DRM_DEBUG_KMS("[CRTC:%d] wrong plane connection detected!\n",
                              crtc->base.base.id);
  
                WARN_ON(crtc->active);
                crtc->base.enabled = false;
        }
- ok:
  
        if (dev_priv->quirks & QUIRK_PIPEA_FORCE &&
            crtc->pipe == PIPE_A && !crtc->active) {
index d1e8ddb2d6c0801e42a25c30e1eb66c29fb80150,bd2c34a0aa9ae266dc21cd8ff2839febaf5037e2..1b727a5c9ee5680364343be93e15203df42e2369
  #include <linux/i2c.h>
  #include <linux/slab.h>
  #include <linux/export.h>
 -#include "drmP.h"
 -#include "drm.h"
 -#include "drm_crtc.h"
 -#include "drm_crtc_helper.h"
 -#include "drm_edid.h"
 +#include <drm/drmP.h>
 +#include <drm/drm_crtc.h>
 +#include <drm/drm_crtc_helper.h>
 +#include <drm/drm_edid.h>
  #include "intel_drv.h"
 -#include "i915_drm.h"
 +#include <drm/i915_drm.h>
  #include "i915_drv.h"
  
  #define DP_RECEIVER_CAP_SIZE  0xf
@@@ -2369,8 -2370,9 +2369,9 @@@ static voi
  intel_dp_destroy(struct drm_connector *connector)
  {
        struct drm_device *dev = connector->dev;
+       struct intel_dp *intel_dp = intel_attached_dp(connector);
  
-       if (intel_dpd_is_edp(dev))
+       if (is_edp(intel_dp))
                intel_panel_destroy_backlight(dev);
  
        drm_sysfs_connector_remove(connector);
index ebff850a9ab6ff8f7b35c17fced205be45d84205,555912f510a92b2011fa00ce7d16fd31be5d03c7..495625914e4a084f01f476d93524bed83db7ac42
@@@ -25,8 -25,9 +25,8 @@@
   *
   * Derived from Xorg ddx, xf86-video-intel, src/i830_video.c
   */
 -#include "drmP.h"
 -#include "drm.h"
 -#include "i915_drm.h"
 +#include <drm/drmP.h>
 +#include <drm/i915_drm.h>
  #include "i915_drv.h"
  #include "i915_reg.h"
  #include "intel_drv.h"
@@@ -209,7 -210,6 +209,6 @@@ static void intel_overlay_unmap_regs(st
  }
  
  static int intel_overlay_do_wait_request(struct intel_overlay *overlay,
-                                        struct drm_i915_gem_request *request,
                                         void (*tail)(struct intel_overlay *))
  {
        struct drm_device *dev = overlay->dev;
        int ret;
  
        BUG_ON(overlay->last_flip_req);
-       ret = i915_add_request(ring, NULL, request);
-       if (ret) {
-           kfree(request);
-           return ret;
-       }
-       overlay->last_flip_req = request->seqno;
+       ret = i915_add_request(ring, NULL, &overlay->last_flip_req);
+       if (ret)
+               return ret;
        overlay->flip_tail = tail;
        ret = i915_wait_seqno(ring, overlay->last_flip_req);
        if (ret)
@@@ -240,7 -238,6 +237,6 @@@ static int intel_overlay_on(struct inte
        struct drm_device *dev = overlay->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
-       struct drm_i915_gem_request *request;
        int ret;
  
        BUG_ON(overlay->active);
  
        WARN_ON(IS_I830(dev) && !(dev_priv->quirks & QUIRK_PIPEA_FORCE));
  
-       request = kzalloc(sizeof(*request), GFP_KERNEL);
-       if (request == NULL) {
-               ret = -ENOMEM;
-               goto out;
-       }
        ret = intel_ring_begin(ring, 4);
-       if (ret) {
-               kfree(request);
-               goto out;
-       }
+       if (ret)
+               return ret;
  
        intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_ON);
        intel_ring_emit(ring, overlay->flip_addr | OFC_UPDATE);
        intel_ring_emit(ring, MI_NOOP);
        intel_ring_advance(ring);
  
-       ret = intel_overlay_do_wait_request(overlay, request, NULL);
- out:
-       return ret;
+       return intel_overlay_do_wait_request(overlay, NULL);
  }
  
  /* overlay needs to be enabled in OCMD reg */
@@@ -278,17 -265,12 +264,12 @@@ static int intel_overlay_continue(struc
        struct drm_device *dev = overlay->dev;
        drm_i915_private_t *dev_priv = dev->dev_private;
        struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
-       struct drm_i915_gem_request *request;
        u32 flip_addr = overlay->flip_addr;
        u32 tmp;
        int ret;
  
        BUG_ON(!overlay->active);
  
-       request = kzalloc(sizeof(*request), GFP_KERNEL);
-       if (request == NULL)
-               return -ENOMEM;
        if (load_polyphase_filter)
                flip_addr |= OFC_UPDATE;
  
                DRM_DEBUG("overlay underrun, DOVSTA: %x\n", tmp);
  
        ret = intel_ring_begin(ring, 2);
-       if (ret) {
-               kfree(request);
+       if (ret)
                return ret;
-       }
        intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
        intel_ring_emit(ring, flip_addr);
        intel_ring_advance(ring);
  
-       ret = i915_add_request(ring, NULL, request);
-       if (ret) {
-               kfree(request);
-               return ret;
-       }
-       overlay->last_flip_req = request->seqno;
-       return 0;
+       return i915_add_request(ring, NULL, &overlay->last_flip_req);
  }
  
  static void intel_overlay_release_old_vid_tail(struct intel_overlay *overlay)
@@@ -349,15 -323,10 +322,10 @@@ static int intel_overlay_off(struct int
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_ring_buffer *ring = &dev_priv->ring[RCS];
        u32 flip_addr = overlay->flip_addr;
-       struct drm_i915_gem_request *request;
        int ret;
  
        BUG_ON(!overlay->active);
  
-       request = kzalloc(sizeof(*request), GFP_KERNEL);
-       if (request == NULL)
-               return -ENOMEM;
        /* According to intel docs the overlay hw may hang (when switching
         * off) without loading the filter coeffs. It is however unclear whether
         * this applies to the disabling of the overlay or to the switching off
        flip_addr |= OFC_UPDATE;
  
        ret = intel_ring_begin(ring, 6);
-       if (ret) {
-               kfree(request);
+       if (ret)
                return ret;
-       }
        /* wait for overlay to go idle */
        intel_ring_emit(ring, MI_OVERLAY_FLIP | MI_OVERLAY_CONTINUE);
        intel_ring_emit(ring, flip_addr);
        intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
        intel_ring_advance(ring);
  
-       return intel_overlay_do_wait_request(overlay, request,
-                                            intel_overlay_off_tail);
+       return intel_overlay_do_wait_request(overlay, intel_overlay_off_tail);
  }
  
  /* recover from an interruption due to a signal
@@@ -425,24 -392,16 +391,16 @@@ static int intel_overlay_release_old_vi
                return 0;
  
        if (I915_READ(ISR) & I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT) {
-               struct drm_i915_gem_request *request;
                /* synchronous slowpath */
-               request = kzalloc(sizeof(*request), GFP_KERNEL);
-               if (request == NULL)
-                       return -ENOMEM;
                ret = intel_ring_begin(ring, 2);
-               if (ret) {
-                       kfree(request);
+               if (ret)
                        return ret;
-               }
  
                intel_ring_emit(ring, MI_WAIT_FOR_EVENT | MI_WAIT_FOR_OVERLAY_FLIP);
                intel_ring_emit(ring, MI_NOOP);
                intel_ring_advance(ring);
  
-               ret = intel_overlay_do_wait_request(overlay, request,
+               ret = intel_overlay_do_wait_request(overlay,
                                                    intel_overlay_release_old_vid_tail);
                if (ret)
                        return ret;