Merge tag 'drm-intel-next-2014-03-21' of git://anongit.freedesktop.org/drm-intel...
authorDave Airlie <airlied@redhat.com>
Wed, 2 Apr 2014 21:51:54 +0000 (07:51 +1000)
committerDave Airlie <airlied@redhat.com>
Wed, 2 Apr 2014 21:51:54 +0000 (07:51 +1000)
- Inherit/reuse firmwar framebuffers (for real this time) from Jesse, less
  flicker for fastbooting.
- More flexible cloning for hdmi (Ville).
- Some PPGTT fixes from Ben.
- Ring init fixes from Naresh Kumar.
- set_cache_level regression fixes for the vma conversion from Ville&Chris.
- Conversion to the new dp aux helpers (Jani).
- Unification of runtime pm with pc8 support from Paulo, prep work for runtime
  pm on other platforms than HSW.
- Larger cursor sizes (Sagar Kamble).
- Piles of improvements and fixes all over, as usual.

* tag 'drm-intel-next-2014-03-21' of git://anongit.freedesktop.org/drm-intel: (75 commits)
  drm/i915: Include a note about the dangers of I915_READ64/I915_WRITE64
  drm/i915/sdvo: fix questionable return value check
  drm/i915: Fix unsafe loop iteration over vma whilst unbinding them
  drm/i915: Enabling 128x128 and 256x256 ARGB Cursor Support
  drm/i915: Print how many objects are shared in per-process stats
  drm/i915: Per-process stats work better when evaluated per-process
  drm/i915: remove rps local variables
  drm/i915: Remove extraneous MMIO for RPS
  drm/i915: Rename and comment all the RPS *stuff*
  drm/i915: Store the HW min frequency as min_freq
  drm/i915: Fix coding style for RPS
  drm/i915: Reorganize the overclock code
  drm/i915: init pm.suspended earlier
  drm/i915: update the PC8 and runtime PM documentation
  drm/i915: rename __hsw_do_{en, dis}able_pc8
  drm/i915: kill struct i915_package_c8
  drm/i915: move pc8.irqs_disabled to pm.irqs_disabled
  drm/i915: remove dev_priv->pc8.enabled
  drm/i915: don't get/put PC8 when getting/putting power wells
  drm/i915: make intel_aux_display_runtime_get get runtime PM, not PC8
  ...

Conflicts:
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c

1  2 
drivers/gpu/drm/drm_dp_helper.c
drivers/gpu/drm/i915/i915_cmd_parser.c
drivers/gpu/drm/i915/i915_debugfs.c
drivers/gpu/drm/i915/i915_irq.c
drivers/gpu/drm/i915/intel_display.c
drivers/gpu/drm/i915/intel_dp.c
drivers/gpu/drm/i915/intel_fbdev.c
drivers/gpu/drm/i915/intel_lvds.c
drivers/gpu/drm/i915/intel_pm.c

Simple merge
@@@ -402,10 -402,10 +402,10 @@@ int i915_parse_cmds(struct intel_ring_b
                        length = ((*cmd & desc->length.mask) + LENGTH_BIAS);
  
                if ((batch_end - cmd) < length) {
-                       DRM_DEBUG_DRIVER("CMD: Command length exceeds batch length: 0x%08X length=%d batchlen=%ld\n",
+                       DRM_DEBUG_DRIVER("CMD: Command length exceeds batch length: 0x%08X length=%d batchlen=%td\n",
                                         *cmd,
                                         length,
 -                                       batch_end - cmd);
 +                                       (unsigned long)(batch_end - cmd));
                        ret = -EINVAL;
                        break;
                }
Simple merge
Simple merge
@@@ -741,10 -741,10 +741,10 @@@ bool intel_crtc_active(struct drm_crtc 
         * We can ditch the adjusted_mode.crtc_clock check as soon
         * as Haswell has gained clock readout/fastboot support.
         *
--       * We can ditch the crtc->fb check as soon as we can
++       * We can ditch the crtc->primary->fb check as soon as we can
         * properly reconstruct framebuffers.
         */
 -      return intel_crtc->active && crtc->fb &&
 +      return intel_crtc->active && crtc->primary->fb &&
                intel_crtc->config.adjusted_mode.crtc_clock;
  }
  
@@@ -2047,8 -2047,114 +2047,114 @@@ unsigned long intel_gen4_compute_page_o
        }
  }
  
- static int i9xx_update_plane(struct drm_crtc *crtc, struct drm_framebuffer *fb,
-                            int x, int y)
+ int intel_format_to_fourcc(int format)
+ {
+       switch (format) {
+       case DISPPLANE_8BPP:
+               return DRM_FORMAT_C8;
+       case DISPPLANE_BGRX555:
+               return DRM_FORMAT_XRGB1555;
+       case DISPPLANE_BGRX565:
+               return DRM_FORMAT_RGB565;
+       default:
+       case DISPPLANE_BGRX888:
+               return DRM_FORMAT_XRGB8888;
+       case DISPPLANE_RGBX888:
+               return DRM_FORMAT_XBGR8888;
+       case DISPPLANE_BGRX101010:
+               return DRM_FORMAT_XRGB2101010;
+       case DISPPLANE_RGBX101010:
+               return DRM_FORMAT_XBGR2101010;
+       }
+ }
+ static bool intel_alloc_plane_obj(struct intel_crtc *crtc,
+                                 struct intel_plane_config *plane_config)
+ {
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_gem_object *obj = NULL;
+       struct drm_mode_fb_cmd2 mode_cmd = { 0 };
+       u32 base = plane_config->base;
+       if (plane_config->size == 0)
+               return false;
+       obj = i915_gem_object_create_stolen_for_preallocated(dev, base, base,
+                                                            plane_config->size);
+       if (!obj)
+               return false;
+       if (plane_config->tiled) {
+               obj->tiling_mode = I915_TILING_X;
 -              obj->stride = crtc->base.fb->pitches[0];
++              obj->stride = crtc->base.primary->fb->pitches[0];
+       }
 -      mode_cmd.pixel_format = crtc->base.fb->pixel_format;
 -      mode_cmd.width = crtc->base.fb->width;
 -      mode_cmd.height = crtc->base.fb->height;
 -      mode_cmd.pitches[0] = crtc->base.fb->pitches[0];
++      mode_cmd.pixel_format = crtc->base.primary->fb->pixel_format;
++      mode_cmd.width = crtc->base.primary->fb->width;
++      mode_cmd.height = crtc->base.primary->fb->height;
++      mode_cmd.pitches[0] = crtc->base.primary->fb->pitches[0];
+       mutex_lock(&dev->struct_mutex);
 -      if (intel_framebuffer_init(dev, to_intel_framebuffer(crtc->base.fb),
++      if (intel_framebuffer_init(dev, to_intel_framebuffer(crtc->base.primary->fb),
+                                  &mode_cmd, obj)) {
+               DRM_DEBUG_KMS("intel fb init failed\n");
+               goto out_unref_obj;
+       }
+       mutex_unlock(&dev->struct_mutex);
+       DRM_DEBUG_KMS("plane fb obj %p\n", obj);
+       return true;
+ out_unref_obj:
+       drm_gem_object_unreference(&obj->base);
+       mutex_unlock(&dev->struct_mutex);
+       return false;
+ }
+ static void intel_find_plane_obj(struct intel_crtc *intel_crtc,
+                                struct intel_plane_config *plane_config)
+ {
+       struct drm_device *dev = intel_crtc->base.dev;
+       struct drm_crtc *c;
+       struct intel_crtc *i;
+       struct intel_framebuffer *fb;
 -      if (!intel_crtc->base.fb)
++      if (!intel_crtc->base.primary->fb)
+               return;
+       if (intel_alloc_plane_obj(intel_crtc, plane_config))
+               return;
 -      kfree(intel_crtc->base.fb);
 -      intel_crtc->base.fb = NULL;
++      kfree(intel_crtc->base.primary->fb);
++      intel_crtc->base.primary->fb = NULL;
+       /*
+        * Failed to alloc the obj, check to see if we should share
+        * an fb with another CRTC instead
+        */
+       list_for_each_entry(c, &dev->mode_config.crtc_list, head) {
+               i = to_intel_crtc(c);
+               if (c == &intel_crtc->base)
+                       continue;
 -              if (!i->active || !c->fb)
++              if (!i->active || !c->primary->fb)
+                       continue;
 -              fb = to_intel_framebuffer(c->fb);
++              fb = to_intel_framebuffer(c->primary->fb);
+               if (i915_gem_obj_ggtt_offset(fb->obj) == plane_config->base) {
 -                      drm_framebuffer_reference(c->fb);
 -                      intel_crtc->base.fb = c->fb;
++                      drm_framebuffer_reference(c->primary->fb);
++                      intel_crtc->base.primary->fb = c->primary->fb;
+                       break;
+               }
+       }
+ }
+ static int i9xx_update_primary_plane(struct drm_crtc *crtc,
+                                    struct drm_framebuffer *fb,
+                                    int x, int y)
  {
        struct drm_device *dev = crtc->dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
@@@ -2289,11 -2396,13 +2396,13 @@@ void intel_display_handle_reset(struct 
                /*
                 * FIXME: Once we have proper support for primary planes (and
                 * disabling them without disabling the entire crtc) allow again
--               * a NULL crtc->fb.
++               * a NULL crtc->primary->fb.
                 */
 -              if (intel_crtc->active && crtc->fb)
 +              if (intel_crtc->active && crtc->primary->fb)
-                       dev_priv->display.update_plane(crtc, crtc->primary->fb,
-                                                      crtc->x, crtc->y);
+                       dev_priv->display.update_primary_plane(crtc,
 -                                                             crtc->fb,
++                                                             crtc->primary->fb,
+                                                              crtc->x,
+                                                              crtc->y);
                mutex_unlock(&crtc->mutex);
        }
  }
@@@ -5611,6 -5718,67 +5724,67 @@@ static void vlv_crtc_clock_get(struct i
        pipe_config->port_clock = clock.dot / 5;
  }
  
 -      crtc->base.fb = kzalloc(sizeof(struct intel_framebuffer), GFP_KERNEL);
 -      if (!crtc->base.fb) {
+ static void i9xx_get_plane_config(struct intel_crtc *crtc,
+                                 struct intel_plane_config *plane_config)
+ {
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 val, base, offset;
+       int pipe = crtc->pipe, plane = crtc->plane;
+       int fourcc, pixel_format;
+       int aligned_height;
 -      crtc->base.fb->pixel_format = fourcc;
 -      crtc->base.fb->bits_per_pixel =
++      crtc->base.primary->fb = kzalloc(sizeof(struct intel_framebuffer), GFP_KERNEL);
++      if (!crtc->base.primary->fb) {
+               DRM_DEBUG_KMS("failed to alloc fb\n");
+               return;
+       }
+       val = I915_READ(DSPCNTR(plane));
+       if (INTEL_INFO(dev)->gen >= 4)
+               if (val & DISPPLANE_TILED)
+                       plane_config->tiled = true;
+       pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
+       fourcc = intel_format_to_fourcc(pixel_format);
 -      crtc->base.fb->width = ((val >> 16) & 0xfff) + 1;
 -      crtc->base.fb->height = ((val >> 0) & 0xfff) + 1;
++      crtc->base.primary->fb->pixel_format = fourcc;
++      crtc->base.primary->fb->bits_per_pixel =
+               drm_format_plane_cpp(fourcc, 0) * 8;
+       if (INTEL_INFO(dev)->gen >= 4) {
+               if (plane_config->tiled)
+                       offset = I915_READ(DSPTILEOFF(plane));
+               else
+                       offset = I915_READ(DSPLINOFF(plane));
+               base = I915_READ(DSPSURF(plane)) & 0xfffff000;
+       } else {
+               base = I915_READ(DSPADDR(plane));
+       }
+       plane_config->base = base;
+       val = I915_READ(PIPESRC(pipe));
 -      crtc->base.fb->pitches[0] = val & 0xffffff80;
++      crtc->base.primary->fb->width = ((val >> 16) & 0xfff) + 1;
++      crtc->base.primary->fb->height = ((val >> 0) & 0xfff) + 1;
+       val = I915_READ(DSPSTRIDE(pipe));
 -      aligned_height = intel_align_height(dev, crtc->base.fb->height,
++      crtc->base.primary->fb->pitches[0] = val & 0xffffff80;
 -      plane_config->size = ALIGN(crtc->base.fb->pitches[0] *
++      aligned_height = intel_align_height(dev, crtc->base.primary->fb->height,
+                                           plane_config->tiled);
 -                    pipe, plane, crtc->base.fb->width,
 -                    crtc->base.fb->height,
 -                    crtc->base.fb->bits_per_pixel, base,
 -                    crtc->base.fb->pitches[0],
++      plane_config->size = ALIGN(crtc->base.primary->fb->pitches[0] *
+                                  aligned_height, PAGE_SIZE);
+       DRM_DEBUG_KMS("pipe/plane %d/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
++                    pipe, plane, crtc->base.primary->fb->width,
++                    crtc->base.primary->fb->height,
++                    crtc->base.primary->fb->bits_per_pixel, base,
++                    crtc->base.primary->fb->pitches[0],
+                     plane_config->size);
+ }
  static bool i9xx_get_pipe_config(struct intel_crtc *crtc,
                                 struct intel_crtc_config *pipe_config)
  {
@@@ -6558,6 -6726,66 +6732,66 @@@ static void ironlake_get_pfit_config(st
        }
  }
  
 -      crtc->base.fb = kzalloc(sizeof(struct intel_framebuffer), GFP_KERNEL);
 -      if (!crtc->base.fb) {
+ static void ironlake_get_plane_config(struct intel_crtc *crtc,
+                                     struct intel_plane_config *plane_config)
+ {
+       struct drm_device *dev = crtc->base.dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
+       u32 val, base, offset;
+       int pipe = crtc->pipe, plane = crtc->plane;
+       int fourcc, pixel_format;
+       int aligned_height;
 -      crtc->base.fb->pixel_format = fourcc;
 -      crtc->base.fb->bits_per_pixel =
++      crtc->base.primary->fb = kzalloc(sizeof(struct intel_framebuffer), GFP_KERNEL);
++      if (!crtc->base.primary->fb) {
+               DRM_DEBUG_KMS("failed to alloc fb\n");
+               return;
+       }
+       val = I915_READ(DSPCNTR(plane));
+       if (INTEL_INFO(dev)->gen >= 4)
+               if (val & DISPPLANE_TILED)
+                       plane_config->tiled = true;
+       pixel_format = val & DISPPLANE_PIXFORMAT_MASK;
+       fourcc = intel_format_to_fourcc(pixel_format);
 -      crtc->base.fb->width = ((val >> 16) & 0xfff) + 1;
 -      crtc->base.fb->height = ((val >> 0) & 0xfff) + 1;
++      crtc->base.primary->fb->pixel_format = fourcc;
++      crtc->base.primary->fb->bits_per_pixel =
+               drm_format_plane_cpp(fourcc, 0) * 8;
+       base = I915_READ(DSPSURF(plane)) & 0xfffff000;
+       if (IS_HASWELL(dev) || IS_BROADWELL(dev)) {
+               offset = I915_READ(DSPOFFSET(plane));
+       } else {
+               if (plane_config->tiled)
+                       offset = I915_READ(DSPTILEOFF(plane));
+               else
+                       offset = I915_READ(DSPLINOFF(plane));
+       }
+       plane_config->base = base;
+       val = I915_READ(PIPESRC(pipe));
 -      crtc->base.fb->pitches[0] = val & 0xffffff80;
++      crtc->base.primary->fb->width = ((val >> 16) & 0xfff) + 1;
++      crtc->base.primary->fb->height = ((val >> 0) & 0xfff) + 1;
+       val = I915_READ(DSPSTRIDE(pipe));
 -      aligned_height = intel_align_height(dev, crtc->base.fb->height,
++      crtc->base.primary->fb->pitches[0] = val & 0xffffff80;
 -      plane_config->size = ALIGN(crtc->base.fb->pitches[0] *
++      aligned_height = intel_align_height(dev, crtc->base.primary->fb->height,
+                                           plane_config->tiled);
 -                    pipe, plane, crtc->base.fb->width,
 -                    crtc->base.fb->height,
 -                    crtc->base.fb->bits_per_pixel, base,
 -                    crtc->base.fb->pitches[0],
++      plane_config->size = ALIGN(crtc->base.primary->fb->pitches[0] *
+                                  aligned_height, PAGE_SIZE);
+       DRM_DEBUG_KMS("pipe/plane %d/%d with fb: size=%dx%d@%d, offset=%x, pitch %d, size 0x%x\n",
++                    pipe, plane, crtc->base.primary->fb->width,
++                    crtc->base.primary->fb->height,
++                    crtc->base.primary->fb->bits_per_pixel, base,
++                    crtc->base.primary->fb->pitches[0],
+                     plane_config->size);
+ }
  static bool ironlake_get_pipe_config(struct intel_crtc *crtc,
                                     struct intel_crtc_config *pipe_config)
  {
@@@ -11487,6 -11737,26 +11743,26 @@@ void intel_modeset_gem_init(struct drm_
        intel_modeset_init_hw(dev);
  
        intel_setup_overlay(dev);
 -              if (!c->fb)
+       /*
+        * Make sure any fbs we allocated at startup are properly
+        * pinned & fenced.  When we do the allocation it's too early
+        * for this.
+        */
+       mutex_lock(&dev->struct_mutex);
+       list_for_each_entry(c, &dev->mode_config.crtc_list, head) {
 -              fb = to_intel_framebuffer(c->fb);
++              if (!c->primary->fb)
+                       continue;
 -                      drm_framebuffer_unreference(c->fb);
 -                      c->fb = NULL;
++              fb = to_intel_framebuffer(c->primary->fb);
+               if (intel_pin_and_fence_fb_obj(dev, fb->obj, NULL)) {
+                       DRM_ERROR("failed to pin boot fb on pipe %d\n",
+                                 to_intel_crtc(c)->pipe);
++                      drm_framebuffer_unreference(c->primary->fb);
++                      c->primary->fb = NULL;
+               }
+       }
+       mutex_unlock(&dev->struct_mutex);
  }
  
  void intel_connector_unregister(struct intel_connector *intel_connector)
@@@ -3763,8 -3646,7 +3646,8 @@@ static bool intel_edp_init_connector(st
        /* We now know it's not a ghost, init power sequence regs. */
        intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, power_seq);
  
-       edid = drm_get_edid(connector, &intel_dp->adapter);
 +      mutex_lock(&dev->mode_config.mutex);
+       edid = drm_get_edid(connector, &intel_dp->aux.ddc);
        if (edid) {
                if (drm_add_edid_modes(connector, edid)) {
                        drm_mode_connector_update_edid_property(connector,
@@@ -454,6 -456,124 +456,124 @@@ static void intel_fbdev_destroy(struct 
        drm_framebuffer_remove(&ifbdev->fb->base);
  }
  
 -              if (!intel_crtc->active || !crtc->fb) {
+ /*
+  * Build an intel_fbdev struct using a BIOS allocated framebuffer, if possible.
+  * The core display code will have read out the current plane configuration,
+  * so we use that to figure out if there's an object for us to use as the
+  * fb, and if so, we re-use it for the fbdev configuration.
+  *
+  * Note we only support a single fb shared across pipes for boot (mostly for
+  * fbcon), so we just find the biggest and use that.
+  */
+ static bool intel_fbdev_init_bios(struct drm_device *dev,
+                                struct intel_fbdev *ifbdev)
+ {
+       struct intel_framebuffer *fb = NULL;
+       struct drm_crtc *crtc;
+       struct intel_crtc *intel_crtc;
+       struct intel_plane_config *plane_config = NULL;
+       unsigned int max_size = 0;
+       if (!i915.fastboot)
+               return false;
+       /* Find the largest fb */
+       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+               intel_crtc = to_intel_crtc(crtc);
 -                      fb = to_intel_framebuffer(crtc->fb);
++              if (!intel_crtc->active || !crtc->primary->fb) {
+                       DRM_DEBUG_KMS("pipe %c not active or no fb, skipping\n",
+                                     pipe_name(intel_crtc->pipe));
+                       continue;
+               }
+               if (intel_crtc->plane_config.size > max_size) {
+                       DRM_DEBUG_KMS("found possible fb from plane %c\n",
+                                     pipe_name(intel_crtc->pipe));
+                       plane_config = &intel_crtc->plane_config;
 -              WARN(!crtc->fb,
++                      fb = to_intel_framebuffer(crtc->primary->fb);
+                       max_size = plane_config->size;
+               }
+       }
+       if (!fb) {
+               DRM_DEBUG_KMS("no active fbs found, not using BIOS config\n");
+               goto out;
+       }
+       /* Now make sure all the pipes will fit into it */
+       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+               unsigned int cur_size;
+               intel_crtc = to_intel_crtc(crtc);
+               if (!intel_crtc->active) {
+                       DRM_DEBUG_KMS("pipe %c not active, skipping\n",
+                                     pipe_name(intel_crtc->pipe));
+                       continue;
+               }
+               DRM_DEBUG_KMS("checking plane %c for BIOS fb\n",
+                             pipe_name(intel_crtc->pipe));
+               /*
+                * See if the plane fb we found above will fit on this
+                * pipe.  Note we need to use the selected fb's bpp rather
+                * than the current pipe's, since they could be different.
+                */
+               cur_size = intel_crtc->config.adjusted_mode.crtc_hdisplay *
+                       intel_crtc->config.adjusted_mode.crtc_vdisplay;
+               DRM_DEBUG_KMS("pipe %c area: %d\n", pipe_name(intel_crtc->pipe),
+                             cur_size);
+               cur_size *= fb->base.bits_per_pixel / 8;
+               DRM_DEBUG_KMS("total size %d (bpp %d)\n", cur_size,
+                             fb->base.bits_per_pixel / 8);
+               if (cur_size > max_size) {
+                       DRM_DEBUG_KMS("fb not big enough for plane %c (%d vs %d)\n",
+                                     pipe_name(intel_crtc->pipe),
+                                     cur_size, max_size);
+                       plane_config = NULL;
+                       fb = NULL;
+                       break;
+               }
+               DRM_DEBUG_KMS("fb big enough for plane %c (%d >= %d)\n",
+                             pipe_name(intel_crtc->pipe),
+                             max_size, cur_size);
+       }
+       if (!fb) {
+               DRM_DEBUG_KMS("BIOS fb not suitable for all pipes, not using\n");
+               goto out;
+       }
+       ifbdev->preferred_bpp = fb->base.bits_per_pixel;
+       ifbdev->fb = fb;
+       drm_framebuffer_reference(&ifbdev->fb->base);
+       /* Final pass to check if any active pipes don't have fbs */
+       list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
+               intel_crtc = to_intel_crtc(crtc);
+               if (!intel_crtc->active)
+                       continue;
++              WARN(!crtc->primary->fb,
+                    "re-used BIOS config but lost an fb on crtc %d\n",
+                    crtc->base.id);
+       }
+       DRM_DEBUG_KMS("using BIOS fb for initial console\n");
+       return true;
+ out:
+       return false;
+ }
  int intel_fbdev_init(struct drm_device *dev)
  {
        struct intel_fbdev *ifbdev;
Simple merge
Simple merge