|
@@ -1022,6 +1022,12 @@ static void guc_policies_init(struct guc_policies *policies)
|
|
|
policies->is_valid = 1;
|
|
|
}
|
|
|
|
|
|
+/*
|
|
|
+ * The first 80 dwords of the register state context, containing the
|
|
|
+ * execlists and ppgtt registers.
|
|
|
+ */
|
|
|
+#define LR_HW_CONTEXT_SIZE (80 * sizeof(u32))
|
|
|
+
|
|
|
static int guc_ads_create(struct intel_guc *guc)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = guc_to_i915(guc);
|
|
@@ -1036,6 +1042,8 @@ static int guc_ads_create(struct intel_guc *guc)
|
|
|
} __packed *blob;
|
|
|
struct intel_engine_cs *engine;
|
|
|
enum intel_engine_id id;
|
|
|
+ const u32 skipped_offset = LRC_HEADER_PAGES * PAGE_SIZE;
|
|
|
+ const u32 skipped_size = LRC_PPHWSP_SZ * PAGE_SIZE + LR_HW_CONTEXT_SIZE;
|
|
|
u32 base;
|
|
|
|
|
|
GEM_BUG_ON(guc->ads_vma);
|
|
@@ -1066,13 +1074,20 @@ static int guc_ads_create(struct intel_guc *guc)
|
|
|
* engines after a reset. Here we use the Render ring default
|
|
|
* context, which must already exist and be pinned in the GGTT,
|
|
|
* so its address won't change after we've told the GuC where
|
|
|
- * to find it.
|
|
|
+ * to find it. Note that we have to skip our header (1 page),
|
|
|
+ * because our GuC shared data is there.
|
|
|
*/
|
|
|
blob->ads.golden_context_lrca =
|
|
|
- dev_priv->engine[RCS]->status_page.ggtt_offset;
|
|
|
+ guc_ggtt_offset(dev_priv->kernel_context->engine[RCS].state) + skipped_offset;
|
|
|
|
|
|
+ /*
|
|
|
+ * The GuC expects us to exclude the portion of the context image that
|
|
|
+ * it skips from the size it is to read. It starts reading from after
|
|
|
+ * the execlist context (so skipping the first page [PPHWSP] and 80
|
|
|
+ * dwords). Weird guc is weird.
|
|
|
+ */
|
|
|
for_each_engine(engine, dev_priv, id)
|
|
|
- blob->ads.eng_state_size[engine->guc_id] = engine->context_size;
|
|
|
+ blob->ads.eng_state_size[engine->guc_id] = engine->context_size - skipped_size;
|
|
|
|
|
|
base = guc_ggtt_offset(vma);
|
|
|
blob->ads.scheduler_policies = base + ptr_offset(blob, policies);
|