1 // SPDX-License-Identifier: MIT
3 * Copyright © 2014-2019 Intel Corporation
6 #include "gt/intel_gt.h"
7 #include "intel_guc_ads.h"
12 * 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.
19 static void guc_policy_init(struct guc_policy
*policy
)
21 policy
->execution_quantum
= POLICY_DEFAULT_EXECUTION_QUANTUM_US
;
22 policy
->preemption_time
= POLICY_DEFAULT_PREEMPTION_TIME_US
;
23 policy
->fault_time
= POLICY_DEFAULT_FAULT_TIME_US
;
24 policy
->policy_flags
= 0;
27 static void guc_policies_init(struct guc_policies
*policies
)
29 struct guc_policy
*policy
;
32 policies
->dpc_promote_time
= POLICY_DEFAULT_DPC_PROMOTE_TIME_US
;
33 policies
->max_num_work_items
= POLICY_MAX_NUM_WI
;
35 for (p
= 0; p
< GUC_CLIENT_PRIORITY_NUM
; p
++) {
36 for (i
= 0; i
< GUC_MAX_ENGINE_CLASSES
; i
++) {
37 policy
= &policies
->policy
[p
][i
];
39 guc_policy_init(policy
);
43 policies
->is_valid
= 1;
46 static void guc_ct_pool_entries_init(struct guc_ct_pool_entry
*pool
, u32 num
)
48 memset(pool
, 0, num
* sizeof(*pool
));
52 * The first 80 dwords of the register state context, containing the
53 * execlists and ppgtt registers.
55 #define LR_HW_CONTEXT_SIZE (80 * sizeof(u32))
57 /* The ads obj includes the struct itself and buffers passed to GuC */
58 struct __guc_ads_blob
{
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
];
68 static void __guc_ads_init(struct intel_guc
*guc
)
70 struct drm_i915_private
*dev_priv
= guc_to_gt(guc
)->i915
;
71 struct __guc_ads_blob
*blob
= guc
->ads_blob
;
72 const u32 skipped_size
= LRC_PPHWSP_SZ
* PAGE_SIZE
+ LR_HW_CONTEXT_SIZE
;
76 /* GuC scheduling policies */
77 guc_policies_init(&blob
->policies
);
80 * GuC expects a per-engine-class context image and size
81 * (minus hwsp and ring context). The context image will be
82 * used to reinitialize engines after a reset. It must exist
83 * and be pinned in the GGTT, so that the address won't change after
84 * we have told GuC where to find it. The context size will be used
85 * to validate that the LRC base + size fall within allowed GGTT.
87 for (engine_class
= 0; engine_class
<= MAX_ENGINE_CLASS
; ++engine_class
) {
88 if (engine_class
== OTHER_CLASS
)
91 * TODO: Set context pointer to default state to allow
92 * GuC to re-init guilty contexts after internal reset.
94 blob
->ads
.golden_context_lrca
[engine_class
] = 0;
95 blob
->ads
.eng_state_size
[engine_class
] =
96 intel_engine_context_size(guc_to_gt(guc
),
102 blob
->system_info
.slice_enabled
= hweight8(RUNTIME_INFO(dev_priv
)->sseu
.slice_mask
);
103 blob
->system_info
.rcs_enabled
= 1;
104 blob
->system_info
.bcs_enabled
= 1;
106 blob
->system_info
.vdbox_enable_mask
= VDBOX_MASK(dev_priv
);
107 blob
->system_info
.vebox_enable_mask
= VEBOX_MASK(dev_priv
);
108 blob
->system_info
.vdbox_sfc_support_mask
= RUNTIME_INFO(dev_priv
)->vdbox_sfc_access
;
110 base
= intel_guc_ggtt_offset(guc
, guc
->ads_vma
);
113 guc_ct_pool_entries_init(blob
->ct_pool
, ARRAY_SIZE(blob
->ct_pool
));
115 blob
->clients_info
.clients_num
= 1;
116 blob
->clients_info
.ct_pool_addr
= base
+ ptr_offset(blob
, ct_pool
);
117 blob
->clients_info
.ct_pool_count
= ARRAY_SIZE(blob
->ct_pool
);
120 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
);
123 blob
->ads
.gt_system_info
= base
+ ptr_offset(blob
, system_info
);
124 blob
->ads
.clients_info
= base
+ ptr_offset(blob
, clients_info
);
126 i915_gem_object_flush_map(guc
->ads_vma
->obj
);
130 * intel_guc_ads_create() - allocates and initializes GuC ADS.
131 * @guc: intel_guc struct
133 * GuC needs memory block (Additional Data Struct), where it will store
134 * some data. Allocate and initialize such memory block for GuC use.
136 int intel_guc_ads_create(struct intel_guc
*guc
)
138 const u32 size
= PAGE_ALIGN(sizeof(struct __guc_ads_blob
));
141 GEM_BUG_ON(guc
->ads_vma
);
143 ret
= intel_guc_allocate_and_map_vma(guc
, size
, &guc
->ads_vma
,
144 (void **)&guc
->ads_blob
);
154 void intel_guc_ads_destroy(struct intel_guc
*guc
)
156 i915_vma_unpin_and_release(&guc
->ads_vma
, I915_VMA_RELEASE_MAP
);
160 * intel_guc_ads_reset() - prepares GuC Additional Data Struct for reuse
161 * @guc: intel_guc struct
163 * GuC stores some data in ADS, which might be stale after a reset.
164 * Reinitialize whole ADS in case any part of it was corrupted during
167 void intel_guc_ads_reset(struct intel_guc
*guc
)