Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 82ba789f authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge branch 'drm-intel-fixes' of git://people.freedesktop.org/~danvet/drm-intel

Daniel writes:
"Pretty much all just major fixes:
- 2 pieces of duct-tape for the ilk bug.
- Sprite regression fixes from Chris.
- OOPS fix for a div-by-zero from Chris, regression due to the modeset
  rework in 3.7, now brought to light by a benign change in 3.8.
- Fix interrupted bo pinning, used to work around CS coherency issues on
  i830/i845 (kernel also has a w/a newly in 3.8, but pinning is more efficient if
  possible)."
parents ecf02a60 93927ca5
Loading
Loading
Loading
Loading
+17 −28
Original line number Diff line number Diff line
@@ -221,11 +221,13 @@ static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,

	BUG_ON(!hole_node->hole_follows || node->allocated);

	if (mm->color_adjust)
		mm->color_adjust(hole_node, color, &adj_start, &adj_end);

	if (adj_start < start)
		adj_start = start;
	if (adj_end > end)
		adj_end = end;

	if (mm->color_adjust)
		mm->color_adjust(hole_node, color, &adj_start, &adj_end);

	if (alignment) {
		unsigned tmp = adj_start % alignment;
@@ -506,7 +508,7 @@ void drm_mm_init_scan(struct drm_mm *mm,
	mm->scan_size = size;
	mm->scanned_blocks = 0;
	mm->scan_hit_start = 0;
	mm->scan_hit_size = 0;
	mm->scan_hit_end = 0;
	mm->scan_check_range = 0;
	mm->prev_scanned_node = NULL;
}
@@ -533,7 +535,7 @@ void drm_mm_init_scan_with_range(struct drm_mm *mm,
	mm->scan_size = size;
	mm->scanned_blocks = 0;
	mm->scan_hit_start = 0;
	mm->scan_hit_size = 0;
	mm->scan_hit_end = 0;
	mm->scan_start = start;
	mm->scan_end = end;
	mm->scan_check_range = 1;
@@ -552,8 +554,7 @@ int drm_mm_scan_add_block(struct drm_mm_node *node)
	struct drm_mm *mm = node->mm;
	struct drm_mm_node *prev_node;
	unsigned long hole_start, hole_end;
	unsigned long adj_start;
	unsigned long adj_end;
	unsigned long adj_start, adj_end;

	mm->scanned_blocks++;

@@ -570,14 +571,8 @@ int drm_mm_scan_add_block(struct drm_mm_node *node)
	node->node_list.next = &mm->prev_scanned_node->node_list;
	mm->prev_scanned_node = node;

	hole_start = drm_mm_hole_node_start(prev_node);
	hole_end = drm_mm_hole_node_end(prev_node);

	adj_start = hole_start;
	adj_end = hole_end;

	if (mm->color_adjust)
		mm->color_adjust(prev_node, mm->scan_color, &adj_start, &adj_end);
	adj_start = hole_start = drm_mm_hole_node_start(prev_node);
	adj_end = hole_end = drm_mm_hole_node_end(prev_node);

	if (mm->scan_check_range) {
		if (adj_start < mm->scan_start)
@@ -586,11 +581,14 @@ int drm_mm_scan_add_block(struct drm_mm_node *node)
			adj_end = mm->scan_end;
	}

	if (mm->color_adjust)
		mm->color_adjust(prev_node, mm->scan_color,
				 &adj_start, &adj_end);

	if (check_free_hole(adj_start, adj_end,
			    mm->scan_size, mm->scan_alignment)) {
		mm->scan_hit_start = hole_start;
		mm->scan_hit_size = hole_end;

		mm->scan_hit_end = hole_end;
		return 1;
	}

@@ -626,19 +624,10 @@ int drm_mm_scan_remove_block(struct drm_mm_node *node)
			       node_list);

	prev_node->hole_follows = node->scanned_preceeds_hole;
	INIT_LIST_HEAD(&node->node_list);
	list_add(&node->node_list, &prev_node->node_list);

	/* Only need to check for containement because start&size for the
	 * complete resulting free block (not just the desired part) is
	 * stored. */
	if (node->start >= mm->scan_hit_start &&
	    node->start + node->size
	    		<= mm->scan_hit_start + mm->scan_hit_size) {
		return 1;
	}

	return 0;
	 return (drm_mm_hole_node_end(node) > mm->scan_hit_start &&
		 node->start < mm->scan_hit_end);
}
EXPORT_SYMBOL(drm_mm_scan_remove_block);

+18 −7
Original line number Diff line number Diff line
@@ -1717,7 +1717,8 @@ i915_gem_object_put_pages(struct drm_i915_gem_object *obj)
}

static long
i915_gem_purge(struct drm_i915_private *dev_priv, long target)
__i915_gem_shrink(struct drm_i915_private *dev_priv, long target,
		  bool purgeable_only)
{
	struct drm_i915_gem_object *obj, *next;
	long count = 0;
@@ -1725,7 +1726,7 @@ i915_gem_purge(struct drm_i915_private *dev_priv, long target)
	list_for_each_entry_safe(obj, next,
				 &dev_priv->mm.unbound_list,
				 gtt_list) {
		if (i915_gem_object_is_purgeable(obj) &&
		if ((i915_gem_object_is_purgeable(obj) || !purgeable_only) &&
		    i915_gem_object_put_pages(obj) == 0) {
			count += obj->base.size >> PAGE_SHIFT;
			if (count >= target)
@@ -1736,7 +1737,7 @@ i915_gem_purge(struct drm_i915_private *dev_priv, long target)
	list_for_each_entry_safe(obj, next,
				 &dev_priv->mm.inactive_list,
				 mm_list) {
		if (i915_gem_object_is_purgeable(obj) &&
		if ((i915_gem_object_is_purgeable(obj) || !purgeable_only) &&
		    i915_gem_object_unbind(obj) == 0 &&
		    i915_gem_object_put_pages(obj) == 0) {
			count += obj->base.size >> PAGE_SHIFT;
@@ -1748,6 +1749,12 @@ i915_gem_purge(struct drm_i915_private *dev_priv, long target)
	return count;
}

static long
i915_gem_purge(struct drm_i915_private *dev_priv, long target)
{
	return __i915_gem_shrink(dev_priv, target, true);
}

static void
i915_gem_shrink_all(struct drm_i915_private *dev_priv)
{
@@ -3522,14 +3529,15 @@ i915_gem_pin_ioctl(struct drm_device *dev, void *data,
		goto out;
	}

	obj->user_pin_count++;
	obj->pin_filp = file;
	if (obj->user_pin_count == 1) {
	if (obj->user_pin_count == 0) {
		ret = i915_gem_object_pin(obj, args->alignment, true, false);
		if (ret)
			goto out;
	}

	obj->user_pin_count++;
	obj->pin_filp = file;

	/* XXX - flush the CPU caches for pinned objects
	 * as the X server doesn't manage domains yet
	 */
@@ -4394,6 +4402,9 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc)

	if (nr_to_scan) {
		nr_to_scan -= i915_gem_purge(dev_priv, nr_to_scan);
		if (nr_to_scan > 0)
			nr_to_scan -= __i915_gem_shrink(dev_priv, nr_to_scan,
							false);
		if (nr_to_scan > 0)
			i915_gem_shrink_all(dev_priv);
	}
@@ -4402,7 +4413,7 @@ i915_gem_inactive_shrink(struct shrinker *shrinker, struct shrink_control *sc)
	list_for_each_entry(obj, &dev_priv->mm.unbound_list, gtt_list)
		if (obj->pages_pin_count == 0)
			cnt += obj->base.size >> PAGE_SHIFT;
	list_for_each_entry(obj, &dev_priv->mm.bound_list, gtt_list)
	list_for_each_entry(obj, &dev_priv->mm.inactive_list, gtt_list)
		if (obj->pin_count == 0 && obj->pages_pin_count == 0)
			cnt += obj->base.size >> PAGE_SHIFT;

+25 −8
Original line number Diff line number Diff line
@@ -8598,19 +8598,30 @@ int intel_framebuffer_init(struct drm_device *dev,
{
	int ret;

	if (obj->tiling_mode == I915_TILING_Y)
	if (obj->tiling_mode == I915_TILING_Y) {
		DRM_DEBUG("hardware does not support tiling Y\n");
		return -EINVAL;
	}

	if (mode_cmd->pitches[0] & 63)
	if (mode_cmd->pitches[0] & 63) {
		DRM_DEBUG("pitch (%d) must be at least 64 byte aligned\n",
			  mode_cmd->pitches[0]);
		return -EINVAL;
	}

	/* FIXME <= Gen4 stride limits are bit unclear */
	if (mode_cmd->pitches[0] > 32768)
	if (mode_cmd->pitches[0] > 32768) {
		DRM_DEBUG("pitch (%d) must be at less than 32768\n",
			  mode_cmd->pitches[0]);
		return -EINVAL;
	}

	if (obj->tiling_mode != I915_TILING_NONE &&
	    mode_cmd->pitches[0] != obj->stride)
	    mode_cmd->pitches[0] != obj->stride) {
		DRM_DEBUG("pitch (%d) must match tiling stride (%d)\n",
			  mode_cmd->pitches[0], obj->stride);
		return -EINVAL;
	}

	/* Reject formats not supported by any plane early. */
	switch (mode_cmd->pixel_format) {
@@ -8621,8 +8632,10 @@ int intel_framebuffer_init(struct drm_device *dev,
		break;
	case DRM_FORMAT_XRGB1555:
	case DRM_FORMAT_ARGB1555:
		if (INTEL_INFO(dev)->gen > 3)
		if (INTEL_INFO(dev)->gen > 3) {
			DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format);
			return -EINVAL;
		}
		break;
	case DRM_FORMAT_XBGR8888:
	case DRM_FORMAT_ABGR8888:
@@ -8630,18 +8643,22 @@ int intel_framebuffer_init(struct drm_device *dev,
	case DRM_FORMAT_ARGB2101010:
	case DRM_FORMAT_XBGR2101010:
	case DRM_FORMAT_ABGR2101010:
		if (INTEL_INFO(dev)->gen < 4)
		if (INTEL_INFO(dev)->gen < 4) {
			DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format);
			return -EINVAL;
		}
		break;
	case DRM_FORMAT_YUYV:
	case DRM_FORMAT_UYVY:
	case DRM_FORMAT_YVYU:
	case DRM_FORMAT_VYUY:
		if (INTEL_INFO(dev)->gen < 6)
		if (INTEL_INFO(dev)->gen < 5) {
			DRM_DEBUG("invalid format: 0x%08x\n", mode_cmd->pixel_format);
			return -EINVAL;
		}
		break;
	default:
		DRM_DEBUG_KMS("unsupported pixel format 0x%08x\n", mode_cmd->pixel_format);
		DRM_DEBUG("unsupported pixel format 0x%08x\n", mode_cmd->pixel_format);
		return -EINVAL;
	}

+0 −8
Original line number Diff line number Diff line
@@ -774,14 +774,6 @@ static const struct dmi_system_id intel_no_lvds[] = {
			DMI_MATCH(DMI_BOARD_NAME, "MS-7469"),
		},
	},
	{
		.callback = intel_no_lvds_dmi_callback,
		.ident = "ZOTAC ZBOXSD-ID12/ID13",
		.matches = {
			DMI_MATCH(DMI_BOARD_VENDOR, "ZOTAC"),
			DMI_MATCH(DMI_BOARD_NAME, "ZBOXSD-ID12/ID13"),
		},
	},
	{
		.callback = intel_no_lvds_dmi_callback,
		.ident = "Gigabyte GA-D525TUD",
+16 −9
Original line number Diff line number Diff line
@@ -44,6 +44,14 @@
 * i915.i915_enable_fbc parameter
 */

static bool intel_crtc_active(struct drm_crtc *crtc)
{
	/* Be paranoid as we can arrive here with only partial
	 * state retrieved from the hardware during setup.
	 */
	return to_intel_crtc(crtc)->active && crtc->fb && crtc->mode.clock;
}

static void i8xx_disable_fbc(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
@@ -405,9 +413,8 @@ void intel_update_fbc(struct drm_device *dev)
	 *   - going to an unsupported config (interlace, pixel multiply, etc.)
	 */
	list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) {
		if (to_intel_crtc(tmp_crtc)->active &&
		    !to_intel_crtc(tmp_crtc)->primary_disabled &&
		    tmp_crtc->fb) {
		if (intel_crtc_active(tmp_crtc) &&
		    !to_intel_crtc(tmp_crtc)->primary_disabled) {
			if (crtc) {
				DRM_DEBUG_KMS("more than one pipe active, disabling compression\n");
				dev_priv->no_fbc_reason = FBC_MULTIPLE_PIPES;
@@ -992,7 +999,7 @@ static struct drm_crtc *single_enabled_crtc(struct drm_device *dev)
	struct drm_crtc *crtc, *enabled = NULL;

	list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
		if (to_intel_crtc(crtc)->active && crtc->fb) {
		if (intel_crtc_active(crtc)) {
			if (enabled)
				return NULL;
			enabled = crtc;
@@ -1086,7 +1093,7 @@ static bool g4x_compute_wm0(struct drm_device *dev,
	int entries, tlb_miss;

	crtc = intel_get_crtc_for_plane(dev, plane);
	if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) {
	if (!intel_crtc_active(crtc)) {
		*cursor_wm = cursor->guard_size;
		*plane_wm = display->guard_size;
		return false;
@@ -1215,7 +1222,7 @@ static bool vlv_compute_drain_latency(struct drm_device *dev,
	int entries;

	crtc = intel_get_crtc_for_plane(dev, plane);
	if (crtc->fb == NULL || !to_intel_crtc(crtc)->active)
	if (!intel_crtc_active(crtc))
		return false;

	clock = crtc->mode.clock;	/* VESA DOT Clock */
@@ -1476,7 +1483,7 @@ static void i9xx_update_wm(struct drm_device *dev)

	fifo_size = dev_priv->display.get_fifo_size(dev, 0);
	crtc = intel_get_crtc_for_plane(dev, 0);
	if (to_intel_crtc(crtc)->active && crtc->fb) {
	if (intel_crtc_active(crtc)) {
		int cpp = crtc->fb->bits_per_pixel / 8;
		if (IS_GEN2(dev))
			cpp = 4;
@@ -1490,7 +1497,7 @@ static void i9xx_update_wm(struct drm_device *dev)

	fifo_size = dev_priv->display.get_fifo_size(dev, 1);
	crtc = intel_get_crtc_for_plane(dev, 1);
	if (to_intel_crtc(crtc)->active && crtc->fb) {
	if (intel_crtc_active(crtc)) {
		int cpp = crtc->fb->bits_per_pixel / 8;
		if (IS_GEN2(dev))
			cpp = 4;
@@ -2044,7 +2051,7 @@ sandybridge_compute_sprite_wm(struct drm_device *dev, int plane,
	int entries, tlb_miss;

	crtc = intel_get_crtc_for_plane(dev, plane);
	if (crtc->fb == NULL || !to_intel_crtc(crtc)->active) {
	if (!intel_crtc_active(crtc)) {
		*sprite_wm = display->guard_size;
		return false;
	}
Loading