From: Armin Reese <armin.c.re...@intel.com>

Golden context batch buffers now can contain a set of offsets in
which to optionally place MI_BATCH_BUFFER_END commands.  This
allows the driver to customize the GC batch for various chipsets
in a family by requesting that the GC BB exit early for one chipset
to prevent execution of GPU commands intended for another chipset
in the same GEN family.

Signed-off-by: Armin Reese <armin.c.re...@intel.com>
---
 drivers/gpu/drm/i915/i915_gem_render_state.c  | 59 +++++++++++++++++++++++++--
 drivers/gpu/drm/i915/i915_gem_render_state.h  |  2 +
 drivers/gpu/drm/i915/intel_renderstate.h      | 14 +++++--
 drivers/gpu/drm/i915/intel_renderstate_gen6.c |  6 ++-
 drivers/gpu/drm/i915/intel_renderstate_gen7.c |  6 ++-
 drivers/gpu/drm/i915/intel_renderstate_gen8.c |  4 ++
 drivers/gpu/drm/i915/intel_renderstate_gen9.c | 29 +++++++++++--
 7 files changed, 106 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c 
b/drivers/gpu/drm/i915/i915_gem_render_state.c
index 98dcd94..80aeff9 100644
--- a/drivers/gpu/drm/i915/i915_gem_render_state.c
+++ b/drivers/gpu/drm/i915/i915_gem_render_state.c
@@ -45,6 +45,44 @@ render_state_get_rodata(struct drm_device *dev, const int 
gen)
        return NULL;
 }
 
+/**
+ * Alternate batch buffer end offsets defined in intel_renderstate_genx.c
+ * are locations in the golden context batch buffer where MI_BATCH_BUFFER_END
+ * commands can be optionally inserted.  BB end commands can be added to
+ * terminate the GC BB early and thus customize the BB for product variations
+ * in a given GEN family.
+ */
+static int insert_alternate_bbend(struct drm_device *dev,
+                               const struct intel_renderstate_rodata *rodata,
+                               u32 *d)
+{
+       int index = -1; /* Default to no alternate bbend index */
+
+       /* For GEN9, exit golden context BB before executing all commands */
+       if (IS_GEN9(dev))
+               index = 0;
+
+       /* Write MI_BATCH_BUFFER_END at valid location */
+       if (index >= 0) {
+               if (index < rodata->alternate_bbend_items) {
+                       int bbend_offset;
+
+                       bbend_offset = rodata->alternate_bbend_offsets[index];
+
+                       /* Check for DWORD aligned address, et al */
+                       if ((bbend_offset <= 0) ||
+                           (bbend_offset > PAGE_SIZE - sizeof(u32)) ||
+                           ((bbend_offset & (sizeof(u32) - 1)) != 0))
+                               return -EINVAL;
+
+                       d[bbend_offset/sizeof(u32)] = MI_BATCH_BUFFER_END;
+               } else
+                       return -EINVAL;
+       }
+
+       return 0;
+}
+
 static int render_state_init(struct render_state *so, struct drm_device *dev)
 {
        int ret;
@@ -73,7 +111,7 @@ free_gem:
        return ret;
 }
 
-static int render_state_setup(struct render_state *so)
+static int render_state_setup(struct render_state *so, struct drm_device *dev)
 {
        const struct intel_renderstate_rodata *rodata = so->rodata;
        unsigned int i = 0, reloc_index = 0;
@@ -89,10 +127,11 @@ static int render_state_setup(struct render_state *so)
        d = kmap(page);
 
        while (i < rodata->batch_items) {
-               u32 s = rodata->batch[i];
+               u32 s = rodata->batch[i];       /* DWORD from R/O batch */
 
                if (i * 4  == rodata->reloc[reloc_index]) {
-                       u64 r = s + so->ggtt_offset;
+                       u64 r = s + /* Object offset stored in reloc DWORD */
+                               so->ggtt_offset; /* Batch buffer gfx offset */
                        s = lower_32_bits(r);
                        if (so->gen >= 8) {
                                if (i + 1 >= rodata->batch_items ||
@@ -108,8 +147,20 @@ static int render_state_setup(struct render_state *so)
 
                d[i++] = s;
        }
+
+       /* Any alternate BB end entries? */
+       if (rodata->alternate_bbend_offsets[0] != -1)
+               ret = insert_alternate_bbend(dev, rodata, d);
+       else
+               ret = 0;
+
        kunmap(page);
 
+       if (ret) {
+               DRM_ERROR("invalid alternate batch buffer end\n");
+               return ret;
+       }
+
        ret = i915_gem_object_set_to_gtt_domain(so->obj, false);
        if (ret)
                return ret;
@@ -143,7 +194,7 @@ int i915_gem_render_state_prepare(struct intel_engine_cs 
*ring,
        if (so->rodata == NULL)
                return 0;
 
-       ret = render_state_setup(so);
+       ret = render_state_setup(so, ring->dev);
        if (ret) {
                i915_gem_render_state_fini(so);
                return ret;
diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.h 
b/drivers/gpu/drm/i915/i915_gem_render_state.h
index c44961e..3f540c8 100644
--- a/drivers/gpu/drm/i915/i915_gem_render_state.h
+++ b/drivers/gpu/drm/i915/i915_gem_render_state.h
@@ -28,6 +28,8 @@
 
 struct intel_renderstate_rodata {
        const u32 *reloc;
+       const u32 *alternate_bbend_offsets;
+       const u32 alternate_bbend_items;
        const u32 *batch;
        const u32 batch_items;
 };
diff --git a/drivers/gpu/drm/i915/intel_renderstate.h 
b/drivers/gpu/drm/i915/intel_renderstate.h
index 5bd6985..8d5d975 100644
--- a/drivers/gpu/drm/i915/intel_renderstate.h
+++ b/drivers/gpu/drm/i915/intel_renderstate.h
@@ -31,11 +31,17 @@ extern const struct intel_renderstate_rodata 
gen7_null_state;
 extern const struct intel_renderstate_rodata gen8_null_state;
 extern const struct intel_renderstate_rodata gen9_null_state;
 
-#define RO_RENDERSTATE(_g)                                             \
+#define RO_RENDERSTATE(_g) \
        const struct intel_renderstate_rodata gen ## _g ## _null_state = { \
-               .reloc = gen ## _g ## _null_state_relocs,               \
-               .batch = gen ## _g ## _null_state_batch,                \
-               .batch_items = sizeof(gen ## _g ## _null_state_batch)/4, \
+               .reloc = gen ## _g ## _null_state_relocs, \
+               .alternate_bbend_offsets = \
+                       gen ## _g ## _alternate_bbend_offsets, \
+               .alternate_bbend_items = \
+                       sizeof(gen ## _g ## _alternate_bbend_offsets) / \
+                       sizeof(u32), \
+               .batch = gen ## _g ## _null_state_batch, \
+               .batch_items = sizeof(gen ## _g ## _null_state_batch) / \
+                               sizeof(u32) \
        }
 
 #endif /* INTEL_RENDERSTATE_H */
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen6.c 
b/drivers/gpu/drm/i915/intel_renderstate_gen6.c
index c2568a7..95e30f8 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen6.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen6.c
@@ -29,7 +29,11 @@ static const u32 gen6_null_state_relocs[] = {
        0x0000002c,
        0x000001e0,
        0x000001e4,
-       -1,
+       -1
+};
+
+static const u32 gen6_alternate_bbend_offsets[] = {
+       -1
 };
 
 static const u32 gen6_null_state_batch[] = {
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen7.c 
b/drivers/gpu/drm/i915/intel_renderstate_gen7.c
index e14aec5..c22b89f 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen7.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen7.c
@@ -28,7 +28,11 @@ static const u32 gen7_null_state_relocs[] = {
        0x00000010,
        0x00000018,
        0x000001ec,
-       -1,
+       -1
+};
+
+static const u32 gen7_alternate_bbend_offsets[] = {
+       -1
 };
 
 static const u32 gen7_null_state_batch[] = {
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen8.c 
b/drivers/gpu/drm/i915/intel_renderstate_gen8.c
index 88991e2..282012e 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen8.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen8.c
@@ -31,6 +31,10 @@ static const u32 gen8_null_state_relocs[] = {
        -1,
 };
 
+static const u32 gen8_alternate_bbend_offsets[] = {
+       -1
+};
+
 static const u32 gen8_null_state_batch[] = {
        0x7a000004,
        0x01000000,
diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen9.c 
b/drivers/gpu/drm/i915/intel_renderstate_gen9.c
index e1ea838..eca1384 100644
--- a/drivers/gpu/drm/i915/intel_renderstate_gen9.c
+++ b/drivers/gpu/drm/i915/intel_renderstate_gen9.c
@@ -31,6 +31,11 @@ static const u32 gen9_null_state_relocs[] = {
        -1,
 };
 
+static const u32 gen9_alternate_bbend_offsets[] = {
+       0x00000dac,
+       -1
+};
+
 static const u32 gen9_null_state_batch[] = {
        0x7a000004,
        0x01000000,
@@ -867,9 +872,9 @@ static const u32 gen9_null_state_batch[] = {
        0x00000000,
        0x680b0001,
        0x780e0000,
-       0x00000dc1,
-       0x78240000,
        0x00000e01,
+       0x78240000,
+       0x00000e41,
        0x784f0000,
        0x80000100,
        0x784d0000,
@@ -887,9 +892,9 @@ static const u32 gen9_null_state_batch[] = {
        0x780f0000,
        0x00000000,
        0x78230000,
-       0x00000e60,
+       0x00000ea0,
        0x78210000,
-       0x00000e80,
+       0x00000ec0,
        0x78260000,
        0x00000000,
        0x78270000,
@@ -907,11 +912,27 @@ static const u32 gen9_null_state_batch[] = {
        0x00000001,
        0x00000000,
        0x00000000,
+       0x00000000,      /* alternate bbend */
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
        0x05000000,      /* cmds end */
        0x00000000,
        0x00000000,
        0x00000000,
        0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
+       0x00000000,
        0x00000000,      /* state start */
        0x00000000,
        0x3f800000,
-- 
1.9.1

_______________________________________________
Intel-gfx mailing list
Intel-gfx@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/intel-gfx

Reply via email to