drm/i915/guc: Add GuC ADS (Addition Data Structure) - allocation
authorAlex Dai <yu.dai@intel.com>
Fri, 18 Dec 2015 20:00:09 +0000 (12:00 -0800)
committerDaniel Vetter <daniel.vetter@ffwll.ch>
Tue, 5 Jan 2016 10:33:34 +0000 (11:33 +0100)
The GuC firmware uses this for various purposes. The ADS itself is
a chunk of memory created by driver to share with GuC. Its members
are usually addresses telling where GuC to access them, including
things like scheduler policies, register list that will be saved
and restored during reset etc.

This is the first patch of a series to enable GuC ADS. For now, we
only create the ADS obj whilst keep it disabled.

v1: remove dead code checking return of kmap_atomic (Chris Wilson)
v2: use kmap instead of the atomic version of it.

Signed-off-by: Alex Dai <yu.dai@intel.com>
Reviewed-by: Dave Gordon <david.s.gordon@intel.com>
Link: http://patchwork.freedesktop.org/patch/msgid/1450468812-4882-3-git-send-email-yu.dai@intel.com
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
drivers/gpu/drm/i915/i915_guc_reg.h
drivers/gpu/drm/i915/i915_guc_submission.c
drivers/gpu/drm/i915/intel_guc.h
drivers/gpu/drm/i915/intel_guc_fwif.h

index 685c7991e24f33bc549baf1e50f8c9416c177cf6..e4ba5822289bb6dcbc0a225c02e87d62fe48175a 100644 (file)
@@ -40,6 +40,7 @@
 #define   GS_MIA_CORE_STATE              (1 << GS_MIA_SHIFT)
 
 #define SOFT_SCRATCH(n)                        _MMIO(0xc180 + (n) * 4)
+#define SOFT_SCRATCH_COUNT             16
 
 #define UOS_RSA_SCRATCH(i)             _MMIO(0xc200 + (i) * 4)
 #define   UOS_RSA_SCRATCH_MAX_COUNT      64
index 8b00f4619b1e9afc2bb476be46772edfd17233da..7e6c5272e7349c103d893b80639a8a486dbc1e1a 100644 (file)
@@ -839,6 +839,46 @@ static void guc_create_log(struct intel_guc *guc)
        guc->log_flags = (offset << GUC_LOG_BUF_ADDR_SHIFT) | flags;
 }
 
+static void guc_create_ads(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 and buffers passed to GuC */
+       size = sizeof(struct guc_ads);
+
+       obj = guc->ads_obj;
+       if (!obj) {
+               obj = gem_allocate_guc_obj(dev_priv->dev, PAGE_ALIGN(size));
+               if (!obj)
+                       return;
+
+               guc->ads_obj = obj;
+       }
+
+       page = i915_gem_object_get_page(obj, 0);
+       ads = kmap(page);
+
+       /*
+        * The GuC requires a "Golden Context" when it reinitialises
+        * 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.
+        */
+       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(page);
+}
+
 /*
  * 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.
@@ -865,6 +905,8 @@ int i915_guc_submission_init(struct drm_device *dev)
 
        guc_create_log(guc);
 
+       guc_create_ads(guc);
+
        return 0;
 }
 
@@ -903,6 +945,9 @@ 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;
 
index e8612c9afbc9329dd37c6ff115c0f18b968a2096..045b1491ff7a2f100424bb4b982c58de3388ab53 100644 (file)
@@ -89,6 +89,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;
 
index 40b2ea572e16e959a321cb2599f9e1158d282992..bc9829eaabb301d83d6e94a7dbee50923f37f7b6 100644 (file)
 #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)
 #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)
 #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)
 /* Verbosity range-check limits, without the shift */
 #define          GUC_LOG_VERBOSITY_MIN         0
 #define          GUC_LOG_VERBOSITY_MAX         3
+#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
 
-#define GUC_CTL_MAX_DWORDS             (GUC_CTL_RSRVD + 1)
+#define GUC_CTL_MAX_DWORDS             (SOFT_SCRATCH_COUNT - 2) /* [1..14] */
 
 /**
  * DOC: GuC Firmware Layout
@@ -299,6 +316,18 @@ struct guc_context_desc {
 #define GUC_POWER_D2           3
 #define GUC_POWER_D3           4
 
+/* GuC Additional Data Struct */
+
+struct guc_ads {
+       u32 reg_state_addr;
+       u32 reg_state_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,