Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt...
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 2 Jul 2010 01:48:11 +0000 (18:48 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 2 Jul 2010 01:48:11 +0000 (18:48 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/anholt/drm-intel:
  drm/i915: fix page flip finish vs. prepare on plane B
  drm/i915: change default panel fitting mode to preserve aspect ratio
  drm/i915: fix uninitialized variable warning in i915_setup_compression()
  drm/i915: take struct_mutex in i915_dma_cleanup()
  drm/i915: Fix CRT hotplug regression in 2.6.35-rc1
  i915: fix ironlake edp panel setup (v4)
  drm/i915: don't access FW_BLC_SELF on 965G
  drm/i915: Account for space on the ring buffer consumed whilst wrapping.
  drm/i915: gen3 page flipping fixes
  drm/i915: don't queue flips during a flip pending event
  drm/i915: Fix incorrect intel_ring_begin size in BSD ringbuffer.
  drm/i915: Turn on 945 self-refresh only if single CRTC is active
  drm/i915/gen4: Fix interrupt setup ordering
  drm/i915: Use RSEN instead of HTPLG for tfp410 monitor detection.
  drm/i915: Move non-phys cursors into the GTT
  Revert "drm/i915: Don't enable pipe/plane/VCO early (wait for DPMS on)."

(Included the "fix page flip finish vs.  prepare on plane B" patch from
Jesse on top of the pull request from Eric.   -- Linus)

1  2 
drivers/gpu/drm/i915/i915_dma.c
drivers/gpu/drm/i915/i915_drv.h
drivers/gpu/drm/i915/intel_display.c

index 59a2bf8592ece73672c403ef3744c4bdeb715c04,e50ae3c6cb6e437adbfdb8239b7048cfba211a59..f00c5ae9556ccb47358ce1f5267dd9cc5cb17a21
@@@ -128,9 -128,11 +128,11 @@@ static int i915_dma_cleanup(struct drm_
        if (dev->irq_enabled)
                drm_irq_uninstall(dev);
  
+       mutex_lock(&dev->struct_mutex);
        intel_cleanup_ring_buffer(dev, &dev_priv->render_ring);
        if (HAS_BSD(dev))
                intel_cleanup_ring_buffer(dev, &dev_priv->bsd_ring);
+       mutex_unlock(&dev->struct_mutex);
  
        /* Clear the HWS virtual address at teardown */
        if (I915_NEED_GFX_HWS(dev))
@@@ -1229,7 -1231,7 +1231,7 @@@ static void i915_warn_stolen(struct drm
  static void i915_setup_compression(struct drm_device *dev, int size)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
-       struct drm_mm_node *compressed_fb, *compressed_llb;
+       struct drm_mm_node *compressed_fb, *uninitialized_var(compressed_llb);
        unsigned long cfb_base;
        unsigned long ll_base = 0;
  
@@@ -1320,14 -1322,12 +1322,14 @@@ static void i915_switcheroo_set_state(s
        struct drm_device *dev = pci_get_drvdata(pdev);
        pm_message_t pmm = { .event = PM_EVENT_SUSPEND };
        if (state == VGA_SWITCHEROO_ON) {
 -              printk(KERN_INFO "i915: switched off\n");
 +              printk(KERN_INFO "i915: switched on\n");
                /* i915 resume handler doesn't set to D0 */
                pci_set_power_state(dev->pdev, PCI_D0);
                i915_resume(dev);
 +              drm_kms_helper_poll_enable(dev);
        } else {
                printk(KERN_ERR "i915: switched off\n");
 +              drm_kms_helper_poll_disable(dev);
                i915_suspend(dev, pmm);
        }
  }
@@@ -1402,19 -1402,23 +1404,23 @@@ static int i915_load_modeset_init(struc
        /* if we have > 1 VGA cards, then disable the radeon VGA resources */
        ret = vga_client_register(dev->pdev, dev, NULL, i915_vga_set_decode);
        if (ret)
 -              goto destroy_ringbuffer;
 +              goto cleanup_ringbuffer;
  
        ret = vga_switcheroo_register_client(dev->pdev,
                                             i915_switcheroo_set_state,
                                             i915_switcheroo_can_switch);
        if (ret)
 -              goto destroy_ringbuffer;
 +              goto cleanup_vga_client;
  
+       /* IIR "flip pending" bit means done if this bit is set */
+       if (IS_GEN3(dev) && (I915_READ(ECOSKPD) & ECO_FLIP_DONE))
+               dev_priv->flip_pending_is_done = true;
        intel_modeset_init(dev);
  
        ret = drm_irq_install(dev);
        if (ret)
 -              goto destroy_ringbuffer;
 +              goto cleanup_vga_switcheroo;
  
        /* Always safe in the mode setting case. */
        /* FIXME: do pre/post-mode set stuff in core KMS code */
  
        I915_WRITE(INSTPM, (1 << 5) | (1 << 21));
  
 -      intel_fbdev_init(dev);
 +      ret = intel_fbdev_init(dev);
 +      if (ret)
 +              goto cleanup_irq;
 +
        drm_kms_helper_poll_init(dev);
        return 0;
  
 -destroy_ringbuffer:
 +cleanup_irq:
 +      drm_irq_uninstall(dev);
 +cleanup_vga_switcheroo:
 +      vga_switcheroo_unregister_client(dev->pdev);
 +cleanup_vga_client:
 +      vga_client_register(dev->pdev, NULL, NULL, NULL);
 +cleanup_ringbuffer:
        mutex_lock(&dev->struct_mutex);
        i915_gem_cleanup_ringbuffer(dev);
        mutex_unlock(&dev->struct_mutex);
index 2765831598479b8d9e0bb72712d3ca71ce9a95e2,21e217dd48efdc0af6c2ec136dbd2b3ac7763780..d147ab2f5bfcabfc8bc82cd5ccdea93064fa4cf0
@@@ -278,7 -278,6 +278,7 @@@ typedef struct drm_i915_private 
        struct mem_block *agp_heap;
        unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
        int vblank_pipe;
 +      int num_pipe;
  
        /* For hangcheck timer */
  #define DRM_I915_HANGCHECK_PERIOD 75 /* in jiffies */
        struct drm_crtc *plane_to_crtc_mapping[2];
        struct drm_crtc *pipe_to_crtc_mapping[2];
        wait_queue_head_t pending_flip_queue;
+       bool flip_pending_is_done;
  
        /* Reclocking support */
        bool render_reclock_avail;
@@@ -1076,7 -1076,7 +1077,7 @@@ extern int intel_trans_dp_port_sel (str
        drm_i915_private_t *dev_priv = dev->dev_private;                \
        if (I915_VERBOSE)                                               \
                DRM_DEBUG("   BEGIN_LP_RING %x\n", (int)(n));           \
-       intel_ring_begin(dev, &dev_priv->render_ring, 4*(n));           \
+       intel_ring_begin(dev, &dev_priv->render_ring, (n));             \
  } while (0)
  
  
index cc8131ff319f3f0d243a15c0ddd924c1a93b8147,3acb766bda7e507a2300d593359f61823e9808e4..68dcf36e2793f51fa42aeecb9b67037aa8515205
@@@ -2970,11 -2970,13 +2970,13 @@@ static void i965_update_wm(struct drm_d
                if (srwm < 0)
                        srwm = 1;
                srwm &= 0x3f;
-               I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
+               if (IS_I965GM(dev))
+                       I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN);
        } else {
                /* Turn off self refresh if both pipes are enabled */
-               I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF)
-                                       & ~FW_BLC_SELF_EN);
+               if (IS_I965GM(dev))
+                       I915_WRITE(FW_BLC_SELF, I915_READ(FW_BLC_SELF)
+                                  & ~FW_BLC_SELF_EN);
        }
  
        DRM_DEBUG_KMS("Setting FIFO watermarks - A: 8, B: 8, C: 8, SR %d\n",
@@@ -4483,6 -4485,7 +4485,7 @@@ static void intel_idle_update(struct wo
        struct drm_device *dev = dev_priv->dev;
        struct drm_crtc *crtc;
        struct intel_crtc *intel_crtc;
+       int enabled = 0;
  
        if (!i915_powersave)
                return;
  
        i915_update_gfx_val(dev_priv);
  
-       if (IS_I945G(dev) || IS_I945GM(dev)) {
-               DRM_DEBUG_DRIVER("enable memory self refresh on 945\n");
-               I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN);
-       }
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
                /* Skip inactive CRTCs */
                if (!crtc->fb)
                        continue;
  
+               enabled++;
                intel_crtc = to_intel_crtc(crtc);
                if (!intel_crtc->busy)
                        intel_decrease_pllclock(crtc);
        }
  
+       if ((enabled == 1) && (IS_I945G(dev) || IS_I945GM(dev))) {
+               DRM_DEBUG_DRIVER("enable memory self refresh on 945\n");
+               I915_WRITE(FW_BLC_SELF, FW_BLC_SELF_EN_MASK | FW_BLC_SELF_EN);
+       }
        mutex_unlock(&dev->struct_mutex);
  }
  
@@@ -4601,10 -4605,10 +4605,10 @@@ static void intel_unpin_work_fn(struct 
        kfree(work);
  }
  
- void intel_finish_page_flip(struct drm_device *dev, int pipe)
+ static void do_intel_finish_page_flip(struct drm_device *dev,
+                                     struct drm_crtc *crtc)
  {
        drm_i915_private_t *dev_priv = dev->dev_private;
-       struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
        struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
        struct intel_unpin_work *work;
        struct drm_i915_gem_object *obj_priv;
        schedule_work(&work->work);
  }
  
+ void intel_finish_page_flip(struct drm_device *dev, int pipe)
+ {
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       struct drm_crtc *crtc = dev_priv->pipe_to_crtc_mapping[pipe];
+       do_intel_finish_page_flip(dev, crtc);
+ }
+ void intel_finish_page_flip_plane(struct drm_device *dev, int plane)
+ {
+       drm_i915_private_t *dev_priv = dev->dev_private;
+       struct drm_crtc *crtc = dev_priv->plane_to_crtc_mapping[plane];
+       do_intel_finish_page_flip(dev, crtc);
+ }
  void intel_prepare_page_flip(struct drm_device *dev, int plane)
  {
        drm_i915_private_t *dev_priv = dev->dev_private;
@@@ -4678,6 -4698,7 +4698,7 @@@ static int intel_crtc_page_flip(struct 
        unsigned long flags;
        int pipesrc_reg = (intel_crtc->pipe == 0) ? PIPEASRC : PIPEBSRC;
        int ret, pipesrc;
+       u32 flip_mask;
  
        work = kzalloc(sizeof *work, GFP_KERNEL);
        if (work == NULL)
        atomic_inc(&obj_priv->pending_flip);
        work->pending_flip_obj = obj;
  
+       if (intel_crtc->plane)
+               flip_mask = I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT;
+       else
+               flip_mask = I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT;
+       /* Wait for any previous flip to finish */
+       if (IS_GEN3(dev))
+               while (I915_READ(ISR) & flip_mask)
+                       ;
        BEGIN_LP_RING(4);
-       OUT_RING(MI_DISPLAY_FLIP |
-                MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
-       OUT_RING(fb->pitch);
        if (IS_I965G(dev)) {
+               OUT_RING(MI_DISPLAY_FLIP |
+                        MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+               OUT_RING(fb->pitch);
                OUT_RING(obj_priv->gtt_offset | obj_priv->tiling_mode);
                pipesrc = I915_READ(pipesrc_reg); 
                OUT_RING(pipesrc & 0x0fff0fff);
        } else {
+               OUT_RING(MI_DISPLAY_FLIP_I915 |
+                        MI_DISPLAY_FLIP_PLANE(intel_crtc->plane));
+               OUT_RING(fb->pitch);
                OUT_RING(obj_priv->gtt_offset);
                OUT_RING(MI_NOOP);
        }
@@@ -5475,6 -5509,7 +5509,6 @@@ static void intel_init_display(struct d
  void intel_modeset_init(struct drm_device *dev)
  {
        struct drm_i915_private *dev_priv = dev->dev_private;
 -      int num_pipe;
        int i;
  
        drm_mode_config_init(dev);
                dev->mode_config.fb_base = pci_resource_start(dev->pdev, 0);
  
        if (IS_MOBILE(dev) || IS_I9XX(dev))
 -              num_pipe = 2;
 +              dev_priv->num_pipe = 2;
        else
 -              num_pipe = 1;
 +              dev_priv->num_pipe = 1;
        DRM_DEBUG_KMS("%d display pipe%s available.\n",
 -                num_pipe, num_pipe > 1 ? "s" : "");
 +                    dev_priv->num_pipe, dev_priv->num_pipe > 1 ? "s" : "");
  
 -      for (i = 0; i < num_pipe; i++) {
 +      for (i = 0; i < dev_priv->num_pipe; i++) {
                intel_crtc_init(dev, i);
        }