diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 17:36:12 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 17:36:12 -0700 |
commit | a7d7a143d0b4cb1914705884ca5c25e322dba693 (patch) | |
tree | 0ee5e9e43f0863b38a29e8abc293e80eab177d74 /drivers/gpu/drm/i915/i915_gem_execbuffer.c | |
parent | 43c40df2c7fedce640a6c39fcdf58764f6bbac5c (diff) | |
parent | 7963e9db1b1f842fdc53309baa8714d38e9f5681 (diff) |
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull DRM updates from Dave Airlie:
"Like all good pull reqs this ends with a revert, so it must mean we
tested it,
[ Ed. That's _one_ way of looking at it ]
This pull is missing nouveau, Ben has been stuck trying to track down
a very longstanding bug that revealed itself due to some other
changes. I've asked him to send you a direct pull request for nouveau
once he cleans things up. I'm away until Monday so don't want to
delay things, you can make a decision on that when he sends it, I have
my phone so I can ack things just not really merge much.
It has one trivial conflict with your tree in armada_drv.c, and also
the pull request contains some component changes that are already in
your tree, the base tree from Russell went via Greg's tree already,
but some stuff still shows up in here that doesn't when I merge my
tree into yours.
Otherwise all pretty standard graphics fare, one new driver and
changes all over the place.
New drivers:
- sti kms driver for STMicroelectronics chipsets stih416 and stih407.
core:
- lots of cleanups to the drm core
- DP MST helper code merged
- universal cursor planes.
- render nodes enabled by default
panel:
- better panel interfaces
- new panel support
- non-continuous cock advertising ability
ttm:
- shrinker fixes
i915:
- hopefully ditched UMS support
- runtime pm fixes
- psr tracking and locking - now enabled by default
- userptr fixes
- backlight brightness fixes
- MST support merged
- runtime PM for dpms
- primary planes locking fixes
- gen8 hw semaphore support
- fbc fixes
- runtime PM on SOix sleep state hw.
- mmio base page flipping
- lots of vlv/chv fixes.
- universal cursor planes
radeon:
- Hawaii fixes
- display scalar support for non-fixed mode displays
- new firmware format support
- dpm on more asics by default
- GPUVM improvements
- uncached and wc GTT buffers
- BOs > visible VRAM
exynos:
- i80 interface support
- module auto-loading
- ipp driver consolidated.
armada:
- irq handling in crtc layer only
- crtc renumbering
- add component support
- DT interaction changes.
tegra:
- load as module fixes
- eDP bpp and sync polarity fixed
- DSI non-continuous clock mode support
- better support for importing buffers from nouveau
msm:
- mdp5/adq8084 v1.3 hw enablement
- devicetree clk changse
- ifc6410 board working
tda998x:
- component support
- DT documentation update
vmwgfx:
- fix compat shader namespace"
* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (551 commits)
Revert "drm: drop redundant drm_file->is_master"
drm/panel: simple: Use devm_gpiod_get_optional()
drm/dsi: Replace upcasting macro by function
drm/panel: ld9040: Replace upcasting macro by function
drm/exynos: dp: Modify driver to support drm_panel
drm/exynos: Move DP setup into commit()
drm/panel: simple: Add AUO B133HTN01 panel support
drm/panel: simple: Support delays in panel functions
drm/panel: simple: Add proper definition for prepare and unprepare
drm/panel: s6e8aa0: Add proper definition for prepare and unprepare
drm/panel: ld9040: Add proper definition for prepare and unprepare
drm/tegra: Add support for panel prepare and unprepare routines
drm/exynos: dsi: Add support for panel prepare and unprepare routines
drm/exynos: dpi: Add support for panel prepare and unprepare routines
drm/panel: simple: Add dummy prepare and unprepare routines
drm/panel: s6e8aa0: Add dummy prepare and unprepare routines
drm/panel: ld9040: Add dummy prepare and unprepare routines
drm/panel: Provide convenience wrapper for .get_modes()
drm/panel: add .prepare() and .unprepare() functions
drm/panel: simple: Remove simple-panel compatible
...
Diffstat (limited to 'drivers/gpu/drm/i915/i915_gem_execbuffer.c')
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 308 |
1 files changed, 166 insertions, 142 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 3a30133f93e..60998fc4e5b 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c @@ -938,7 +938,7 @@ i915_gem_validate_context(struct drm_device *dev, struct drm_file *file, struct intel_context *ctx = NULL; struct i915_ctx_hang_stats *hs; - if (ring->id != RCS && ctx_id != DEFAULT_CONTEXT_ID) + if (ring->id != RCS && ctx_id != DEFAULT_CONTEXT_HANDLE) return ERR_PTR(-EINVAL); ctx = i915_gem_context_get(file->driver_priv, ctx_id); @@ -975,10 +975,8 @@ i915_gem_execbuffer_move_to_active(struct list_head *vmas, if (obj->base.write_domain) { obj->dirty = 1; obj->last_write_seqno = intel_ring_get_seqno(ring); - /* check for potential scanout */ - if (i915_gem_obj_ggtt_bound(obj) && - i915_gem_obj_to_ggtt(obj)->pin_count) - intel_mark_fb_busy(obj, ring); + + intel_fb_obj_invalidate(obj, ring); /* update for the implicit flush after a batch */ obj->base.write_domain &= ~I915_GEM_GPU_DOMAINS; @@ -1028,6 +1026,163 @@ i915_reset_gen7_sol_offsets(struct drm_device *dev, return 0; } +static int +legacy_ringbuffer_submission(struct drm_device *dev, struct drm_file *file, + struct intel_engine_cs *ring, + struct intel_context *ctx, + struct drm_i915_gem_execbuffer2 *args, + struct list_head *vmas, + struct drm_i915_gem_object *batch_obj, + u64 exec_start, u32 flags) +{ + struct drm_clip_rect *cliprects = NULL; + struct drm_i915_private *dev_priv = dev->dev_private; + u64 exec_len; + int instp_mode; + u32 instp_mask; + int i, ret = 0; + + if (args->num_cliprects != 0) { + if (ring != &dev_priv->ring[RCS]) { + DRM_DEBUG("clip rectangles are only valid with the render ring\n"); + return -EINVAL; + } + + if (INTEL_INFO(dev)->gen >= 5) { + DRM_DEBUG("clip rectangles are only valid on pre-gen5\n"); + return -EINVAL; + } + + if (args->num_cliprects > UINT_MAX / sizeof(*cliprects)) { + DRM_DEBUG("execbuf with %u cliprects\n", + args->num_cliprects); + return -EINVAL; + } + + cliprects = kcalloc(args->num_cliprects, + sizeof(*cliprects), + GFP_KERNEL); + if (cliprects == NULL) { + ret = -ENOMEM; + goto error; + } + + if (copy_from_user(cliprects, + to_user_ptr(args->cliprects_ptr), + sizeof(*cliprects)*args->num_cliprects)) { + ret = -EFAULT; + goto error; + } + } else { + if (args->DR4 == 0xffffffff) { + DRM_DEBUG("UXA submitting garbage DR4, fixing up\n"); + args->DR4 = 0; + } + + if (args->DR1 || args->DR4 || args->cliprects_ptr) { + DRM_DEBUG("0 cliprects but dirt in cliprects fields\n"); + return -EINVAL; + } + } + + ret = i915_gem_execbuffer_move_to_gpu(ring, vmas); + if (ret) + goto error; + + ret = i915_switch_context(ring, ctx); + if (ret) + goto error; + + instp_mode = args->flags & I915_EXEC_CONSTANTS_MASK; + instp_mask = I915_EXEC_CONSTANTS_MASK; + switch (instp_mode) { + case I915_EXEC_CONSTANTS_REL_GENERAL: + case I915_EXEC_CONSTANTS_ABSOLUTE: + case I915_EXEC_CONSTANTS_REL_SURFACE: + if (instp_mode != 0 && ring != &dev_priv->ring[RCS]) { + DRM_DEBUG("non-0 rel constants mode on non-RCS\n"); + ret = -EINVAL; + goto error; + } + + if (instp_mode != dev_priv->relative_constants_mode) { + if (INTEL_INFO(dev)->gen < 4) { + DRM_DEBUG("no rel constants on pre-gen4\n"); + ret = -EINVAL; + goto error; + } + + if (INTEL_INFO(dev)->gen > 5 && + instp_mode == I915_EXEC_CONSTANTS_REL_SURFACE) { + DRM_DEBUG("rel surface constants mode invalid on gen5+\n"); + ret = -EINVAL; + goto error; + } + + /* The HW changed the meaning on this bit on gen6 */ + if (INTEL_INFO(dev)->gen >= 6) + instp_mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE; + } + break; + default: + DRM_DEBUG("execbuf with unknown constants: %d\n", instp_mode); + ret = -EINVAL; + goto error; + } + + if (ring == &dev_priv->ring[RCS] && + instp_mode != dev_priv->relative_constants_mode) { + ret = intel_ring_begin(ring, 4); + if (ret) + goto error; + + intel_ring_emit(ring, MI_NOOP); + intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); + intel_ring_emit(ring, INSTPM); + intel_ring_emit(ring, instp_mask << 16 | instp_mode); + intel_ring_advance(ring); + + dev_priv->relative_constants_mode = instp_mode; + } + + if (args->flags & I915_EXEC_GEN7_SOL_RESET) { + ret = i915_reset_gen7_sol_offsets(dev, ring); + if (ret) + goto error; + } + + exec_len = args->batch_len; + if (cliprects) { + for (i = 0; i < args->num_cliprects; i++) { + ret = i915_emit_box(dev, &cliprects[i], + args->DR1, args->DR4); + if (ret) + goto error; + + ret = ring->dispatch_execbuffer(ring, + exec_start, exec_len, + flags); + if (ret) + goto error; + } + } else { + ret = ring->dispatch_execbuffer(ring, + exec_start, exec_len, + flags); + if (ret) + return ret; + } + + trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags); + + i915_gem_execbuffer_move_to_active(vmas, ring); + i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj); + +error: + kfree(cliprects); + return ret; +} + /** * Find one BSD ring to dispatch the corresponding BSD command. * The Ring ID is returned. @@ -1087,14 +1242,13 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, struct drm_i915_private *dev_priv = dev->dev_private; struct eb_vmas *eb; struct drm_i915_gem_object *batch_obj; - struct drm_clip_rect *cliprects = NULL; struct intel_engine_cs *ring; struct intel_context *ctx; struct i915_address_space *vm; const u32 ctx_id = i915_execbuffer2_get_context_id(*args); - u64 exec_start = args->batch_start_offset, exec_len; - u32 mask, flags; - int ret, mode, i; + u64 exec_start = args->batch_start_offset; + u32 flags; + int ret; bool need_relocs; if (!i915_gem_check_execbuffer(args)) @@ -1138,87 +1292,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, return -EINVAL; } - mode = args->flags & I915_EXEC_CONSTANTS_MASK; - mask = I915_EXEC_CONSTANTS_MASK; - switch (mode) { - case I915_EXEC_CONSTANTS_REL_GENERAL: - case I915_EXEC_CONSTANTS_ABSOLUTE: - case I915_EXEC_CONSTANTS_REL_SURFACE: - if (mode != 0 && ring != &dev_priv->ring[RCS]) { - DRM_DEBUG("non-0 rel constants mode on non-RCS\n"); - return -EINVAL; - } - - if (mode != dev_priv->relative_constants_mode) { - if (INTEL_INFO(dev)->gen < 4) { - DRM_DEBUG("no rel constants on pre-gen4\n"); - return -EINVAL; - } - - if (INTEL_INFO(dev)->gen > 5 && - mode == I915_EXEC_CONSTANTS_REL_SURFACE) { - DRM_DEBUG("rel surface constants mode invalid on gen5+\n"); - return -EINVAL; - } - - /* The HW changed the meaning on this bit on gen6 */ - if (INTEL_INFO(dev)->gen >= 6) - mask &= ~I915_EXEC_CONSTANTS_REL_SURFACE; - } - break; - default: - DRM_DEBUG("execbuf with unknown constants: %d\n", mode); - return -EINVAL; - } - if (args->buffer_count < 1) { DRM_DEBUG("execbuf with %d buffers\n", args->buffer_count); return -EINVAL; } - if (args->num_cliprects != 0) { - if (ring != &dev_priv->ring[RCS]) { - DRM_DEBUG("clip rectangles are only valid with the render ring\n"); - return -EINVAL; - } - - if (INTEL_INFO(dev)->gen >= 5) { - DRM_DEBUG("clip rectangles are only valid on pre-gen5\n"); - return -EINVAL; - } - - if (args->num_cliprects > UINT_MAX / sizeof(*cliprects)) { - DRM_DEBUG("execbuf with %u cliprects\n", - args->num_cliprects); - return -EINVAL; - } - - cliprects = kcalloc(args->num_cliprects, - sizeof(*cliprects), - GFP_KERNEL); - if (cliprects == NULL) { - ret = -ENOMEM; - goto pre_mutex_err; - } - - if (copy_from_user(cliprects, - to_user_ptr(args->cliprects_ptr), - sizeof(*cliprects)*args->num_cliprects)) { - ret = -EFAULT; - goto pre_mutex_err; - } - } else { - if (args->DR4 == 0xffffffff) { - DRM_DEBUG("UXA submitting garbage DR4, fixing up\n"); - args->DR4 = 0; - } - - if (args->DR1 || args->DR4 || args->cliprects_ptr) { - DRM_DEBUG("0 cliprects but dirt in cliprects fields\n"); - return -EINVAL; - } - } - intel_runtime_pm_get(dev_priv); ret = i915_mutex_lock_interruptible(dev); @@ -1322,63 +1400,11 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data, else exec_start += i915_gem_obj_offset(batch_obj, vm); - ret = i915_gem_execbuffer_move_to_gpu(ring, &eb->vmas); + ret = legacy_ringbuffer_submission(dev, file, ring, ctx, + args, &eb->vmas, batch_obj, exec_start, flags); if (ret) goto err; - ret = i915_switch_context(ring, ctx); - if (ret) - goto err; - - if (ring == &dev_priv->ring[RCS] && - mode != dev_priv->relative_constants_mode) { - ret = intel_ring_begin(ring, 4); - if (ret) - goto err; - - intel_ring_emit(ring, MI_NOOP); - intel_ring_emit(ring, MI_LOAD_REGISTER_IMM(1)); - intel_ring_emit(ring, INSTPM); - intel_ring_emit(ring, mask << 16 | mode); - intel_ring_advance(ring); - - dev_priv->relative_constants_mode = mode; - } - - if (args->flags & I915_EXEC_GEN7_SOL_RESET) { - ret = i915_reset_gen7_sol_offsets(dev, ring); - if (ret) - goto err; - } - - - exec_len = args->batch_len; - if (cliprects) { - for (i = 0; i < args->num_cliprects; i++) { - ret = i915_emit_box(dev, &cliprects[i], - args->DR1, args->DR4); - if (ret) - goto err; - - ret = ring->dispatch_execbuffer(ring, - exec_start, exec_len, - flags); - if (ret) - goto err; - } - } else { - ret = ring->dispatch_execbuffer(ring, - exec_start, exec_len, - flags); - if (ret) - goto err; - } - - trace_i915_gem_ring_dispatch(ring, intel_ring_get_seqno(ring), flags); - - i915_gem_execbuffer_move_to_active(&eb->vmas, ring); - i915_gem_execbuffer_retire_commands(dev, file, ring, batch_obj); - err: /* the request owns the ref now */ i915_gem_context_unreference(ctx); @@ -1387,8 +1413,6 @@ err: mutex_unlock(&dev->struct_mutex); pre_mutex_err: - kfree(cliprects); - /* intel_gpu_busy should also get a ref, so it will free when the device * is really idle. */ intel_runtime_pm_put(dev_priv); @@ -1525,7 +1549,7 @@ i915_gem_execbuffer2(struct drm_device *dev, void *data, ret = i915_gem_do_execbuffer(dev, data, file, args, exec2_list); if (!ret) { /* Copy the new buffer offsets back to the user's exec list. */ - struct drm_i915_gem_exec_object2 *user_exec_list = + struct drm_i915_gem_exec_object2 __user *user_exec_list = to_user_ptr(args->buffers_ptr); int i; |