From: Dave Gordon <david.s.gordon@xxxxxxxxx> The GuC firmware uses this for various purposes; it seems to be required for preemption to work. For: VIZ-2021 Signed-off-by: Dave Gordon <david.s.gordon@xxxxxxxxx> --- drivers/gpu/drm/i915/i915_guc_reg.h | 1 + drivers/gpu/drm/i915/i915_guc_submission.c | 57 ++++++++++++++++++++++- drivers/gpu/drm/i915/intel_guc.h | 2 + drivers/gpu/drm/i915/intel_guc_fwif.h | 73 +++++++++++++++++++++++++++++- drivers/gpu/drm/i915/intel_guc_loader.c | 14 ++++-- 5 files changed, 141 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/i915/i915_guc_reg.h b/drivers/gpu/drm/i915/i915_guc_reg.h index b51b828..10947de 100644 --- a/drivers/gpu/drm/i915/i915_guc_reg.h +++ b/drivers/gpu/drm/i915/i915_guc_reg.h @@ -40,6 +40,7 @@ #define GS_MIA_CORE_STATE (1 << GS_MIA_SHIFT) #define SOFT_SCRATCH(n) (0xc180 + ((n) * 4)) +#define SOFT_SCRATCH_COUNT 16 #define UOS_RSA_SCRATCH(i) (0xc200 + (i) * 4) #define UOS_RSA_SCRATCH_MAX_COUNT 64 diff --git a/drivers/gpu/drm/i915/i915_guc_submission.c b/drivers/gpu/drm/i915/i915_guc_submission.c index d11bba9..035f126 100644 --- a/drivers/gpu/drm/i915/i915_guc_submission.c +++ b/drivers/gpu/drm/i915/i915_guc_submission.c @@ -611,9 +611,10 @@ static int guc_add_workqueue_item(struct i915_guc_client *gc, wqi->context_desc = (u32)intel_lr_context_descriptor(rq->ctx, rq->ring); /* The GuC firmware wants the tail index in QWords, not bytes */ + WARN_ON(rq->ringbuf->tail & 7); tail = rq->ringbuf->tail >> 3; wqi->ring_tail = tail << WQ_RING_TAIL_SHIFT; - wqi->fence_id = 0; /*XXX: what fence to be here */ + wqi->fence_id = rq->seqno; /*XXX: what fence to be here */ kunmap_atomic(base); @@ -926,6 +927,57 @@ static void guc_create_log(struct intel_guc *guc) guc->log_flags = (offset << GUC_LOG_BUF_ADDR_SHIFT) | flags; } +static void guc_create_addon(struct intel_guc *guc) +{ + struct drm_i915_private *dev_priv = guc_to_i915(guc); + struct drm_i915_gem_object *obj; + struct guc_ads *ads; + struct intel_engine_cs *ring; + struct page *page; + u32 size, i; + + /* The ads obj includes the struct itself, plus memory for GuC to use + * internally to save MMIO registers and states when reset or PM state + * change happens. */ + size = PAGE_ALIGN(sizeof(struct guc_ads)) + + PAGE_ALIGN(sizeof(struct guc_mmio_reg_state)) + + GUC_MAX_S3_SAVE_SPACE_PAGES * PAGE_SIZE; + + obj = guc->ads_obj; + if (!obj) { + obj = gem_allocate_guc_obj(dev_priv->dev, size); + if (!obj) + return; + + guc->ads_obj = obj; + } + + page = i915_gem_object_get_page(obj, 0); + ads = kmap_atomic(page); + if (!ads) { + guc->ads_obj = NULL; + gem_release_guc_obj(obj); + return; + } + + /* TODO: Fill up the register table here */ + ads->mmio_reg_state_addr = i915_gem_obj_ggtt_offset(obj) + + PAGE_ALIGN(sizeof(struct guc_ads)); + + ads->guc_state_saved_buffer = ads->mmio_reg_state_addr + + PAGE_ALIGN(sizeof(struct guc_mmio_reg_state)); + + /* TODO: a Goldern Context is needed by GuC to initialize lrc context + * after reset. Here we use the render ring default context. */ + ring = &dev_priv->ring[RCS]; + ads->golden_context_lrca = ring->status_page.gfx_addr; + + for_each_ring(ring, dev_priv, i) + ads->eng_state_size[i] = intel_lr_context_size(ring); + + kunmap_atomic(ads); +} + /* * Set up the memory resources to be shared with the GuC. At this point, * we require just one object that can be mapped through the GGTT. @@ -953,6 +1005,7 @@ int i915_guc_submission_init(struct drm_device *dev) ida_init(&guc->ctx_ids); guc_create_log(guc); + guc_create_addon(guc); return 0; } @@ -1000,6 +1053,8 @@ void i915_guc_submission_fini(struct drm_device *dev) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_guc *guc = &dev_priv->guc; + gem_release_guc_obj(dev_priv->guc.ads_obj); + guc->ads_obj = NULL; gem_release_guc_obj(dev_priv->guc.log_obj); guc->log_obj = NULL; diff --git a/drivers/gpu/drm/i915/intel_guc.h b/drivers/gpu/drm/i915/intel_guc.h index 0793713..150d596 100644 --- a/drivers/gpu/drm/i915/intel_guc.h +++ b/drivers/gpu/drm/i915/intel_guc.h @@ -90,6 +90,8 @@ struct intel_guc { uint32_t log_flags; struct drm_i915_gem_object *log_obj; + struct drm_i915_gem_object *ads_obj; + struct drm_i915_gem_object *ctx_pool_obj; struct ida ctx_ids; diff --git a/drivers/gpu/drm/i915/intel_guc_fwif.h b/drivers/gpu/drm/i915/intel_guc_fwif.h index 110496a..9f5be1d 100644 --- a/drivers/gpu/drm/i915/intel_guc_fwif.h +++ b/drivers/gpu/drm/i915/intel_guc_fwif.h @@ -81,11 +81,14 @@ #define GUC_CTL_CTXINFO 0 #define GUC_CTL_CTXNUM_IN16_SHIFT 0 #define GUC_CTL_BASE_ADDR_SHIFT 12 + #define GUC_CTL_ARAT_HIGH 1 #define GUC_CTL_ARAT_LOW 2 + #define GUC_CTL_DEVICE_INFO 3 #define GUC_CTL_GTTYPE_SHIFT 0 #define GUC_CTL_COREFAMILY_SHIFT 7 + #define GUC_CTL_LOG_PARAMS 4 #define GUC_LOG_VALID (1 << 0) #define GUC_LOG_NOTIFY_ON_HALF_FULL (1 << 1) @@ -97,9 +100,12 @@ #define GUC_LOG_ISR_PAGES 3 #define GUC_LOG_ISR_SHIFT 9 #define GUC_LOG_BUF_ADDR_SHIFT 12 + #define GUC_CTL_PAGE_FAULT_CONTROL 5 + #define GUC_CTL_WA 6 #define GUC_CTL_WA_UK_BY_DRIVER (1 << 3) + #define GUC_CTL_FEATURE 7 #define GUC_CTL_VCS2_ENABLED (1 << 0) #define GUC_CTL_KERNEL_SUBMISSIONS (1 << 1) @@ -109,6 +115,7 @@ #define GUC_CTL_PREEMPTION_LOG (1 << 5) #define GUC_CTL_ENABLE_SLPC (1 << 7) #define GUC_CTL_RESET_ON_PREMPT_FAILURE (1 << 8) + #define GUC_CTL_DEBUG 8 #define GUC_LOG_VERBOSITY_SHIFT 0 #define GUC_LOG_VERBOSITY_LOW (0 << GUC_LOG_VERBOSITY_SHIFT) @@ -118,9 +125,19 @@ /* Verbosity range-check limits, without the shift */ #define GUC_LOG_VERBOSITY_MIN 0 #define GUC_LOG_VERBOSITY_MAX 3 -#define GUC_CTL_RSRVD 9 +#define GUC_LOG_VERBOSITY_MASK 0x0000000f +#define GUC_LOG_DESTINATION_MASK (3 << 4) +#define GUC_LOG_DISABLED (1 << 6) +#define GUC_PROFILE_ENABLED (1 << 7) +#define GUC_WQ_TRACK_ENABLED (1 << 8) +#define GUC_ADS_ENABLED (1 << 9) +#define GUC_DEBUG_RESERVED (1 << 10) +#define GUC_ADS_ADDR_SHIFT 11 +#define GUC_ADS_ADDR_MASK 0xfffff800 + +#define GUC_CTL_RSRVD 9 // GfxAddressKmSharedData? -#define GUC_CTL_MAX_DWORDS (GUC_CTL_RSRVD + 1) +#define GUC_CTL_MAX_DWORDS (SOFT_SCRATCH_COUNT - 2) /* [1..14] */ /** * DOC: GuC Firmware Layout @@ -304,16 +321,68 @@ struct guc_context_desc { #define GUC_POWER_D2 3 #define GUC_POWER_D3 4 +/* GuC Additional Data Struct */ + +#define GUC_REGSET_FLAGS_NONE 0x0 +#define GUC_REGSET_POWERCYCLE 0x1 +#define GUC_REGSET_MASKED 0x2 +#define GUC_REGSET_ENGINERESET 0x4 +#define GUC_REGSET_SAVE_DEFAULT_VALUE 0x8 +#define GUC_REGSET_SAVE_CURRENT_VALUE 0x10 + +#define GUC_REGSET_MAX_REGISTERS_PER_SET 20 + +#define KM_MMIO_WHITE_LIST_MAX_OFFSETS 12 +struct guc_mmio_white_list { + u32 mmio_start; + u32 offsets[KM_MMIO_WHITE_LIST_MAX_OFFSETS]; + u32 count; +} __packed; + +struct guc_mmio_reg { + u32 offset; + u32 value; + u32 Flags; +} __packed; + +struct guc_mmio_regset { + struct guc_mmio_reg registers[GUC_REGSET_MAX_REGISTERS_PER_SET]; + u32 values_valid; + u32 number_of_registers; +} __packed; + +struct guc_mmio_reg_state { + struct guc_mmio_regset global_reg; + struct guc_mmio_regset node_reg[I915_NUM_RINGS]; + /* MMIO registers that are set as non privileged */ + struct guc_mmio_white_list mmio_white_list[I915_NUM_RINGS]; +} __packed; + +#define GUC_MAX_S3_SAVE_SPACE_PAGES 10 + +/* Additional Data Struct */ +struct guc_ads { + u32 mmio_reg_state_addr; + u32 guc_state_saved_buffer; + u32 golden_context_lrca; + u32 scheduler_policies; + u32 reserved0[3]; + u32 eng_state_size[I915_NUM_RINGS]; + u32 reserved2[4]; +} __packed; + /* This Action will be programmed in C180 - SOFT_SCRATCH_O_REG */ enum host2guc_action { HOST2GUC_ACTION_DEFAULT = 0x0, HOST2GUC_ACTION_REQUEST_PREEMPTION = 0x2, + HOST2GUC_ACTION_REQUEST_ENGINE_RESET = 0x3, HOST2GUC_ACTION_SAMPLE_FORCEWAKE = 0x6, HOST2GUC_ACTION_ALLOCATE_DOORBELL = 0x10, HOST2GUC_ACTION_DEALLOCATE_DOORBELL = 0x20, HOST2GUC_ACTION_ENTER_S_STATE = 0x501, HOST2GUC_ACTION_EXIT_S_STATE = 0x502, HOST2GUC_ACTION_SLPC_REQUEST = 0x3003, + HOST2GUC_ACTION_AUTHENTICATE_HUC = 0x4000, HOST2GUC_ACTION_LIMIT }; diff --git a/drivers/gpu/drm/i915/intel_guc_loader.c b/drivers/gpu/drm/i915/intel_guc_loader.c index 550921f..ce692cf 100644 --- a/drivers/gpu/drm/i915/intel_guc_loader.c +++ b/drivers/gpu/drm/i915/intel_guc_loader.c @@ -165,18 +165,26 @@ static void set_guc_init_params(struct drm_i915_private *dev_priv) i915.guc_log_level << GUC_LOG_VERBOSITY_SHIFT; } + if (guc->ads_obj) { + u32 ads = (u32)i915_gem_obj_ggtt_offset(guc->ads_obj); + ads >>= PAGE_SHIFT; + + params[GUC_CTL_DEBUG] |= ads << GUC_ADS_ADDR_SHIFT; + params[GUC_CTL_DEBUG] |= GUC_ADS_ENABLED; + } + /* If GuC submission is enabled, set up additional parameters here */ if (i915.enable_guc_submission) { - u32 pgs = i915_gem_obj_ggtt_offset(dev_priv->guc.ctx_pool_obj); u32 ctx_in_16 = GUC_MAX_GPU_CONTEXTS / 16; - + u32 pgs = (u32)i915_gem_obj_ggtt_offset(guc->ctx_pool_obj); pgs >>= PAGE_SHIFT; + params[GUC_CTL_CTXINFO] = (pgs << GUC_CTL_BASE_ADDR_SHIFT) | (ctx_in_16 << GUC_CTL_CTXNUM_IN16_SHIFT); params[GUC_CTL_FEATURE] |= GUC_CTL_KERNEL_SUBMISSIONS; - /* Unmask this bit to enable the GuC's internal scheduler */ + /* Clear this bit to enable the GuC's internal scheduler */ params[GUC_CTL_FEATURE] &= ~GUC_CTL_DISABLE_SCHEDULER; } -- 1.9.1 _______________________________________________ Intel-gfx mailing list Intel-gfx@xxxxxxxxxxxxxxxxxxxxx http://lists.freedesktop.org/mailman/listinfo/intel-gfx