Skip to content

Commit c784e52

Browse files
johnharr-inteljlahtine-intel
authored andcommitted
drm/i915/guc: Update to use firmware v49.0.1
The latest GuC firmware includes a number of interface changes that require driver updates to match. * Starting from Gen11, the ID to be provided to GuC needs to contain the engine class in bits [0..2] and the instance in bits [3..6]. NOTE: this patch breaks pointer dereferences in some existing GuC functions that use the guc_id to dereference arrays but these functions are not used for now as we have GuC submission disabled and we will update these functions in follow up patch which requires new IDs. * The new GuC requires the additional data structure (ADS) and associated 'private_data' pointer to be setup. This is basically a scratch area of memory that the GuC owns. The size is read from the CSS header. * There is now a physical to logical engine mapping table in the ADS which needs to be configured in order for the firmware to load. For now, the table is initialised with a 1 to 1 mapping. * GUC_CTL_CTXINFO has been removed from the initialization params. * reg_state_buffer is maintained internally by the GuC as part of the private data. * The ADS layout has changed significantly. This patch updates the shared structure and also adds better documentation of the layout. * While i915 does not use GuC doorbells, the firmware now requires that some initialisation is done. * The number of engine classes and instances supported in the ADS has been increased. Signed-off-by: John Harrison <[email protected]> Signed-off-by: Matthew Brost <[email protected]> Signed-off-by: Daniele Ceraolo Spurio <[email protected]> Signed-off-by: Oscar Mateo <[email protected]> Signed-off-by: Michel Thierry <[email protected]> Signed-off-by: Rodrigo Vivi <[email protected]> Signed-off-by: Michal Wajdeczko <[email protected]> Cc: Michal Winiarski <[email protected]> Cc: Tomasz Lis <[email protected]> Cc: Joonas Lahtinen <[email protected]> Reviewed-by: Daniele Ceraolo Spurio <[email protected]> Signed-off-by: Joonas Lahtinen <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected]
1 parent c071ab8 commit c784e52

File tree

8 files changed

+176
-96
lines changed

8 files changed

+176
-96
lines changed

drivers/gpu/drm/i915/gt/intel_engine_cs.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -305,8 +305,9 @@ static int intel_engine_setup(struct intel_gt *gt, enum intel_engine_id id)
305305
engine->i915 = i915;
306306
engine->gt = gt;
307307
engine->uncore = gt->uncore;
308-
engine->hw_id = engine->guc_id = info->hw_id;
309308
engine->mmio_base = __engine_mmio_base(i915, info->mmio_bases);
309+
engine->hw_id = info->hw_id;
310+
engine->guc_id = MAKE_GUC_ID(info->class, info->instance);
310311

311312
engine->class = info->class;
312313
engine->instance = info->instance;

drivers/gpu/drm/i915/gt/uc/intel_guc.c

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -213,23 +213,6 @@ static u32 guc_ctl_feature_flags(struct intel_guc *guc)
213213
return flags;
214214
}
215215

216-
static u32 guc_ctl_ctxinfo_flags(struct intel_guc *guc)
217-
{
218-
u32 flags = 0;
219-
220-
if (intel_guc_submission_is_used(guc)) {
221-
u32 ctxnum, base;
222-
223-
base = intel_guc_ggtt_offset(guc, guc->stage_desc_pool);
224-
ctxnum = GUC_MAX_STAGE_DESCRIPTORS / 16;
225-
226-
base >>= PAGE_SHIFT;
227-
flags |= (base << GUC_CTL_BASE_ADDR_SHIFT) |
228-
(ctxnum << GUC_CTL_CTXNUM_IN16_SHIFT);
229-
}
230-
return flags;
231-
}
232-
233216
static u32 guc_ctl_log_params_flags(struct intel_guc *guc)
234217
{
235218
u32 offset = intel_guc_ggtt_offset(guc, guc->log.vma) >> PAGE_SHIFT;
@@ -291,7 +274,6 @@ static void guc_init_params(struct intel_guc *guc)
291274

292275
BUILD_BUG_ON(sizeof(guc->params) != GUC_CTL_MAX_DWORDS * sizeof(u32));
293276

294-
params[GUC_CTL_CTXINFO] = guc_ctl_ctxinfo_flags(guc);
295277
params[GUC_CTL_LOG_PARAMS] = guc_ctl_log_params_flags(guc);
296278
params[GUC_CTL_FEATURE] = guc_ctl_feature_flags(guc);
297279
params[GUC_CTL_DEBUG] = guc_ctl_debug_flags(guc);

drivers/gpu/drm/i915/gt/uc/intel_guc_ads.c

Lines changed: 106 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,52 @@
1010

1111
/*
1212
* The Additional Data Struct (ADS) has pointers for different buffers used by
13-
* the GuC. One single gem object contains the ADS struct itself (guc_ads), the
14-
* scheduling policies (guc_policies), a structure describing a collection of
15-
* register sets (guc_mmio_reg_state) and some extra pages for the GuC to save
16-
* its internal state for sleep.
13+
* the GuC. One single gem object contains the ADS struct itself (guc_ads) and
14+
* all the extra buffers indirectly linked via the ADS struct's entries.
15+
*
16+
* Layout of the ADS blob allocated for the GuC:
17+
*
18+
* +---------------------------------------+ <== base
19+
* | guc_ads |
20+
* +---------------------------------------+
21+
* | guc_policies |
22+
* +---------------------------------------+
23+
* | guc_gt_system_info |
24+
* +---------------------------------------+
25+
* | guc_clients_info |
26+
* +---------------------------------------+
27+
* | guc_ct_pool_entry[size] |
28+
* +---------------------------------------+
29+
* | padding |
30+
* +---------------------------------------+ <== 4K aligned
31+
* | private data |
32+
* +---------------------------------------+
33+
* | padding |
34+
* +---------------------------------------+ <== 4K aligned
1735
*/
36+
struct __guc_ads_blob {
37+
struct guc_ads ads;
38+
struct guc_policies policies;
39+
struct guc_gt_system_info system_info;
40+
struct guc_clients_info clients_info;
41+
struct guc_ct_pool_entry ct_pool[GUC_CT_POOL_SIZE];
42+
} __packed;
43+
44+
static u32 guc_ads_private_data_size(struct intel_guc *guc)
45+
{
46+
return PAGE_ALIGN(guc->fw.private_data_size);
47+
}
48+
49+
static u32 guc_ads_private_data_offset(struct intel_guc *guc)
50+
{
51+
return PAGE_ALIGN(sizeof(struct __guc_ads_blob));
52+
}
53+
54+
static u32 guc_ads_blob_size(struct intel_guc *guc)
55+
{
56+
return guc_ads_private_data_offset(guc) +
57+
guc_ads_private_data_size(guc);
58+
}
1859

1960
static void guc_policy_init(struct guc_policy *policy)
2061
{
@@ -48,26 +89,37 @@ static void guc_ct_pool_entries_init(struct guc_ct_pool_entry *pool, u32 num)
4889
memset(pool, 0, num * sizeof(*pool));
4990
}
5091

92+
static void guc_mapping_table_init(struct intel_gt *gt,
93+
struct guc_gt_system_info *system_info)
94+
{
95+
unsigned int i, j;
96+
struct intel_engine_cs *engine;
97+
enum intel_engine_id id;
98+
99+
/* Table must be set to invalid values for entries not used */
100+
for (i = 0; i < GUC_MAX_ENGINE_CLASSES; ++i)
101+
for (j = 0; j < GUC_MAX_INSTANCES_PER_CLASS; ++j)
102+
system_info->mapping_table[i][j] =
103+
GUC_MAX_INSTANCES_PER_CLASS;
104+
105+
for_each_engine(engine, gt, id) {
106+
u8 guc_class = engine->class;
107+
108+
system_info->mapping_table[guc_class][engine->instance] =
109+
engine->instance;
110+
}
111+
}
112+
51113
/*
52114
* The first 80 dwords of the register state context, containing the
53115
* execlists and ppgtt registers.
54116
*/
55117
#define LR_HW_CONTEXT_SIZE (80 * sizeof(u32))
56118

57-
/* The ads obj includes the struct itself and buffers passed to GuC */
58-
struct __guc_ads_blob {
59-
struct guc_ads ads;
60-
struct guc_policies policies;
61-
struct guc_mmio_reg_state reg_state;
62-
struct guc_gt_system_info system_info;
63-
struct guc_clients_info clients_info;
64-
struct guc_ct_pool_entry ct_pool[GUC_CT_POOL_SIZE];
65-
u8 reg_state_buffer[GUC_S3_SAVE_SPACE_PAGES * PAGE_SIZE];
66-
} __packed;
67-
68119
static void __guc_ads_init(struct intel_guc *guc)
69120
{
70121
struct intel_gt *gt = guc_to_gt(guc);
122+
struct drm_i915_private *i915 = gt->i915;
71123
struct __guc_ads_blob *blob = guc->ads_blob;
72124
const u32 skipped_size = LRC_PPHWSP_SZ * PAGE_SIZE + LR_HW_CONTEXT_SIZE;
73125
u32 base;
@@ -99,13 +151,25 @@ static void __guc_ads_init(struct intel_guc *guc)
99151
}
100152

101153
/* System info */
102-
blob->system_info.slice_enabled = hweight8(gt->info.sseu.slice_mask);
103-
blob->system_info.rcs_enabled = 1;
104-
blob->system_info.bcs_enabled = 1;
154+
blob->system_info.engine_enabled_masks[RENDER_CLASS] = 1;
155+
blob->system_info.engine_enabled_masks[COPY_ENGINE_CLASS] = 1;
156+
blob->system_info.engine_enabled_masks[VIDEO_DECODE_CLASS] = VDBOX_MASK(gt);
157+
blob->system_info.engine_enabled_masks[VIDEO_ENHANCEMENT_CLASS] = VEBOX_MASK(gt);
158+
159+
blob->system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_SLICE_ENABLED] =
160+
hweight8(gt->info.sseu.slice_mask);
161+
blob->system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_VDBOX_SFC_SUPPORT_MASK] =
162+
gt->info.vdbox_sfc_access;
163+
164+
if (INTEL_GEN(i915) >= 12 && !IS_DGFX(i915)) {
165+
u32 distdbreg = intel_uncore_read(gt->uncore,
166+
GEN12_DIST_DBS_POPULATED);
167+
blob->system_info.generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_DOORBELL_COUNT_PER_SQIDI] =
168+
((distdbreg >> GEN12_DOORBELLS_PER_SQIDI_SHIFT) &
169+
GEN12_DOORBELLS_PER_SQIDI) + 1;
170+
}
105171

106-
blob->system_info.vdbox_enable_mask = VDBOX_MASK(gt);
107-
blob->system_info.vebox_enable_mask = VEBOX_MASK(gt);
108-
blob->system_info.vdbox_sfc_support_mask = gt->info.vdbox_sfc_access;
172+
guc_mapping_table_init(guc_to_gt(guc), &blob->system_info);
109173

110174
base = intel_guc_ggtt_offset(guc, guc->ads_vma);
111175

@@ -118,11 +182,12 @@ static void __guc_ads_init(struct intel_guc *guc)
118182

119183
/* ADS */
120184
blob->ads.scheduler_policies = base + ptr_offset(blob, policies);
121-
blob->ads.reg_state_buffer = base + ptr_offset(blob, reg_state_buffer);
122-
blob->ads.reg_state_addr = base + ptr_offset(blob, reg_state);
123185
blob->ads.gt_system_info = base + ptr_offset(blob, system_info);
124186
blob->ads.clients_info = base + ptr_offset(blob, clients_info);
125187

188+
/* Private Data */
189+
blob->ads.private_data = base + guc_ads_private_data_offset(guc);
190+
126191
i915_gem_object_flush_map(guc->ads_vma->obj);
127192
}
128193

@@ -135,14 +200,15 @@ static void __guc_ads_init(struct intel_guc *guc)
135200
*/
136201
int intel_guc_ads_create(struct intel_guc *guc)
137202
{
138-
const u32 size = PAGE_ALIGN(sizeof(struct __guc_ads_blob));
203+
u32 size;
139204
int ret;
140205

141206
GEM_BUG_ON(guc->ads_vma);
142207

208+
size = guc_ads_blob_size(guc);
209+
143210
ret = intel_guc_allocate_and_map_vma(guc, size, &guc->ads_vma,
144211
(void **)&guc->ads_blob);
145-
146212
if (ret)
147213
return ret;
148214

@@ -156,6 +222,18 @@ void intel_guc_ads_destroy(struct intel_guc *guc)
156222
i915_vma_unpin_and_release(&guc->ads_vma, I915_VMA_RELEASE_MAP);
157223
}
158224

225+
static void guc_ads_private_data_reset(struct intel_guc *guc)
226+
{
227+
u32 size;
228+
229+
size = guc_ads_private_data_size(guc);
230+
if (!size)
231+
return;
232+
233+
memset((void *)guc->ads_blob + guc_ads_private_data_offset(guc), 0,
234+
size);
235+
}
236+
159237
/**
160238
* intel_guc_ads_reset() - prepares GuC Additional Data Struct for reuse
161239
* @guc: intel_guc struct
@@ -168,5 +246,8 @@ void intel_guc_ads_reset(struct intel_guc *guc)
168246
{
169247
if (!guc->ads_vma)
170248
return;
249+
171250
__guc_ads_init(guc);
251+
252+
guc_ads_private_data_reset(guc);
172253
}

drivers/gpu/drm/i915/gt/uc/intel_guc_fwif.h

Lines changed: 43 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
#define GUC_VIDEO_ENGINE2 4
2727
#define GUC_MAX_ENGINES_NUM (GUC_VIDEO_ENGINE2 + 1)
2828

29-
#define GUC_MAX_ENGINE_CLASSES 5
30-
#define GUC_MAX_INSTANCES_PER_CLASS 16
29+
#define GUC_MAX_ENGINE_CLASSES 16
30+
#define GUC_MAX_INSTANCES_PER_CLASS 32
3131

3232
#define GUC_DOORBELL_INVALID 256
3333

@@ -62,12 +62,7 @@
6262
#define GUC_STAGE_DESC_ATTR_PCH BIT(6)
6363
#define GUC_STAGE_DESC_ATTR_TERMINATED BIT(7)
6464

65-
/* New GuC control data */
66-
#define GUC_CTL_CTXINFO 0
67-
#define GUC_CTL_CTXNUM_IN16_SHIFT 0
68-
#define GUC_CTL_BASE_ADDR_SHIFT 12
69-
70-
#define GUC_CTL_LOG_PARAMS 1
65+
#define GUC_CTL_LOG_PARAMS 0
7166
#define GUC_LOG_VALID (1 << 0)
7267
#define GUC_LOG_NOTIFY_ON_HALF_FULL (1 << 1)
7368
#define GUC_LOG_ALLOC_IN_MEGABYTE (1 << 3)
@@ -79,11 +74,11 @@
7974
#define GUC_LOG_ISR_MASK (0x7 << GUC_LOG_ISR_SHIFT)
8075
#define GUC_LOG_BUF_ADDR_SHIFT 12
8176

82-
#define GUC_CTL_WA 2
83-
#define GUC_CTL_FEATURE 3
77+
#define GUC_CTL_WA 1
78+
#define GUC_CTL_FEATURE 2
8479
#define GUC_CTL_DISABLE_SCHEDULER (1 << 14)
8580

86-
#define GUC_CTL_DEBUG 4
81+
#define GUC_CTL_DEBUG 3
8782
#define GUC_LOG_VERBOSITY_SHIFT 0
8883
#define GUC_LOG_VERBOSITY_LOW (0 << GUC_LOG_VERBOSITY_SHIFT)
8984
#define GUC_LOG_VERBOSITY_MED (1 << GUC_LOG_VERBOSITY_SHIFT)
@@ -97,12 +92,37 @@
9792
#define GUC_LOG_DISABLED (1 << 6)
9893
#define GUC_PROFILE_ENABLED (1 << 7)
9994

100-
#define GUC_CTL_ADS 5
95+
#define GUC_CTL_ADS 4
10196
#define GUC_ADS_ADDR_SHIFT 1
10297
#define GUC_ADS_ADDR_MASK (0xFFFFF << GUC_ADS_ADDR_SHIFT)
10398

10499
#define GUC_CTL_MAX_DWORDS (SOFT_SCRATCH_COUNT - 2) /* [1..14] */
105100

101+
/* Generic GT SysInfo data types */
102+
#define GUC_GENERIC_GT_SYSINFO_SLICE_ENABLED 0
103+
#define GUC_GENERIC_GT_SYSINFO_VDBOX_SFC_SUPPORT_MASK 1
104+
#define GUC_GENERIC_GT_SYSINFO_DOORBELL_COUNT_PER_SQIDI 2
105+
#define GUC_GENERIC_GT_SYSINFO_MAX 16
106+
107+
/*
108+
* The class goes in bits [0..2] of the GuC ID, the instance in bits [3..6].
109+
* Bit 7 can be used for operations that apply to all engine classes&instances.
110+
*/
111+
#define GUC_ENGINE_CLASS_SHIFT 0
112+
#define GUC_ENGINE_CLASS_MASK (0x7 << GUC_ENGINE_CLASS_SHIFT)
113+
#define GUC_ENGINE_INSTANCE_SHIFT 3
114+
#define GUC_ENGINE_INSTANCE_MASK (0xf << GUC_ENGINE_INSTANCE_SHIFT)
115+
#define GUC_ENGINE_ALL_INSTANCES BIT(7)
116+
117+
#define MAKE_GUC_ID(class, instance) \
118+
(((class) << GUC_ENGINE_CLASS_SHIFT) | \
119+
((instance) << GUC_ENGINE_INSTANCE_SHIFT))
120+
121+
#define GUC_ID_TO_ENGINE_CLASS(guc_id) \
122+
(((guc_id) & GUC_ENGINE_CLASS_MASK) >> GUC_ENGINE_CLASS_SHIFT)
123+
#define GUC_ID_TO_ENGINE_INSTANCE(guc_id) \
124+
(((guc_id) & GUC_ENGINE_INSTANCE_MASK) >> GUC_ENGINE_INSTANCE_SHIFT)
125+
106126
/* Work item for submitting workloads into work queue of GuC. */
107127
struct guc_wq_item {
108128
u32 header;
@@ -336,40 +356,25 @@ struct guc_policies {
336356
} __packed;
337357

338358
/* GuC MMIO reg state struct */
339-
340-
341-
#define GUC_REGSET_MAX_REGISTERS 64
342-
#define GUC_S3_SAVE_SPACE_PAGES 10
343-
344359
struct guc_mmio_reg {
345360
u32 offset;
346361
u32 value;
347362
u32 flags;
348363
#define GUC_REGSET_MASKED (1 << 0)
349364
} __packed;
350365

351-
struct guc_mmio_regset {
352-
struct guc_mmio_reg registers[GUC_REGSET_MAX_REGISTERS];
353-
u32 values_valid;
354-
u32 number_of_registers;
355-
} __packed;
356-
357366
/* GuC register sets */
358-
struct guc_mmio_reg_state {
359-
struct guc_mmio_regset engine_reg[GUC_MAX_ENGINE_CLASSES][GUC_MAX_INSTANCES_PER_CLASS];
360-
u32 reserved[98];
367+
struct guc_mmio_reg_set {
368+
u32 address;
369+
u16 count;
370+
u16 reserved;
361371
} __packed;
362372

363373
/* HW info */
364374
struct guc_gt_system_info {
365-
u32 slice_enabled;
366-
u32 rcs_enabled;
367-
u32 reserved0;
368-
u32 bcs_enabled;
369-
u32 vdbox_enable_mask;
370-
u32 vdbox_sfc_support_mask;
371-
u32 vebox_enable_mask;
372-
u32 reserved[9];
375+
u8 mapping_table[GUC_MAX_ENGINE_CLASSES][GUC_MAX_INSTANCES_PER_CLASS];
376+
u32 engine_enabled_masks[GUC_MAX_ENGINE_CLASSES];
377+
u32 generic_gt_sysinfo[GUC_GENERIC_GT_SYSINFO_MAX];
373378
} __packed;
374379

375380
/* Clients info */
@@ -390,15 +395,16 @@ struct guc_clients_info {
390395

391396
/* GuC Additional Data Struct */
392397
struct guc_ads {
393-
u32 reg_state_addr;
394-
u32 reg_state_buffer;
398+
struct guc_mmio_reg_set reg_state_list[GUC_MAX_ENGINE_CLASSES][GUC_MAX_INSTANCES_PER_CLASS];
399+
u32 reserved0;
395400
u32 scheduler_policies;
396401
u32 gt_system_info;
397402
u32 clients_info;
398403
u32 control_data;
399404
u32 golden_context_lrca[GUC_MAX_ENGINE_CLASSES];
400405
u32 eng_state_size[GUC_MAX_ENGINE_CLASSES];
401-
u32 reserved[16];
406+
u32 private_data;
407+
u32 reserved[15];
402408
} __packed;
403409

404410
/* GuC logging structures */

0 commit comments

Comments
 (0)