Commit b09935a6 authored by Oscar Mateo's avatar Oscar Mateo Committed by Joonas Lahtinen

drm/i915/guc: Refactor the concept "GuC context descriptor" into "GuC stage descriptor"

A GuC context and a HW context are in no way related, so the name "GuC context descriptor"
is very unfortunate, because a new reader of the code gets overwhelmed very quickly with
a lot of things called "context" that refer to different things. We can improve legibility
a lot by simply renaming a few objects in the GuC code.

v2:
  - Rebased
  - s/ctx_desc_pool/stage_desc_pool
  - Move some explanations to the definition of the guc_stage_desc struct (Chris)

v3:
  - Calculate gemsize with less intermediate steps (Joonas)
  - Use BIT() macro (Joonas)
Signed-off-by: default avatarOscar Mateo <oscar.mateo@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Reviewed-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
Signed-off-by: default avatarJoonas Lahtinen <joonas.lahtinen@linux.intel.com>
parent 397fce88
...@@ -2471,8 +2471,8 @@ static void i915_guc_client_info(struct seq_file *m, ...@@ -2471,8 +2471,8 @@ static void i915_guc_client_info(struct seq_file *m,
enum intel_engine_id id; enum intel_engine_id id;
uint64_t tot = 0; uint64_t tot = 0;
seq_printf(m, "\tPriority %d, GuC ctx index: %u, PD offset 0x%x\n", seq_printf(m, "\tPriority %d, GuC stage index: %u, PD offset 0x%x\n",
client->priority, client->ctx_index, client->proc_desc_offset); client->priority, client->stage_id, client->proc_desc_offset);
seq_printf(m, "\tDoorbell id %d, offset: 0x%lx, cookie 0x%x\n", seq_printf(m, "\tDoorbell id %d, offset: 0x%lx, cookie 0x%x\n",
client->doorbell_id, client->doorbell_offset, client->doorbell_cookie); client->doorbell_id, client->doorbell_offset, client->doorbell_cookie);
seq_printf(m, "\tWQ size %d, offset: 0x%x, tail %d\n", seq_printf(m, "\tWQ size %d, offset: 0x%x, tail %d\n",
......
...@@ -37,16 +37,16 @@ ...@@ -37,16 +37,16 @@
* descriptor and a workqueue (all of them inside a single gem object that * descriptor and a workqueue (all of them inside a single gem object that
* contains all required pages for these elements). * contains all required pages for these elements).
* *
* GuC context descriptor: * GuC stage descriptor:
* During initialization, the driver allocates a static pool of 1024 such * During initialization, the driver allocates a static pool of 1024 such
* descriptors, and shares them with the GuC. * descriptors, and shares them with the GuC.
* Currently, there exists a 1:1 mapping between a i915_guc_client and a * Currently, there exists a 1:1 mapping between a i915_guc_client and a
* guc_context_desc (via the client's context_index), so effectively only * guc_stage_desc (via the client's stage_id), so effectively only one
* one guc_context_desc gets used. This context descriptor lets the GuC know * gets used. This stage descriptor lets the GuC know about the doorbell,
* about the doorbell, workqueue and process descriptor. Theoretically, it also * workqueue and process descriptor. Theoretically, it also lets the GuC
* lets the GuC know about our HW contexts (Context ID, etc...), but we actually * know about our HW contexts (context ID, etc...), but we actually
* employ a kind of submission where the GuC uses the LRCA sent via the work * employ a kind of submission where the GuC uses the LRCA sent via the work
* item instead (the single guc_context_desc associated to execbuf client * item instead (the single guc_stage_desc associated to execbuf client
* contains information about the default kernel context only, but this is * contains information about the default kernel context only, but this is
* essentially unused). This is called a "proxy" submission. * essentially unused). This is called a "proxy" submission.
* *
...@@ -82,7 +82,7 @@ ...@@ -82,7 +82,7 @@
static inline bool is_high_priority(struct i915_guc_client* client) static inline bool is_high_priority(struct i915_guc_client* client)
{ {
return client->priority <= GUC_CTX_PRIORITY_HIGH; return client->priority <= GUC_CLIENT_PRIORITY_HIGH;
} }
static int __reserve_doorbell(struct i915_guc_client *client) static int __reserve_doorbell(struct i915_guc_client *client)
...@@ -112,7 +112,7 @@ static int __reserve_doorbell(struct i915_guc_client *client) ...@@ -112,7 +112,7 @@ static int __reserve_doorbell(struct i915_guc_client *client)
__set_bit(id, client->guc->doorbell_bitmap); __set_bit(id, client->guc->doorbell_bitmap);
client->doorbell_id = id; client->doorbell_id = id;
DRM_DEBUG_DRIVER("client %u (high prio=%s) reserved doorbell: %d\n", DRM_DEBUG_DRIVER("client %u (high prio=%s) reserved doorbell: %d\n",
client->ctx_index, yesno(is_high_priority(client)), client->stage_id, yesno(is_high_priority(client)),
id); id);
return 0; return 0;
} }
...@@ -129,31 +129,31 @@ static void __unreserve_doorbell(struct i915_guc_client *client) ...@@ -129,31 +129,31 @@ static void __unreserve_doorbell(struct i915_guc_client *client)
* Tell the GuC to allocate or deallocate a specific doorbell * Tell the GuC to allocate or deallocate a specific doorbell
*/ */
static int __guc_allocate_doorbell(struct intel_guc *guc, u32 ctx_index) static int __guc_allocate_doorbell(struct intel_guc *guc, u32 stage_id)
{ {
u32 action[] = { u32 action[] = {
INTEL_GUC_ACTION_ALLOCATE_DOORBELL, INTEL_GUC_ACTION_ALLOCATE_DOORBELL,
ctx_index stage_id
}; };
return intel_guc_send(guc, action, ARRAY_SIZE(action)); return intel_guc_send(guc, action, ARRAY_SIZE(action));
} }
static int __guc_deallocate_doorbell(struct intel_guc *guc, u32 ctx_index) static int __guc_deallocate_doorbell(struct intel_guc *guc, u32 stage_id)
{ {
u32 action[] = { u32 action[] = {
INTEL_GUC_ACTION_DEALLOCATE_DOORBELL, INTEL_GUC_ACTION_DEALLOCATE_DOORBELL,
ctx_index stage_id
}; };
return intel_guc_send(guc, action, ARRAY_SIZE(action)); return intel_guc_send(guc, action, ARRAY_SIZE(action));
} }
static struct guc_context_desc *__get_context_desc(struct i915_guc_client *client) static struct guc_stage_desc *__get_stage_desc(struct i915_guc_client *client)
{ {
struct guc_context_desc *base = client->guc->ctx_pool_vaddr; struct guc_stage_desc *base = client->guc->stage_desc_pool_vaddr;
return &base[client->ctx_index]; return &base[client->stage_id];
} }
/* /*
...@@ -165,10 +165,10 @@ static struct guc_context_desc *__get_context_desc(struct i915_guc_client *clien ...@@ -165,10 +165,10 @@ static struct guc_context_desc *__get_context_desc(struct i915_guc_client *clien
static void __update_doorbell_desc(struct i915_guc_client *client, u16 new_id) static void __update_doorbell_desc(struct i915_guc_client *client, u16 new_id)
{ {
struct guc_context_desc *desc; struct guc_stage_desc *desc;
/* Update the GuC's idea of the doorbell ID */ /* Update the GuC's idea of the doorbell ID */
desc = __get_context_desc(client); desc = __get_stage_desc(client);
desc->db_id = new_id; desc->db_id = new_id;
} }
...@@ -194,7 +194,7 @@ static int __create_doorbell(struct i915_guc_client *client) ...@@ -194,7 +194,7 @@ static int __create_doorbell(struct i915_guc_client *client)
doorbell->db_status = GUC_DOORBELL_ENABLED; doorbell->db_status = GUC_DOORBELL_ENABLED;
doorbell->cookie = client->doorbell_cookie; doorbell->cookie = client->doorbell_cookie;
err = __guc_allocate_doorbell(client->guc, client->ctx_index); err = __guc_allocate_doorbell(client->guc, client->stage_id);
if (err) { if (err) {
doorbell->db_status = GUC_DOORBELL_DISABLED; doorbell->db_status = GUC_DOORBELL_DISABLED;
doorbell->cookie = 0; doorbell->cookie = 0;
...@@ -220,7 +220,7 @@ static int __destroy_doorbell(struct i915_guc_client *client) ...@@ -220,7 +220,7 @@ static int __destroy_doorbell(struct i915_guc_client *client)
if (wait_for_us(!(I915_READ(GEN8_DRBREGL(db_id)) & GEN8_DRB_VALID), 10)) if (wait_for_us(!(I915_READ(GEN8_DRBREGL(db_id)) & GEN8_DRB_VALID), 10))
WARN_ONCE(true, "Doorbell never became invalid after disable\n"); WARN_ONCE(true, "Doorbell never became invalid after disable\n");
return __guc_deallocate_doorbell(client->guc, client->ctx_index); return __guc_deallocate_doorbell(client->guc, client->stage_id);
} }
static int create_doorbell(struct i915_guc_client *client) static int create_doorbell(struct i915_guc_client *client)
...@@ -301,34 +301,34 @@ static void guc_proc_desc_init(struct intel_guc *guc, ...@@ -301,34 +301,34 @@ static void guc_proc_desc_init(struct intel_guc *guc,
desc->wq_base_addr = 0; desc->wq_base_addr = 0;
desc->db_base_addr = 0; desc->db_base_addr = 0;
desc->context_id = client->ctx_index; desc->stage_id = client->stage_id;
desc->wq_size_bytes = client->wq_size; desc->wq_size_bytes = client->wq_size;
desc->wq_status = WQ_STATUS_ACTIVE; desc->wq_status = WQ_STATUS_ACTIVE;
desc->priority = client->priority; desc->priority = client->priority;
} }
/* /*
* Initialise/clear the context descriptor shared with the GuC firmware. * Initialise/clear the stage descriptor shared with the GuC firmware.
* *
* This descriptor tells the GuC where (in GGTT space) to find the important * This descriptor tells the GuC where (in GGTT space) to find the important
* data structures relating to this client (doorbell, process descriptor, * data structures relating to this client (doorbell, process descriptor,
* write queue, etc). * write queue, etc).
*/ */
static void guc_ctx_desc_init(struct intel_guc *guc, static void guc_stage_desc_init(struct intel_guc *guc,
struct i915_guc_client *client) struct i915_guc_client *client)
{ {
struct drm_i915_private *dev_priv = guc_to_i915(guc); struct drm_i915_private *dev_priv = guc_to_i915(guc);
struct intel_engine_cs *engine; struct intel_engine_cs *engine;
struct i915_gem_context *ctx = client->owner; struct i915_gem_context *ctx = client->owner;
struct guc_context_desc *desc; struct guc_stage_desc *desc;
unsigned int tmp; unsigned int tmp;
u32 gfx_addr; u32 gfx_addr;
desc = __get_context_desc(client); desc = __get_stage_desc(client);
memset(desc, 0, sizeof(*desc)); memset(desc, 0, sizeof(*desc));
desc->attribute = GUC_CTX_DESC_ATTR_ACTIVE | GUC_CTX_DESC_ATTR_KERNEL; desc->attribute = GUC_STAGE_DESC_ATTR_ACTIVE | GUC_STAGE_DESC_ATTR_KERNEL;
desc->context_id = client->ctx_index; desc->stage_id = client->stage_id;
desc->priority = client->priority; desc->priority = client->priority;
desc->db_id = client->doorbell_id; desc->db_id = client->doorbell_id;
...@@ -348,7 +348,7 @@ static void guc_ctx_desc_init(struct intel_guc *guc, ...@@ -348,7 +348,7 @@ static void guc_ctx_desc_init(struct intel_guc *guc,
break; /* XXX: continue? */ break; /* XXX: continue? */
/* /*
* XXX: When this is a GUC_CTX_DESC_ATTR_KERNEL client (proxy * XXX: When this is a GUC_STAGE_DESC_ATTR_KERNEL client (proxy
* submission or, in other words, not using a direct submission * submission or, in other words, not using a direct submission
* model) the KMD's LRCA is not used for any work submission. * model) the KMD's LRCA is not used for any work submission.
* Instead, the GuC uses the LRCA of the user mode context (see * Instead, the GuC uses the LRCA of the user mode context (see
...@@ -359,7 +359,10 @@ static void guc_ctx_desc_init(struct intel_guc *guc, ...@@ -359,7 +359,10 @@ static void guc_ctx_desc_init(struct intel_guc *guc,
/* The state page is after PPHWSP */ /* The state page is after PPHWSP */
lrc->ring_lrca = lrc->ring_lrca =
guc_ggtt_offset(ce->state) + LRC_STATE_PN * PAGE_SIZE; guc_ggtt_offset(ce->state) + LRC_STATE_PN * PAGE_SIZE;
lrc->context_id = (client->ctx_index << GUC_ELC_CTXID_OFFSET) |
/* XXX: In direct submission, the GuC wants the HW context id
* here. In proxy submission, it wants the stage id */
lrc->context_id = (client->stage_id << GUC_ELC_CTXID_OFFSET) |
(guc_engine_id << GUC_ELC_ENGINE_OFFSET); (guc_engine_id << GUC_ELC_ENGINE_OFFSET);
lrc->ring_begin = guc_ggtt_offset(ce->ring->vma); lrc->ring_begin = guc_ggtt_offset(ce->ring->vma);
...@@ -390,12 +393,12 @@ static void guc_ctx_desc_init(struct intel_guc *guc, ...@@ -390,12 +393,12 @@ static void guc_ctx_desc_init(struct intel_guc *guc,
desc->desc_private = (uintptr_t)client; desc->desc_private = (uintptr_t)client;
} }
static void guc_ctx_desc_fini(struct intel_guc *guc, static void guc_stage_desc_fini(struct intel_guc *guc,
struct i915_guc_client *client) struct i915_guc_client *client)
{ {
struct guc_context_desc *desc; struct guc_stage_desc *desc;
desc = __get_context_desc(client); desc = __get_stage_desc(client);
memset(desc, 0, sizeof(*desc)); memset(desc, 0, sizeof(*desc));
} }
...@@ -863,7 +866,7 @@ static int guc_init_doorbell_hw(struct intel_guc *guc) ...@@ -863,7 +866,7 @@ static int guc_init_doorbell_hw(struct intel_guc *guc)
ret = __create_doorbell(client); ret = __create_doorbell(client);
if (ret) { if (ret) {
DRM_ERROR("Couldn't recreate client %u doorbell: %d\n", DRM_ERROR("Couldn't recreate client %u doorbell: %d\n",
client->ctx_index, ret); client->stage_id, ret);
return ret; return ret;
} }
} }
...@@ -913,12 +916,12 @@ guc_client_alloc(struct drm_i915_private *dev_priv, ...@@ -913,12 +916,12 @@ guc_client_alloc(struct drm_i915_private *dev_priv,
client->wq_size = GUC_WQ_SIZE; client->wq_size = GUC_WQ_SIZE;
spin_lock_init(&client->wq_lock); spin_lock_init(&client->wq_lock);
ret = ida_simple_get(&guc->ctx_ids, 0, GUC_MAX_GPU_CONTEXTS, ret = ida_simple_get(&guc->stage_ids, 0, GUC_MAX_STAGE_DESCRIPTORS,
GFP_KERNEL); GFP_KERNEL);
if (ret < 0) if (ret < 0)
goto err_client; goto err_client;
client->ctx_index = ret; client->stage_id = ret;
/* The first page is doorbell/proc_desc. Two followed pages are wq. */ /* The first page is doorbell/proc_desc. Two followed pages are wq. */
vma = intel_guc_allocate_vma(guc, GUC_DB_SIZE + GUC_WQ_SIZE); vma = intel_guc_allocate_vma(guc, GUC_DB_SIZE + GUC_WQ_SIZE);
...@@ -950,14 +953,14 @@ guc_client_alloc(struct drm_i915_private *dev_priv, ...@@ -950,14 +953,14 @@ guc_client_alloc(struct drm_i915_private *dev_priv,
client->proc_desc_offset = (GUC_DB_SIZE / 2); client->proc_desc_offset = (GUC_DB_SIZE / 2);
guc_proc_desc_init(guc, client); guc_proc_desc_init(guc, client);
guc_ctx_desc_init(guc, client); guc_stage_desc_init(guc, client);
ret = create_doorbell(client); ret = create_doorbell(client);
if (ret) if (ret)
goto err_vaddr; goto err_vaddr;
DRM_DEBUG_DRIVER("new priority %u client %p for engine(s) 0x%x: ctx_index %u\n", DRM_DEBUG_DRIVER("new priority %u client %p for engine(s) 0x%x: stage_id %u\n",
priority, client, client->engines, client->ctx_index); priority, client, client->engines, client->stage_id);
DRM_DEBUG_DRIVER("doorbell id %u, cacheline offset 0x%lx\n", DRM_DEBUG_DRIVER("doorbell id %u, cacheline offset 0x%lx\n",
client->doorbell_id, client->doorbell_offset); client->doorbell_id, client->doorbell_offset);
...@@ -968,7 +971,7 @@ guc_client_alloc(struct drm_i915_private *dev_priv, ...@@ -968,7 +971,7 @@ guc_client_alloc(struct drm_i915_private *dev_priv,
err_vma: err_vma:
i915_vma_unpin_and_release(&client->vma); i915_vma_unpin_and_release(&client->vma);
err_id: err_id:
ida_simple_remove(&guc->ctx_ids, client->ctx_index); ida_simple_remove(&guc->stage_ids, client->stage_id);
err_client: err_client:
kfree(client); kfree(client);
return ERR_PTR(ret); return ERR_PTR(ret);
...@@ -985,10 +988,10 @@ static void guc_client_free(struct i915_guc_client *client) ...@@ -985,10 +988,10 @@ static void guc_client_free(struct i915_guc_client *client)
* reset, so we cannot destroy the doorbell properly. Ignore the * reset, so we cannot destroy the doorbell properly. Ignore the
* error message for now */ * error message for now */
destroy_doorbell(client); destroy_doorbell(client);
guc_ctx_desc_fini(client->guc, client); guc_stage_desc_fini(client->guc, client);
i915_gem_object_unpin_map(client->vma->obj); i915_gem_object_unpin_map(client->vma->obj);
i915_vma_unpin_and_release(&client->vma); i915_vma_unpin_and_release(&client->vma);
ida_simple_remove(&client->guc->ctx_ids, client->ctx_index); ida_simple_remove(&client->guc->stage_ids, client->stage_id);
kfree(client); kfree(client);
} }
...@@ -1000,7 +1003,7 @@ static void guc_policies_init(struct guc_policies *policies) ...@@ -1000,7 +1003,7 @@ static void guc_policies_init(struct guc_policies *policies)
policies->dpc_promote_time = 500000; policies->dpc_promote_time = 500000;
policies->max_num_work_items = POLICY_MAX_NUM_WI; policies->max_num_work_items = POLICY_MAX_NUM_WI;
for (p = 0; p < GUC_CTX_PRIORITY_NUM; p++) { for (p = 0; p < GUC_CLIENT_PRIORITY_NUM; p++) {
for (i = GUC_RENDER_ENGINE; i < GUC_MAX_ENGINES_NUM; i++) { for (i = GUC_RENDER_ENGINE; i < GUC_MAX_ENGINES_NUM; i++) {
policy = &policies->policy[p][i]; policy = &policies->policy[p][i];
...@@ -1088,30 +1091,29 @@ static void guc_ads_destroy(struct intel_guc *guc) ...@@ -1088,30 +1091,29 @@ static void guc_ads_destroy(struct intel_guc *guc)
*/ */
int i915_guc_submission_init(struct drm_i915_private *dev_priv) int i915_guc_submission_init(struct drm_i915_private *dev_priv)
{ {
const size_t ctxsize = sizeof(struct guc_context_desc);
const size_t poolsize = GUC_MAX_GPU_CONTEXTS * ctxsize;
const size_t gemsize = round_up(poolsize, PAGE_SIZE);
struct intel_guc *guc = &dev_priv->guc; struct intel_guc *guc = &dev_priv->guc;
struct i915_vma *vma; struct i915_vma *vma;
void *vaddr; void *vaddr;
int ret; int ret;
if (guc->ctx_pool) if (guc->stage_desc_pool)
return 0; return 0;
vma = intel_guc_allocate_vma(guc, gemsize); vma = intel_guc_allocate_vma(guc,
PAGE_ALIGN(sizeof(struct guc_stage_desc) *
GUC_MAX_STAGE_DESCRIPTORS));
if (IS_ERR(vma)) if (IS_ERR(vma))
return PTR_ERR(vma); return PTR_ERR(vma);
guc->ctx_pool = vma; guc->stage_desc_pool = vma;
vaddr = i915_gem_object_pin_map(guc->ctx_pool->obj, I915_MAP_WB); vaddr = i915_gem_object_pin_map(guc->stage_desc_pool->obj, I915_MAP_WB);
if (IS_ERR(vaddr)) { if (IS_ERR(vaddr)) {
ret = PTR_ERR(vaddr); ret = PTR_ERR(vaddr);
goto err_vma; goto err_vma;
} }
guc->ctx_pool_vaddr = vaddr; guc->stage_desc_pool_vaddr = vaddr;
ret = intel_guc_log_create(guc); ret = intel_guc_log_create(guc);
if (ret < 0) if (ret < 0)
...@@ -1121,16 +1123,16 @@ int i915_guc_submission_init(struct drm_i915_private *dev_priv) ...@@ -1121,16 +1123,16 @@ int i915_guc_submission_init(struct drm_i915_private *dev_priv)
if (ret < 0) if (ret < 0)
goto err_log; goto err_log;
ida_init(&guc->ctx_ids); ida_init(&guc->stage_ids);
return 0; return 0;
err_log: err_log:
intel_guc_log_destroy(guc); intel_guc_log_destroy(guc);
err_vaddr: err_vaddr:
i915_gem_object_unpin_map(guc->ctx_pool->obj); i915_gem_object_unpin_map(guc->stage_desc_pool->obj);
err_vma: err_vma:
i915_vma_unpin_and_release(&guc->ctx_pool); i915_vma_unpin_and_release(&guc->stage_desc_pool);
return ret; return ret;
} }
...@@ -1138,11 +1140,11 @@ void i915_guc_submission_fini(struct drm_i915_private *dev_priv) ...@@ -1138,11 +1140,11 @@ void i915_guc_submission_fini(struct drm_i915_private *dev_priv)
{ {
struct intel_guc *guc = &dev_priv->guc; struct intel_guc *guc = &dev_priv->guc;
ida_destroy(&guc->ctx_ids); ida_destroy(&guc->stage_ids);
guc_ads_destroy(guc); guc_ads_destroy(guc);
intel_guc_log_destroy(guc); intel_guc_log_destroy(guc);
i915_gem_object_unpin_map(guc->ctx_pool->obj); i915_gem_object_unpin_map(guc->stage_desc_pool->obj);
i915_vma_unpin_and_release(&guc->ctx_pool); i915_vma_unpin_and_release(&guc->stage_desc_pool);
} }
static void guc_interrupts_capture(struct drm_i915_private *dev_priv) static void guc_interrupts_capture(struct drm_i915_private *dev_priv)
...@@ -1198,7 +1200,7 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv) ...@@ -1198,7 +1200,7 @@ int i915_guc_submission_enable(struct drm_i915_private *dev_priv)
if (!client) { if (!client) {
client = guc_client_alloc(dev_priv, client = guc_client_alloc(dev_priv,
INTEL_INFO(dev_priv)->ring_mask, INTEL_INFO(dev_priv)->ring_mask,
GUC_CTX_PRIORITY_KMD_NORMAL, GUC_CLIENT_PRIORITY_KMD_NORMAL,
dev_priv->kernel_context); dev_priv->kernel_context);
if (IS_ERR(client)) { if (IS_ERR(client)) {
DRM_ERROR("Failed to create GuC client for execbuf!\n"); DRM_ERROR("Failed to create GuC client for execbuf!\n");
......
...@@ -26,14 +26,14 @@ ...@@ -26,14 +26,14 @@
#define GFXCORE_FAMILY_GEN9 12 #define GFXCORE_FAMILY_GEN9 12
#define GFXCORE_FAMILY_UNKNOWN 0x7fffffff #define GFXCORE_FAMILY_UNKNOWN 0x7fffffff
#define GUC_CTX_PRIORITY_KMD_HIGH 0 #define GUC_CLIENT_PRIORITY_KMD_HIGH 0
#define GUC_CTX_PRIORITY_HIGH 1 #define GUC_CLIENT_PRIORITY_HIGH 1
#define GUC_CTX_PRIORITY_KMD_NORMAL 2 #define GUC_CLIENT_PRIORITY_KMD_NORMAL 2
#define GUC_CTX_PRIORITY_NORMAL 3 #define GUC_CLIENT_PRIORITY_NORMAL 3
#define GUC_CTX_PRIORITY_NUM 4 #define GUC_CLIENT_PRIORITY_NUM 4
#define GUC_MAX_GPU_CONTEXTS 1024 #define GUC_MAX_STAGE_DESCRIPTORS 1024
#define GUC_INVALID_CTX_ID GUC_MAX_GPU_CONTEXTS #define GUC_INVALID_STAGE_ID GUC_MAX_STAGE_DESCRIPTORS
#define GUC_RENDER_ENGINE 0 #define GUC_RENDER_ENGINE 0
#define GUC_VIDEO_ENGINE 1 #define GUC_VIDEO_ENGINE 1
...@@ -68,14 +68,14 @@ ...@@ -68,14 +68,14 @@
#define GUC_DOORBELL_ENABLED 1 #define GUC_DOORBELL_ENABLED 1
#define GUC_DOORBELL_DISABLED 0 #define GUC_DOORBELL_DISABLED 0
#define GUC_CTX_DESC_ATTR_ACTIVE (1 << 0) #define GUC_STAGE_DESC_ATTR_ACTIVE BIT(0)
#define GUC_CTX_DESC_ATTR_PENDING_DB (1 << 1) #define GUC_STAGE_DESC_ATTR_PENDING_DB BIT(1)
#define GUC_CTX_DESC_ATTR_KERNEL (1 << 2) #define GUC_STAGE_DESC_ATTR_KERNEL BIT(2)
#define GUC_CTX_DESC_ATTR_PREEMPT (1 << 3) #define GUC_STAGE_DESC_ATTR_PREEMPT BIT(3)
#define GUC_CTX_DESC_ATTR_RESET (1 << 4) #define GUC_STAGE_DESC_ATTR_RESET BIT(4)
#define GUC_CTX_DESC_ATTR_WQLOCKED (1 << 5) #define GUC_STAGE_DESC_ATTR_WQLOCKED BIT(5)
#define GUC_CTX_DESC_ATTR_PCH (1 << 6) #define GUC_STAGE_DESC_ATTR_PCH BIT(6)
#define GUC_CTX_DESC_ATTR_TERMINATED (1 << 7) #define GUC_STAGE_DESC_ATTR_TERMINATED BIT(7)
/* The guc control data is 10 DWORDs */ /* The guc control data is 10 DWORDs */
#define GUC_CTL_CTXINFO 0 #define GUC_CTL_CTXINFO 0
...@@ -256,7 +256,7 @@ struct guc_wq_item { ...@@ -256,7 +256,7 @@ struct guc_wq_item {
} __packed; } __packed;
struct guc_process_desc { struct guc_process_desc {
u32 context_id; u32 stage_id;
u64 db_base_addr; u64 db_base_addr;
u32 head; u32 head;
u32 tail; u32 tail;
...@@ -289,10 +289,18 @@ struct guc_execlist_context { ...@@ -289,10 +289,18 @@ struct guc_execlist_context {
u16 engine_submit_queue_count; u16 engine_submit_queue_count;
} __packed; } __packed;
/*Context descriptor for communicating between uKernel and Driver*/ /*
struct guc_context_desc { * This structure describes a stage set arranged for a particular communication
* between uKernel (GuC) and Driver (KMD). Technically, this is known as a
* "GuC Context descriptor" in the specs, but we use the term "stage descriptor"
* to avoid confusion with all the other things already named "context" in the
* driver. A static pool of these descriptors are stored inside a GEM object
* (stage_desc_pool) which is held for the entire lifetime of our interaction
* with the GuC, being allocated before the GuC is loaded with its firmware.
*/
struct guc_stage_desc {
u32 sched_common_area; u32 sched_common_area;
u32 context_id; u32 stage_id;
u32 pas_id; u32 pas_id;
u8 engines_used; u8 engines_used;
u64 db_trigger_cpu; u64 db_trigger_cpu;
...@@ -359,7 +367,7 @@ struct guc_policy { ...@@ -359,7 +367,7 @@ struct guc_policy {
} __packed; } __packed;
struct guc_policies { struct guc_policies {
struct guc_policy policy[GUC_CTX_PRIORITY_NUM][GUC_MAX_ENGINES_NUM]; struct guc_policy policy[GUC_CLIENT_PRIORITY_NUM][GUC_MAX_ENGINES_NUM];
/* In micro seconds. How much time to allow before DPC processing is /* In micro seconds. How much time to allow before DPC processing is
* called back via interrupt (to prevent DPC queue drain starving). * called back via interrupt (to prevent DPC queue drain starving).
......
...@@ -151,8 +151,8 @@ static void guc_params_init(struct drm_i915_private *dev_priv) ...@@ -151,8 +151,8 @@ static void guc_params_init(struct drm_i915_private *dev_priv)
/* If GuC submission is enabled, set up additional parameters here */ /* If GuC submission is enabled, set up additional parameters here */
if (i915.enable_guc_submission) { if (i915.enable_guc_submission) {
u32 ads = guc_ggtt_offset(guc->ads_vma) >> PAGE_SHIFT; u32 ads = guc_ggtt_offset(guc->ads_vma) >> PAGE_SHIFT;
u32 pgs = guc_ggtt_offset(dev_priv->guc.ctx_pool); u32 pgs = guc_ggtt_offset(dev_priv->guc.stage_desc_pool);
u32 ctx_in_16 = GUC_MAX_GPU_CONTEXTS / 16; u32 ctx_in_16 = GUC_MAX_STAGE_DESCRIPTORS / 16;
params[GUC_CTL_DEBUG] |= ads << GUC_ADS_ADDR_SHIFT; params[GUC_CTL_DEBUG] |= ads << GUC_ADS_ADDR_SHIFT;
params[GUC_CTL_DEBUG] |= GUC_ADS_ENABLED; params[GUC_CTL_DEBUG] |= GUC_ADS_ENABLED;
......
...@@ -74,7 +74,7 @@ struct i915_guc_client { ...@@ -74,7 +74,7 @@ struct i915_guc_client {
uint32_t engines; /* bitmap of (host) engine ids */ uint32_t engines; /* bitmap of (host) engine ids */
uint32_t priority; uint32_t priority;
u32 ctx_index; u32 stage_id;
uint32_t proc_desc_offset; uint32_t proc_desc_offset;
u16 doorbell_id; u16 doorbell_id;
...@@ -157,9 +157,9 @@ struct intel_guc { ...@@ -157,9 +157,9 @@ struct intel_guc {
bool interrupts_enabled; bool interrupts_enabled;
struct i915_vma *ads_vma; struct i915_vma *ads_vma;
struct i915_vma *ctx_pool; struct i915_vma *stage_desc_pool;
void *ctx_pool_vaddr; void *stage_desc_pool_vaddr;
struct ida ctx_ids; struct ida stage_ids;
struct i915_guc_client *execbuf_client; struct i915_guc_client *execbuf_client;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment