|
@@ -25,6 +25,36 @@
|
|
|
#include <drm/i915_drm.h>
|
|
|
#include "i915_drv.h"
|
|
|
|
|
|
+/**
|
|
|
+ * DOC: fence register handling
|
|
|
+ *
|
|
|
+ * Important to avoid confusions: "fences" in the i915 driver are not execution
|
|
|
+ * fences used to track command completion but hardware detiler objects which
|
|
|
+ * wrap a given range of the global GTT. Each platform has only a fairly limited
|
|
|
+ * set of these objects.
|
|
|
+ *
|
|
|
+ * Fences are used to detile GTT memory mappings. They're also connected to the
|
|
|
+ * hardware frontbuffer render tracking and hence interract with frontbuffer
|
|
|
+ * conmpression. Furthermore on older platforms fences are required for tiled
|
|
|
+ * objects used by the display engine. They can also be used by the render
|
|
|
+ * engine - they're required for blitter commands and are optional for render
|
|
|
+ * commands. But on gen4+ both display (with the exception of fbc) and rendering
|
|
|
+ * have their own tiling state bits and don't need fences.
|
|
|
+ *
|
|
|
+ * Also note that fences only support X and Y tiling and hence can't be used for
|
|
|
+ * the fancier new tiling formats like W, Ys and Yf.
|
|
|
+ *
|
|
|
+ * Finally note that because fences are such a restricted resource they're
|
|
|
+ * dynamically associated with objects. Furthermore fence state is committed to
|
|
|
+ * the hardware lazily to avoid unecessary stalls on gen2/3. Therefore code must
|
|
|
+ * explictly call i915_gem_object_get_fence() to synchronize fencing status
|
|
|
+ * for cpu access. Also note that some code wants an unfenced view, for those
|
|
|
+ * cases the fence can be removed forcefully with i915_gem_object_put_fence().
|
|
|
+ *
|
|
|
+ * Internally these functions will synchronize with userspace access by removing
|
|
|
+ * CPU ptes into GTT mmaps (not the GTT ptes themselves) as needed.
|
|
|
+ */
|
|
|
+
|
|
|
static void i965_write_fence_reg(struct drm_device *dev, int reg,
|
|
|
struct drm_i915_gem_object *obj)
|
|
|
{
|
|
@@ -247,6 +277,17 @@ i915_gem_object_wait_fence(struct drm_i915_gem_object *obj)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * i915_gem_object_put_fence - force-remove fence for an object
|
|
|
+ * @obj: object to map through a fence reg
|
|
|
+ *
|
|
|
+ * This function force-removes any fence from the given object, which is useful
|
|
|
+ * if the kernel wants to do untiled GTT access.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ *
|
|
|
+ * 0 on success, negative error code on failure.
|
|
|
+ */
|
|
|
int
|
|
|
i915_gem_object_put_fence(struct drm_i915_gem_object *obj)
|
|
|
{
|
|
@@ -322,6 +363,10 @@ deadlock:
|
|
|
* and tiling format.
|
|
|
*
|
|
|
* For an untiled surface, this removes any existing fence.
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ *
|
|
|
+ * 0 on success, negative error code on failure.
|
|
|
*/
|
|
|
int
|
|
|
i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
|
|
@@ -374,6 +419,21 @@ i915_gem_object_get_fence(struct drm_i915_gem_object *obj)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * i915_gem_object_pin_fence - pin fencing state
|
|
|
+ * @obj: object to pin fencing for
|
|
|
+ *
|
|
|
+ * This pins the fencing state (whether tiled or untiled) to make sure the
|
|
|
+ * object is ready to be used as a scanout target. Fencing status must be
|
|
|
+ * synchronize first by calling i915_gem_object_get_fence():
|
|
|
+ *
|
|
|
+ * The resulting fence pin reference must be released again with
|
|
|
+ * i915_gem_object_unpin_fence().
|
|
|
+ *
|
|
|
+ * Returns:
|
|
|
+ *
|
|
|
+ * True if the object has a fence, false otherwise.
|
|
|
+ */
|
|
|
bool
|
|
|
i915_gem_object_pin_fence(struct drm_i915_gem_object *obj)
|
|
|
{
|
|
@@ -390,6 +450,14 @@ i915_gem_object_pin_fence(struct drm_i915_gem_object *obj)
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * i915_gem_object_unpin_fence - unpin fencing state
|
|
|
+ * @obj: object to unpin fencing for
|
|
|
+ *
|
|
|
+ * This releases the fence pin reference acquired through
|
|
|
+ * i915_gem_object_pin_fence. It will handle both objects with and without an
|
|
|
+ * attached fence correctly, callers do not need to distinguish this.
|
|
|
+ */
|
|
|
void
|
|
|
i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj)
|
|
|
{
|
|
@@ -400,6 +468,13 @@ i915_gem_object_unpin_fence(struct drm_i915_gem_object *obj)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+/**
|
|
|
+ * i915_gem_restore_fences - restore fence state
|
|
|
+ * @dev: DRM device
|
|
|
+ *
|
|
|
+ * Restore the hw fence state to match the software tracking again, to be called
|
|
|
+ * after a gpu reset and on resume.
|
|
|
+ */
|
|
|
void i915_gem_restore_fences(struct drm_device *dev)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|