drm/i915/guc: Add GuC kernel doc
Add GuC kernel doc for all structures added thus far for GuC submission and update the main GuC submission section with the new interface details. v2: - Drop guc_active.lock DOC v3: - Fixup a few kernel doc comments (Daniele) v4 (Daniele): - Implement doc suggestions from John - Add kerneldoc for all members of the GuC structure and pull the file in i915.rst v5 (Daniele): - Implement new doc suggestions from John Signed-off-by: Matthew Brost <matthew.brost@intel.com> Signed-off-by: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com> Cc: John Harrison <John.C.Harrison@Intel.com> Reviewed-by: John Harrison <John.C.Harrison@Intel.com> Signed-off-by: John Harrison <John.C.Harrison@Intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20210909164744.31249-24-matthew.brost@intel.com
This commit is contained in:
parent
af5bc9f21e
commit
4f41ddc7c7
|
@ -498,6 +498,8 @@ GuC
|
||||||
.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_guc.c
|
.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_guc.c
|
||||||
:doc: GuC
|
:doc: GuC
|
||||||
|
|
||||||
|
.. kernel-doc:: drivers/gpu/drm/i915/gt/uc/intel_guc.h
|
||||||
|
|
||||||
GuC Firmware Layout
|
GuC Firmware Layout
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -156,40 +156,51 @@ struct intel_context {
|
||||||
u8 wa_bb_page; /* if set, page num reserved for context workarounds */
|
u8 wa_bb_page; /* if set, page num reserved for context workarounds */
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
/** lock: protects everything in guc_state */
|
/** @lock: protects everything in guc_state */
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
/**
|
/**
|
||||||
* sched_state: scheduling state of this context using GuC
|
* @sched_state: scheduling state of this context using GuC
|
||||||
* submission
|
* submission
|
||||||
*/
|
*/
|
||||||
u32 sched_state;
|
u32 sched_state;
|
||||||
/*
|
/*
|
||||||
* fences: maintains of list of requests that have a submit
|
* @fences: maintains a list of requests that are currently
|
||||||
* fence related to GuC submission
|
* being fenced until a GuC operation completes
|
||||||
*/
|
*/
|
||||||
struct list_head fences;
|
struct list_head fences;
|
||||||
/* GuC context blocked fence */
|
/**
|
||||||
struct i915_sw_fence blocked;
|
* @blocked: fence used to signal when the blocking of a
|
||||||
/* GuC committed requests */
|
* context's submissions is complete.
|
||||||
int number_committed_requests;
|
|
||||||
/** requests: active requests on this context */
|
|
||||||
struct list_head requests;
|
|
||||||
/*
|
|
||||||
* GuC priority management
|
|
||||||
*/
|
*/
|
||||||
|
struct i915_sw_fence blocked;
|
||||||
|
/** @number_committed_requests: number of committed requests */
|
||||||
|
int number_committed_requests;
|
||||||
|
/** @requests: list of active requests on this context */
|
||||||
|
struct list_head requests;
|
||||||
|
/** @prio: the context's current guc priority */
|
||||||
u8 prio;
|
u8 prio;
|
||||||
|
/**
|
||||||
|
* @prio_count: a counter of the number requests in flight in
|
||||||
|
* each priority bucket
|
||||||
|
*/
|
||||||
u32 prio_count[GUC_CLIENT_PRIORITY_NUM];
|
u32 prio_count[GUC_CLIENT_PRIORITY_NUM];
|
||||||
} guc_state;
|
} guc_state;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
/* GuC LRC descriptor ID */
|
/**
|
||||||
|
* @id: handle which is used to uniquely identify this context
|
||||||
|
* with the GuC, protected by guc->contexts_lock
|
||||||
|
*/
|
||||||
u16 id;
|
u16 id;
|
||||||
|
/**
|
||||||
/* GuC LRC descriptor reference count */
|
* @ref: the number of references to the guc_id, when
|
||||||
|
* transitioning in and out of zero protected by
|
||||||
|
* guc->contexts_lock
|
||||||
|
*/
|
||||||
atomic_t ref;
|
atomic_t ref;
|
||||||
|
/**
|
||||||
/*
|
* @link: in guc->guc_id_list when the guc_id has no refs but is
|
||||||
* GuC ID link - in list when unpinned but guc_id still valid in GuC
|
* still valid, protected by guc->contexts_lock
|
||||||
*/
|
*/
|
||||||
struct list_head link;
|
struct list_head link;
|
||||||
} guc_id;
|
} guc_id;
|
||||||
|
|
|
@ -22,74 +22,121 @@
|
||||||
|
|
||||||
struct __guc_ads_blob;
|
struct __guc_ads_blob;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Top level structure of GuC. It handles firmware loading and manages client
|
* struct intel_guc - Top level structure of GuC.
|
||||||
* pool. intel_guc owns a intel_guc_client to replace the legacy ExecList
|
*
|
||||||
* submission.
|
* It handles firmware loading and manages client pool. intel_guc owns an
|
||||||
|
* i915_sched_engine for submission.
|
||||||
*/
|
*/
|
||||||
struct intel_guc {
|
struct intel_guc {
|
||||||
|
/** @fw: the GuC firmware */
|
||||||
struct intel_uc_fw fw;
|
struct intel_uc_fw fw;
|
||||||
|
/** @log: sub-structure containing GuC log related data and objects */
|
||||||
struct intel_guc_log log;
|
struct intel_guc_log log;
|
||||||
|
/** @ct: the command transport communication channel */
|
||||||
struct intel_guc_ct ct;
|
struct intel_guc_ct ct;
|
||||||
|
/** @slpc: sub-structure containing SLPC related data and objects */
|
||||||
struct intel_guc_slpc slpc;
|
struct intel_guc_slpc slpc;
|
||||||
|
|
||||||
/* Global engine used to submit requests to GuC */
|
/** @sched_engine: Global engine used to submit requests to GuC */
|
||||||
struct i915_sched_engine *sched_engine;
|
struct i915_sched_engine *sched_engine;
|
||||||
|
/**
|
||||||
|
* @stalled_request: if GuC can't process a request for any reason, we
|
||||||
|
* save it until GuC restarts processing. No other request can be
|
||||||
|
* submitted until the stalled request is processed.
|
||||||
|
*/
|
||||||
struct i915_request *stalled_request;
|
struct i915_request *stalled_request;
|
||||||
|
|
||||||
/* intel_guc_recv interrupt related state */
|
/* intel_guc_recv interrupt related state */
|
||||||
|
/** @irq_lock: protects GuC irq state */
|
||||||
spinlock_t irq_lock;
|
spinlock_t irq_lock;
|
||||||
|
/**
|
||||||
|
* @msg_enabled_mask: mask of events that are processed when receiving
|
||||||
|
* an INTEL_GUC_ACTION_DEFAULT G2H message.
|
||||||
|
*/
|
||||||
unsigned int msg_enabled_mask;
|
unsigned int msg_enabled_mask;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @outstanding_submission_g2h: number of outstanding GuC to Host
|
||||||
|
* responses related to GuC submission, used to determine if the GT is
|
||||||
|
* idle
|
||||||
|
*/
|
||||||
atomic_t outstanding_submission_g2h;
|
atomic_t outstanding_submission_g2h;
|
||||||
|
|
||||||
|
/** @interrupts: pointers to GuC interrupt-managing functions. */
|
||||||
struct {
|
struct {
|
||||||
void (*reset)(struct intel_guc *guc);
|
void (*reset)(struct intel_guc *guc);
|
||||||
void (*enable)(struct intel_guc *guc);
|
void (*enable)(struct intel_guc *guc);
|
||||||
void (*disable)(struct intel_guc *guc);
|
void (*disable)(struct intel_guc *guc);
|
||||||
} interrupts;
|
} interrupts;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* contexts_lock protects the pool of free guc ids and a linked list of
|
* @contexts_lock: protects guc_ids, guc_id_list, ce->guc_id.id, and
|
||||||
* guc ids available to be stolen
|
* ce->guc_id.ref when transitioning in and out of zero
|
||||||
*/
|
*/
|
||||||
spinlock_t contexts_lock;
|
spinlock_t contexts_lock;
|
||||||
|
/** @guc_ids: used to allocate unique ce->guc_id.id values */
|
||||||
struct ida guc_ids;
|
struct ida guc_ids;
|
||||||
|
/**
|
||||||
|
* @guc_id_list: list of intel_context with valid guc_ids but no refs
|
||||||
|
*/
|
||||||
struct list_head guc_id_list;
|
struct list_head guc_id_list;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @submission_supported: tracks whether we support GuC submission on
|
||||||
|
* the current platform
|
||||||
|
*/
|
||||||
bool submission_supported;
|
bool submission_supported;
|
||||||
|
/** @submission_selected: tracks whether the user enabled GuC submission */
|
||||||
bool submission_selected;
|
bool submission_selected;
|
||||||
|
/**
|
||||||
|
* @rc_supported: tracks whether we support GuC rc on the current platform
|
||||||
|
*/
|
||||||
bool rc_supported;
|
bool rc_supported;
|
||||||
|
/** @rc_selected: tracks whether the user enabled GuC rc */
|
||||||
bool rc_selected;
|
bool rc_selected;
|
||||||
|
|
||||||
|
/** @ads_vma: object allocated to hold the GuC ADS */
|
||||||
struct i915_vma *ads_vma;
|
struct i915_vma *ads_vma;
|
||||||
|
/** @ads_blob: contents of the GuC ADS */
|
||||||
struct __guc_ads_blob *ads_blob;
|
struct __guc_ads_blob *ads_blob;
|
||||||
|
/** @ads_regset_size: size of the save/restore regsets in the ADS */
|
||||||
u32 ads_regset_size;
|
u32 ads_regset_size;
|
||||||
|
/** @ads_golden_ctxt_size: size of the golden contexts in the ADS */
|
||||||
u32 ads_golden_ctxt_size;
|
u32 ads_golden_ctxt_size;
|
||||||
|
|
||||||
|
/** @lrc_desc_pool: object allocated to hold the GuC LRC descriptor pool */
|
||||||
struct i915_vma *lrc_desc_pool;
|
struct i915_vma *lrc_desc_pool;
|
||||||
|
/** @lrc_desc_pool_vaddr: contents of the GuC LRC descriptor pool */
|
||||||
void *lrc_desc_pool_vaddr;
|
void *lrc_desc_pool_vaddr;
|
||||||
|
|
||||||
/* guc_id to intel_context lookup */
|
/**
|
||||||
|
* @context_lookup: used to resolve intel_context from guc_id, if a
|
||||||
|
* context is present in this structure it is registered with the GuC
|
||||||
|
*/
|
||||||
struct xarray context_lookup;
|
struct xarray context_lookup;
|
||||||
|
|
||||||
/* Control params for fw initialization */
|
/** @params: Control params for fw initialization */
|
||||||
u32 params[GUC_CTL_MAX_DWORDS];
|
u32 params[GUC_CTL_MAX_DWORDS];
|
||||||
|
|
||||||
/* GuC's FW specific registers used in MMIO send */
|
/** @send_regs: GuC's FW specific registers used for sending MMIO H2G */
|
||||||
struct {
|
struct {
|
||||||
u32 base;
|
u32 base;
|
||||||
unsigned int count;
|
unsigned int count;
|
||||||
enum forcewake_domains fw_domains;
|
enum forcewake_domains fw_domains;
|
||||||
} send_regs;
|
} send_regs;
|
||||||
|
|
||||||
/* register used to send interrupts to the GuC FW */
|
/** @notify_reg: register used to send interrupts to the GuC FW */
|
||||||
i915_reg_t notify_reg;
|
i915_reg_t notify_reg;
|
||||||
|
|
||||||
/* Store msg (e.g. log flush) that we see while CTBs are disabled */
|
/**
|
||||||
|
* @mmio_msg: notification bitmask that the GuC writes in one of its
|
||||||
|
* registers when the CT channel is disabled, to be processed when the
|
||||||
|
* channel is back up.
|
||||||
|
*/
|
||||||
u32 mmio_msg;
|
u32 mmio_msg;
|
||||||
|
|
||||||
/* To serialize the intel_guc_send actions */
|
/** @send_mutex: used to serialize the intel_guc_send actions */
|
||||||
struct mutex send_mutex;
|
struct mutex send_mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,21 +28,6 @@
|
||||||
/**
|
/**
|
||||||
* DOC: GuC-based command submission
|
* DOC: GuC-based command submission
|
||||||
*
|
*
|
||||||
* IMPORTANT NOTE: GuC submission is currently not supported in i915. The GuC
|
|
||||||
* firmware is moving to an updated submission interface and we plan to
|
|
||||||
* turn submission back on when that lands. The below documentation (and related
|
|
||||||
* code) matches the old submission model and will be updated as part of the
|
|
||||||
* upgrade to the new flow.
|
|
||||||
*
|
|
||||||
* GuC stage descriptor:
|
|
||||||
* During initialization, the driver allocates a static pool of 1024 such
|
|
||||||
* descriptors, and shares them with the GuC. Currently, we only use one
|
|
||||||
* descriptor. This stage descriptor lets the GuC know about the workqueue and
|
|
||||||
* process descriptor. Theoretically, it also lets the GuC 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 item instead. This is called
|
|
||||||
* a "proxy" submission.
|
|
||||||
*
|
|
||||||
* The Scratch registers:
|
* The Scratch registers:
|
||||||
* There are 16 MMIO-based registers start from 0xC180. The kernel driver writes
|
* There are 16 MMIO-based registers start from 0xC180. The kernel driver writes
|
||||||
* a value to the action register (SOFT_SCRATCH_0) along with any data. It then
|
* a value to the action register (SOFT_SCRATCH_0) along with any data. It then
|
||||||
|
@ -51,14 +36,85 @@
|
||||||
* processes the request. The kernel driver polls waiting for this update and
|
* processes the request. The kernel driver polls waiting for this update and
|
||||||
* then proceeds.
|
* then proceeds.
|
||||||
*
|
*
|
||||||
* Work Items:
|
* Command Transport buffers (CTBs):
|
||||||
* There are several types of work items that the host may place into a
|
* Covered in detail in other sections but CTBs (Host to GuC - H2G, GuC to Host
|
||||||
* workqueue, each with its own requirements and limitations. Currently only
|
* - G2H) are a message interface between the i915 and GuC.
|
||||||
* WQ_TYPE_INORDER is needed to support legacy submission via GuC, which
|
|
||||||
* represents in-order queue. The kernel driver packs ring tail pointer and an
|
|
||||||
* ELSP context descriptor dword into Work Item.
|
|
||||||
* See guc_add_request()
|
|
||||||
*
|
*
|
||||||
|
* Context registration:
|
||||||
|
* Before a context can be submitted it must be registered with the GuC via a
|
||||||
|
* H2G. A unique guc_id is associated with each context. The context is either
|
||||||
|
* registered at request creation time (normal operation) or at submission time
|
||||||
|
* (abnormal operation, e.g. after a reset).
|
||||||
|
*
|
||||||
|
* Context submission:
|
||||||
|
* The i915 updates the LRC tail value in memory. The i915 must enable the
|
||||||
|
* scheduling of the context within the GuC for the GuC to actually consider it.
|
||||||
|
* Therefore, the first time a disabled context is submitted we use a schedule
|
||||||
|
* enable H2G, while follow up submissions are done via the context submit H2G,
|
||||||
|
* which informs the GuC that a previously enabled context has new work
|
||||||
|
* available.
|
||||||
|
*
|
||||||
|
* Context unpin:
|
||||||
|
* To unpin a context a H2G is used to disable scheduling. When the
|
||||||
|
* corresponding G2H returns indicating the scheduling disable operation has
|
||||||
|
* completed it is safe to unpin the context. While a disable is in flight it
|
||||||
|
* isn't safe to resubmit the context so a fence is used to stall all future
|
||||||
|
* requests of that context until the G2H is returned.
|
||||||
|
*
|
||||||
|
* Context deregistration:
|
||||||
|
* Before a context can be destroyed or if we steal its guc_id we must
|
||||||
|
* deregister the context with the GuC via H2G. If stealing the guc_id it isn't
|
||||||
|
* safe to submit anything to this guc_id until the deregister completes so a
|
||||||
|
* fence is used to stall all requests associated with this guc_id until the
|
||||||
|
* corresponding G2H returns indicating the guc_id has been deregistered.
|
||||||
|
*
|
||||||
|
* guc_ids:
|
||||||
|
* Unique number associated with private GuC context data passed in during
|
||||||
|
* context registration / submission / deregistration. 64k available. Simple ida
|
||||||
|
* is used for allocation.
|
||||||
|
*
|
||||||
|
* Stealing guc_ids:
|
||||||
|
* If no guc_ids are available they can be stolen from another context at
|
||||||
|
* request creation time if that context is unpinned. If a guc_id can't be found
|
||||||
|
* we punt this problem to the user as we believe this is near impossible to hit
|
||||||
|
* during normal use cases.
|
||||||
|
*
|
||||||
|
* Locking:
|
||||||
|
* In the GuC submission code we have 3 basic spin locks which protect
|
||||||
|
* everything. Details about each below.
|
||||||
|
*
|
||||||
|
* sched_engine->lock
|
||||||
|
* This is the submission lock for all contexts that share an i915 schedule
|
||||||
|
* engine (sched_engine), thus only one of the contexts which share a
|
||||||
|
* sched_engine can be submitting at a time. Currently only one sched_engine is
|
||||||
|
* used for all of GuC submission but that could change in the future.
|
||||||
|
*
|
||||||
|
* guc->contexts_lock
|
||||||
|
* Protects guc_id allocation for the given GuC, i.e. only one context can be
|
||||||
|
* doing guc_id allocation operations at a time for each GuC in the system.
|
||||||
|
*
|
||||||
|
* ce->guc_state.lock
|
||||||
|
* Protects everything under ce->guc_state. Ensures that a context is in the
|
||||||
|
* correct state before issuing a H2G. e.g. We don't issue a schedule disable
|
||||||
|
* on a disabled context (bad idea), we don't issue a schedule enable when a
|
||||||
|
* schedule disable is in flight, etc... Also protects list of inflight requests
|
||||||
|
* on the context and the priority management state. Lock is individual to each
|
||||||
|
* context.
|
||||||
|
*
|
||||||
|
* Lock ordering rules:
|
||||||
|
* sched_engine->lock -> ce->guc_state.lock
|
||||||
|
* guc->contexts_lock -> ce->guc_state.lock
|
||||||
|
*
|
||||||
|
* Reset races:
|
||||||
|
* When a full GT reset is triggered it is assumed that some G2H responses to
|
||||||
|
* H2Gs can be lost as the GuC is also reset. Losing these G2H can prove to be
|
||||||
|
* fatal as we do certain operations upon receiving a G2H (e.g. destroy
|
||||||
|
* contexts, release guc_ids, etc...). When this occurs we can scrub the
|
||||||
|
* context state and cleanup appropriately, however this is quite racey.
|
||||||
|
* To avoid races, the reset code must disable submission before scrubbing for
|
||||||
|
* the missing G2H, while the submission code must check for submission being
|
||||||
|
* disabled and skip sending H2Gs and updating context states when it is. Both
|
||||||
|
* sides must also make sure to hold the relevant locks.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* GuC Virtual Engine */
|
/* GuC Virtual Engine */
|
||||||
|
|
|
@ -290,18 +290,23 @@ struct i915_request {
|
||||||
struct hrtimer timer;
|
struct hrtimer timer;
|
||||||
} watchdog;
|
} watchdog;
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Requests may need to be stalled when using GuC submission waiting for
|
* @guc_fence_link: Requests may need to be stalled when using GuC
|
||||||
* certain GuC operations to complete. If that is the case, stalled
|
* submission waiting for certain GuC operations to complete. If that is
|
||||||
* requests are added to a per context list of stalled requests. The
|
* the case, stalled requests are added to a per context list of stalled
|
||||||
* below list_head is the link in that list.
|
* requests. The below list_head is the link in that list. Protected by
|
||||||
|
* ce->guc_state.lock.
|
||||||
*/
|
*/
|
||||||
struct list_head guc_fence_link;
|
struct list_head guc_fence_link;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Priority level while the request is inflight. Differs from i915
|
* @guc_prio: Priority level while the request is in flight. Differs
|
||||||
* scheduler priority. See comment above
|
* from i915 scheduler priority. See comment above
|
||||||
* I915_SCHEDULER_CAP_STATIC_PRIORITY_MAP for details.
|
* I915_SCHEDULER_CAP_STATIC_PRIORITY_MAP for details. Protected by
|
||||||
|
* ce->guc_active.lock. Two special values (GUC_PRIO_INIT and
|
||||||
|
* GUC_PRIO_FINI) outside the GuC priority range are used to indicate
|
||||||
|
* if the priority has not been initialized yet or if no more updates
|
||||||
|
* are possible because the request has completed.
|
||||||
*/
|
*/
|
||||||
#define GUC_PRIO_INIT 0xff
|
#define GUC_PRIO_INIT 0xff
|
||||||
#define GUC_PRIO_FINI 0xfe
|
#define GUC_PRIO_FINI 0xfe
|
||||||
|
|
Loading…
Reference in New Issue