From: Armin Reese <armin.c.reese@xxxxxxxxx> Golden context batch buffers now contain a set of offsets at which contents can optionally be modified. This allows the driver to customize the GC batch for various chipsets in a GEN family. v1 - Originally, the i915 driver was only allowed to insert MI_BATCH_BUFFER_END commands at locations specified by "alternate_bbend_offsets". v2 - The previous "alternate_bbend_offsets" field has been generalized in this version to allow the driver to modify ranges of DWORDs in the golden context BB. These ranges are described in "mod_values" structs. Signed-off-by: Armin Reese <armin.c.reese@xxxxxxxxx> Signed-off-by: Arun Siluvery <arun.siluvery@xxxxxxxxxxxxxxx> --- drivers/gpu/drm/i915/i915_gem_render_state.c | 65 +++++++++++++++++++++++++-- drivers/gpu/drm/i915/i915_gem_render_state.h | 7 +++ drivers/gpu/drm/i915/intel_renderstate.h | 6 ++- drivers/gpu/drm/i915/intel_renderstate_gen6.c | 4 ++ drivers/gpu/drm/i915/intel_renderstate_gen7.c | 4 ++ drivers/gpu/drm/i915/intel_renderstate_gen8.c | 4 ++ drivers/gpu/drm/i915/intel_renderstate_gen9.c | 4 ++ 7 files changed, 89 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c index a0201fc..818233d 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.c +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c @@ -45,6 +45,49 @@ render_state_get_rodata(struct drm_device *dev, const int gen) return NULL; } +/** + * Offsets for golden context "value modifications" defined in + * intel_renderstate_genx.c are locations in the batch buffer + * where the driver is allowed to modify one or more DWORDs + * to customize instructions for the GEN platform present. + */ +static int gc_modify_values(struct drm_device *dev, + const struct intel_renderstate_rodata *rodata, + u32 *d) +{ + /* Init index to "nothing to modify" value */ + int mod_index = -1; + int mod_val[1]; + int num_vals = 0; + + /* Write required value(s) to the specified offset(s) */ + if ((mod_index >= 0) && + (num_vals > 0)) { + if (mod_index < rodata->mod_value_items) { + int mod_offset, mod_max_cnt, i; + + mod_offset = + rodata->mod_values[mod_index].offset; + mod_max_cnt = + rodata->mod_values[mod_index].max_cnt; + + /* Check for DWORD aligned address, et al */ + if ((num_vals > mod_max_cnt) || + (mod_offset <= 0) || + (mod_offset > PAGE_SIZE - (mod_max_cnt * sizeof(u32))) || + ((mod_offset & (sizeof(u32) - 1)) != 0)) + return -EINVAL; + + for (i = 0; i < num_vals; i++) { + d[(mod_offset/sizeof(u32)) + i] = mod_val[i]; + } + } else + return -EINVAL; + } + + return 0; +} + static int render_state_init(struct render_state *so, struct drm_device *dev) { int ret; @@ -73,7 +116,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 +132,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 +152,21 @@ static int render_state_setup(struct render_state *so) d[i++] = s; } + + /* Any golden context BB entries to modify? */ + if ((rodata->mod_values[0].offset != -1) && + (rodata->mod_values[0].max_cnt > 0)) + ret = gc_modify_values(dev, rodata, d); + else + ret = 0; + kunmap(page); + if (ret) { + DRM_ERROR("error modifying golden context batch buffer contents\n"); + return ret; + } + ret = i915_gem_object_set_to_gtt_domain(so->obj, false); if (ret) return ret; @@ -143,7 +200,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 7aa7372..0898559 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.h +++ b/drivers/gpu/drm/i915/i915_gem_render_state.h @@ -26,8 +26,15 @@ #include <linux/types.h> +struct mod_value_info { + u32 offset; + u32 max_cnt; +}; + struct intel_renderstate_rodata { const u32 *reloc; + const struct mod_value_info *mod_values; + const u32 mod_value_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..1a80279 100644 --- a/drivers/gpu/drm/i915/intel_renderstate.h +++ b/drivers/gpu/drm/i915/intel_renderstate.h @@ -34,8 +34,12 @@ extern const struct intel_renderstate_rodata gen9_null_state; #define RO_RENDERSTATE(_g) \ const struct intel_renderstate_rodata gen ## _g ## _null_state = { \ .reloc = gen ## _g ## _null_state_relocs, \ + .mod_values = gen ## _g ## _mod_values, \ + .mod_value_items = (sizeof(gen ## _g ## _mod_values) / \ + sizeof(struct mod_value_info)), \ .batch = gen ## _g ## _null_state_batch, \ - .batch_items = sizeof(gen ## _g ## _null_state_batch)/4, \ + .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 11c8e7b..ef29069 100644 --- a/drivers/gpu/drm/i915/intel_renderstate_gen6.c +++ b/drivers/gpu/drm/i915/intel_renderstate_gen6.c @@ -34,6 +34,10 @@ static const u32 gen6_null_state_relocs[] = { -1, }; +static const struct mod_value_info gen6_mod_values[] = { + {-1, 0}, +}; + static const u32 gen6_null_state_batch[] = { 0x69040000, 0x790d0001, diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen7.c b/drivers/gpu/drm/i915/intel_renderstate_gen7.c index 6551806..408e901 100644 --- a/drivers/gpu/drm/i915/intel_renderstate_gen7.c +++ b/drivers/gpu/drm/i915/intel_renderstate_gen7.c @@ -33,6 +33,10 @@ static const u32 gen7_null_state_relocs[] = { -1, }; +static const struct mod_value_info gen7_mod_values[] = { + {-1, 0}, +}; + static const u32 gen7_null_state_batch[] = { 0x69040000, 0x61010008, diff --git a/drivers/gpu/drm/i915/intel_renderstate_gen8.c b/drivers/gpu/drm/i915/intel_renderstate_gen8.c index 95288a3..d5b1383 100644 --- a/drivers/gpu/drm/i915/intel_renderstate_gen8.c +++ b/drivers/gpu/drm/i915/intel_renderstate_gen8.c @@ -33,6 +33,10 @@ static const u32 gen8_null_state_relocs[] = { -1, }; +static const struct mod_value_info gen8_mod_values[] = { + {-1, 0}, +}; + 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 16a7ec2..7cb43a2 100644 --- a/drivers/gpu/drm/i915/intel_renderstate_gen9.c +++ b/drivers/gpu/drm/i915/intel_renderstate_gen9.c @@ -33,6 +33,10 @@ static const u32 gen9_null_state_relocs[] = { -1, }; +static const struct mod_value_info gen9_mod_values[] = { + {-1, 0}, +}; + static const u32 gen9_null_state_batch[] = { 0x7a000004, 0x01000000, -- 1.9.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx