Merge branch 'drm-intel-fixes' into drm-intel-next
authorChris Wilson <chris@chris-wilson.co.uk>
Sun, 3 Oct 2010 09:56:11 +0000 (10:56 +0100)
committerChris Wilson <chris@chris-wilson.co.uk>
Sun, 3 Oct 2010 09:56:11 +0000 (10:56 +0100)
Conflicts:
drivers/gpu/drm/i915/i915_gem_evict.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c

1  2 
drivers/gpu/drm/i915/i915_gem.c
drivers/gpu/drm/i915/i915_gem_evict.c
drivers/gpu/drm/i915/i915_reg.h
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_drv.h
drivers/gpu/drm/i915/intel_tv.c

Simple merge
Simple merge
index 58cfea25a645254a5c18dbe613f139661f2e766a,4f5e15577e89e3e6f7005cd92f9f87ab0636b4eb..d02de212e6ad217de1f09ddc589ea7949ae814f4
  
  /* Display & cursor control */
  
 -/* dithering flag on Ironlake */
 -#define PIPE_ENABLE_DITHER            (1 << 4)
 -#define PIPE_DITHER_TYPE_MASK         (3 << 2)
 -#define PIPE_DITHER_TYPE_SPATIAL      (0 << 2)
 -#define PIPE_DITHER_TYPE_ST01         (1 << 2)
  /* Pipe A */
  #define PIPEADSL              0x70000
--#define   DSL_LINEMASK                0x00000fff
++#define   DSL_LINEMASK                0x00000fff
  #define PIPEACONF             0x70008
 -#define   PIPEACONF_ENABLE    (1<<31)
 -#define   PIPEACONF_DISABLE   0
 -#define   PIPEACONF_DOUBLE_WIDE       (1<<30)
 +#define   PIPECONF_ENABLE     (1<<31)
 +#define   PIPECONF_DISABLE    0
 +#define   PIPECONF_DOUBLE_WIDE        (1<<30)
  #define   I965_PIPECONF_ACTIVE        (1<<30)
 -#define   PIPEACONF_SINGLE_WIDE       0
 -#define   PIPEACONF_PIPE_UNLOCKED 0
 -#define   PIPEACONF_PIPE_LOCKED       (1<<25)
 -#define   PIPEACONF_PALETTE   0
 -#define   PIPEACONF_GAMMA             (1<<24)
 +#define   PIPECONF_SINGLE_WIDE        0
 +#define   PIPECONF_PIPE_UNLOCKED 0
 +#define   PIPECONF_PIPE_LOCKED        (1<<25)
 +#define   PIPECONF_PALETTE    0
 +#define   PIPECONF_GAMMA              (1<<24)
  #define   PIPECONF_FORCE_BORDER       (1<<25)
  #define   PIPECONF_PROGRESSIVE        (0 << 21)
  #define   PIPECONF_INTERLACE_W_FIELD_INDICATION       (6 << 21)
  #define   PIPE_START_VBLANK_INTERRUPT_STATUS  (1UL<<2) /* 965 or later */
  #define   PIPE_VBLANK_INTERRUPT_STATUS                (1UL<<1)
  #define   PIPE_OVERLAY_UPDATED_STATUS         (1UL<<0)
--#define   PIPE_BPC_MASK                       (7 << 5) /* Ironlake */
++#define   PIPE_BPC_MASK                               (7 << 5) /* Ironlake */
  #define   PIPE_8BPC                           (0 << 5)
  #define   PIPE_10BPC                          (1 << 5)
  #define   PIPE_6BPC                           (2 << 5)
  #define   PIPE_12BPC                          (3 << 5)
  
 +#define PIPECONF(pipe) _PIPE(pipe, PIPEACONF, PIPEBCONF)
++#define PIPEDSL(pipe)  _PIPE(pipe, PIPEADSL, PIPEBDSL)
 +
  #define DSPARB                        0x70030
  #define   DSPARB_CSTART_MASK  (0x7f << 7)
  #define   DSPARB_CSTART_SHIFT 7
index 00214c123ec2c8c900c2d095240d2509978b612f,979228594599a28ac7737762679f1c97fd5981bf..a2e8e15b8f5aea485fc868a94a8b59c26afadcd5
@@@ -1026,28 -1022,42 +1026,41 @@@ void intel_wait_for_vblank(struct drm_d
   * spinning on the vblank interrupt status bit, since we won't actually
   * see an interrupt when the pipe is disabled.
   *
-  * So this function waits for the display line value to settle (it
-  * usually ends up stopping at the start of the next frame).
+  * On Gen4 and above:
+  *   wait for the pipe register state bit to turn off
+  *
+  * Otherwise:
+  *   wait for the display line value to settle (it usually
+  *   ends up stopping at the start of the next frame).
 - *  
++ *
   */
- void intel_wait_for_vblank_off(struct drm_device *dev, int pipe)
 -static void intel_wait_for_pipe_off(struct drm_device *dev, int pipe)
++void intel_wait_for_pipe_off(struct drm_device *dev, int pipe)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL);
-       unsigned long timeout = jiffies + msecs_to_jiffies(100);
-       u32 last_line, line;
-       /* Wait for the display line to settle */
-       line = I915_READ(pipedsl_reg) & DSL_LINEMASK;
-       do {
-               last_line = line;
-               MSLEEP(5);
-               line = I915_READ(pipedsl_reg) & DSL_LINEMASK;
-       } while (line != last_line && time_after(timeout, jiffies));
-       if (line != last_line)
-               DRM_DEBUG_KMS("vblank wait timed out\n");
+       if (INTEL_INFO(dev)->gen >= 4) {
 -              int pipeconf_reg = (pipe == 0 ? PIPEACONF : PIPEBCONF);
++              int reg = PIPECONF(pipe);
+               /* Wait for the Pipe State to go off */
 -              if (wait_for((I915_READ(pipeconf_reg) & I965_PIPECONF_ACTIVE) == 0,
 -                           100, 0))
++              if (wait_for((I915_READ(reg) & I965_PIPECONF_ACTIVE) == 0,
++                           100))
+                       DRM_DEBUG_KMS("pipe_off wait timed out\n");
+       } else {
+               u32 last_line;
 -              int pipedsl_reg = (pipe == 0 ? PIPEADSL : PIPEBDSL);
++              int reg = PIPEDSL(pipe);
+               unsigned long timeout = jiffies + msecs_to_jiffies(100);
+               /* Wait for the display line to settle */
+               do {
 -                      last_line = I915_READ(pipedsl_reg) & DSL_LINEMASK;
++                      last_line = I915_READ(reg) & DSL_LINEMASK;
+                       mdelay(5);
 -              } while (((I915_READ(pipedsl_reg) & DSL_LINEMASK) != last_line) &&
++              } while (((I915_READ(reg) & DSL_LINEMASK) != last_line) &&
+                        time_after(timeout, jiffies));
+               if (time_after(jiffies, timeout))
+                       DRM_DEBUG_KMS("pipe_off wait timed out\n");
+       }
  }
  
 -/* Parameters have changed, update FBC info */
  static void i8xx_enable_fbc(struct drm_crtc *crtc, unsigned long interval)
  {
        struct drm_device *dev = crtc->dev;
@@@ -2381,79 -2273,101 +2394,79 @@@ static void i9xx_crtc_disable(struct dr
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        int pipe = intel_crtc->pipe;
        int plane = intel_crtc->plane;
 -      int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
 -      int dspcntr_reg = (plane == 0) ? DSPACNTR : DSPBCNTR;
 -      int dspbase_reg = (plane == 0) ? DSPAADDR : DSPBADDR;
 -      int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
 -      u32 temp;
 -
 -      /* XXX: When our outputs are all unaware of DPMS modes other than off
 -       * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
 -       */
 -      switch (mode) {
 -      case DRM_MODE_DPMS_ON:
 -      case DRM_MODE_DPMS_STANDBY:
 -      case DRM_MODE_DPMS_SUSPEND:
 -              /* Enable the DPLL */
 -              temp = I915_READ(dpll_reg);
 -              if ((temp & DPLL_VCO_ENABLE) == 0) {
 -                      I915_WRITE(dpll_reg, temp);
 -                      I915_READ(dpll_reg);
 -                      /* Wait for the clocks to stabilize. */
 -                      udelay(150);
 -                      I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
 -                      I915_READ(dpll_reg);
 -                      /* Wait for the clocks to stabilize. */
 -                      udelay(150);
 -                      I915_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
 -                      I915_READ(dpll_reg);
 -                      /* Wait for the clocks to stabilize. */
 -                      udelay(150);
 -              }
 +      u32 reg, temp;
  
 -              /* Enable the pipe */
 -              temp = I915_READ(pipeconf_reg);
 -              if ((temp & PIPEACONF_ENABLE) == 0)
 -                      I915_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
 -
 -              /* Enable the plane */
 -              temp = I915_READ(dspcntr_reg);
 -              if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
 -                      I915_WRITE(dspcntr_reg, temp | DISPLAY_PLANE_ENABLE);
 -                      /* Flush the plane changes */
 -                      I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
 -              }
 +      if (!intel_crtc->active)
 +              return;
  
 -              intel_crtc_load_lut(crtc);
 +      /* Give the overlay scaler a chance to disable if it's on this pipe */
 +      intel_crtc_wait_for_pending_flips(crtc);
 +      drm_vblank_off(dev, pipe);
 +      intel_crtc_dpms_overlay(intel_crtc, false);
 +      intel_crtc_update_cursor(crtc, false);
  
 -              if ((IS_I965G(dev) || plane == 0))
 -                      intel_update_fbc(crtc, &crtc->mode);
 +      if (dev_priv->cfb_plane == plane &&
 +          dev_priv->display.disable_fbc)
 +              dev_priv->display.disable_fbc(dev);
  
 -              /* Give the overlay scaler a chance to enable if it's on this pipe */
 -              intel_crtc_dpms_overlay(intel_crtc, true);
 -      break;
 -      case DRM_MODE_DPMS_OFF:
 -              /* Give the overlay scaler a chance to disable if it's on this pipe */
 -              intel_crtc_dpms_overlay(intel_crtc, false);
 -              drm_vblank_off(dev, pipe);
 -
 -              if (dev_priv->cfb_plane == plane &&
 -                  dev_priv->display.disable_fbc)
 -                      dev_priv->display.disable_fbc(dev);
 -
 -              /* Disable display plane */
 -              temp = I915_READ(dspcntr_reg);
 -              if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
 -                      I915_WRITE(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
 -                      /* Flush the plane changes */
 -                      I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
 -                      I915_READ(dspbase_reg);
 -              }
 +      /* Disable display plane */
 +      reg = DSPCNTR(plane);
 +      temp = I915_READ(reg);
 +      if (temp & DISPLAY_PLANE_ENABLE) {
 +              I915_WRITE(reg, temp & ~DISPLAY_PLANE_ENABLE);
 +              /* Flush the plane changes */
 +              intel_flush_display_plane(dev, plane);
  
 -              /* Don't disable pipe A or pipe A PLLs if needed */
 -              if (pipeconf_reg == PIPEACONF &&
 -                  (dev_priv->quirks & QUIRK_PIPEA_FORCE)) {
 -                      /* Wait for vblank for the disable to take effect */
 +              /* Wait for vblank for the disable to take effect */
 +              if (IS_GEN2(dev))
-                       intel_wait_for_vblank_off(dev, pipe);
+                       intel_wait_for_vblank(dev, pipe);
 -                      goto skip_pipe_off;
 -              }
 +      }
  
 -              /* Next, disable display pipes */
 -              temp = I915_READ(pipeconf_reg);
 -              if ((temp & PIPEACONF_ENABLE) != 0) {
 -                      I915_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
 -                      I915_READ(pipeconf_reg);
 -              }
 +      /* Don't disable pipe A or pipe A PLLs if needed */
 +      if (pipe == 0 && (dev_priv->quirks & QUIRK_PIPEA_FORCE))
 +              goto done;
 +
 +      /* Next, disable display pipes */
 +      reg = PIPECONF(pipe);
 +      temp = I915_READ(reg);
 +      if (temp & PIPECONF_ENABLE) {
 +              I915_WRITE(reg, temp & ~PIPECONF_ENABLE);
  
-               /* Wait for vblank for the disable to take effect. */
+               /* Wait for the pipe to turn off */
 +              POSTING_READ(reg);
-               intel_wait_for_vblank_off(dev, pipe);
+               intel_wait_for_pipe_off(dev, pipe);
 +      }
 +
 +      reg = DPLL(pipe);
 +      temp = I915_READ(reg);
 +      if (temp & DPLL_VCO_ENABLE) {
 +              I915_WRITE(reg, temp & ~DPLL_VCO_ENABLE);
  
 -              temp = I915_READ(dpll_reg);
 -              if ((temp & DPLL_VCO_ENABLE) != 0) {
 -                      I915_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
 -                      I915_READ(dpll_reg);
 -              }
 -      skip_pipe_off:
                /* Wait for the clocks to turn off. */
 +              POSTING_READ(reg);
                udelay(150);
 +      }
 +
 +done:
 +      intel_crtc->active = false;
 +      intel_update_fbc(dev);
 +      intel_update_watermarks(dev);
 +      intel_clear_scanline_wait(dev);
 +}
 +
 +static void i9xx_crtc_dpms(struct drm_crtc *crtc, int mode)
 +{
 +      /* XXX: When our outputs are all unaware of DPMS modes other than off
 +       * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
 +       */
 +      switch (mode) {
 +      case DRM_MODE_DPMS_ON:
 +      case DRM_MODE_DPMS_STANDBY:
 +      case DRM_MODE_DPMS_SUSPEND:
 +              i9xx_crtc_enable(crtc);
 +              break;
 +      case DRM_MODE_DPMS_OFF:
 +              i9xx_crtc_disable(crtc);
                break;
        }
  }
index d19334aa66adcb77deccc2631317d3dcce169538,9ab8708ac6ba1370cea75680d6a660daa5f9b147..9e8fe122b0af8e7f993e63fa38292a3bf835f54f
@@@ -1186,12 -1137,11 +1186,10 @@@ intel_channel_eq_ok(struct intel_dp *in
  static bool
  intel_dp_set_link_train(struct intel_dp *intel_dp,
                        uint32_t dp_reg_value,
--                      uint8_t dp_train_pat,
-                       bool first)
 -                      uint8_t train_set[4])
++                      uint8_t dp_train_pat)
  {
 -      struct drm_device *dev = intel_dp->base.enc.dev;
 +      struct drm_device *dev = intel_dp->base.base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc);
        int ret;
  
        I915_WRITE(intel_dp->output_reg, dp_reg_value);
                                    dp_train_pat);
  
        ret = intel_dp_aux_native_write(intel_dp,
-                                       DP_TRAINING_LANE0_SET, intel_dp->train_set, 4);
 -                                      DP_TRAINING_LANE0_SET, train_set, 4);
++                                      DP_TRAINING_LANE0_SET,
++                                      intel_dp->train_set, 4);
        if (ret != 4)
                return false;
  
        return true;
  }
  
 +/* Enable corresponding port and start training pattern 1 */
  static void
 -intel_dp_link_train(struct intel_dp *intel_dp)
 +intel_dp_start_link_train(struct intel_dp *intel_dp)
  {
 -      struct drm_device *dev = intel_dp->base.enc.dev;
 +      struct drm_device *dev = intel_dp->base.base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
 -      uint8_t train_set[4];
 -      uint8_t link_status[DP_LINK_STATUS_SIZE];
++      struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.base.crtc);
        int i;
        uint8_t voltage;
        bool clock_recovery = false;
-       bool first = true;
 -      bool channel_eq = false;
        int tries;
        u32 reg;
        uint32_t DP = intel_dp->DP;
 -      struct intel_crtc *intel_crtc = to_intel_crtc(intel_dp->base.enc.crtc);
  
+       /* Enable output, wait for it to become active */
+       I915_WRITE(intel_dp->output_reg, intel_dp->DP);
+       POSTING_READ(intel_dp->output_reg);
+       intel_wait_for_vblank(dev, intel_crtc->pipe);
        /* Write the link configuration data */
        intel_dp_aux_native_write(intel_dp, DP_LINK_BW_SET,
                                  intel_dp->link_configuration,
                        reg = DP | DP_LINK_TRAIN_PAT_1;
  
                if (!intel_dp_set_link_train(intel_dp, reg,
-                                            DP_TRAINING_PATTERN_1, first))
 -                                           DP_TRAINING_PATTERN_1, train_set))
++                                           DP_TRAINING_PATTERN_1))
                        break;
-               first = false;
                /* Set training pattern 1 */
  
                udelay(100);
@@@ -1324,8 -1266,7 +1326,7 @@@ intel_dp_complete_link_train(struct int
  
                /* channel eq pattern */
                if (!intel_dp_set_link_train(intel_dp, reg,
-                                            DP_TRAINING_PATTERN_2,
-                                            false))
 -                                           DP_TRAINING_PATTERN_2, train_set))
++                                           DP_TRAINING_PATTERN_2))
                        break;
  
                udelay(400);
index 60ce9305e7725af76141017fbe6e8174ef62c11a,8828b3ac6414eabff93134e34a41ae5c38d1cd34..40e99bf27ff7e23a59a838d37ce5cbd85783dff2
@@@ -242,8 -229,8 +242,8 @@@ extern struct drm_display_mode *intel_c
                                                    struct drm_crtc *crtc);
  int intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
                                struct drm_file *file_priv);
- extern void intel_wait_for_vblank_off(struct drm_device *dev, int pipe);
  extern void intel_wait_for_vblank(struct drm_device *dev, int pipe);
 -extern struct drm_crtc *intel_get_crtc_from_pipe(struct drm_device *dev, int pipe);
++extern void intel_wait_for_pipe_off(struct drm_device *dev, int pipe);
  extern struct drm_crtc *intel_get_load_detect_pipe(struct intel_encoder *intel_encoder,
                                                   struct drm_connector *connector,
                                                   struct drm_display_mode *mode,
index 106560bc84db0292b0cfacb2efb63ef0e8780bac,4a117e318a73a0a44c7ae4cc0be3447d11a403da..2f7681989316643149f2c11de896eef6936d884a
@@@ -1165,12 -1157,12 +1165,12 @@@ intel_tv_mode_set(struct drm_encoder *e
                I915_WRITE(dspbase_reg, I915_READ(dspbase_reg));
  
                /* Wait for vblank for the disable to take effect */
 -              if (!IS_I9XX(dev))
 +              if (IS_GEN2(dev))
                        intel_wait_for_vblank(dev, intel_crtc->pipe);
  
 -              I915_WRITE(pipeconf_reg, pipeconf & ~PIPEACONF_ENABLE);
 +              I915_WRITE(pipeconf_reg, pipeconf & ~PIPECONF_ENABLE);
                /* Wait for vblank for the disable to take effect. */
-               intel_wait_for_vblank_off(dev, intel_crtc->pipe);
 -              intel_wait_for_vblank(dev, intel_crtc->pipe);
++              intel_wait_for_pipe_off(dev, intel_crtc->pipe);
  
                /* Filter ctl must be set before TV_WIN_SIZE */
                I915_WRITE(TV_FILTER_CTL_1, TV_AUTO_SCALE);