diff options
author | Joonas Lahtinen <joonas.lahtinen@linux.intel.com> | 2017-04-28 03:53:36 -0400 |
---|---|---|
committer | Joonas Lahtinen <joonas.lahtinen@linux.intel.com> | 2017-04-28 05:11:59 -0400 |
commit | 63ffbcdadcf2b5dde2cd6db6715fc94e77cd43b6 (patch) | |
tree | fdb59ad7c9664bf324f71fbb053535de891e22e1 /drivers/gpu/drm/i915/intel_engine_cs.c | |
parent | a3662830e1e120e9950072a48d75a61ed921ad4a (diff) |
drm/i915: Sanitize engine context sizes
Pre-calculate engine context size based on engine class and device
generation and store it in the engine instance.
v2:
- Squash and get rid of hw_context_size (Chris)
v3:
- Move after MMIO init for probing on Gen7 and 8 (Chris)
- Retained rounding (Tvrtko)
v4:
- Rebase for deferred legacy context allocation
Signed-off-by: Joonas Lahtinen <joonas.lahtinen@linux.intel.com>
Cc: Paulo Zanoni <paulo.r.zanoni@intel.com>
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Chris Wilson <chris@chris-wilson.co.uk>
Cc: Daniele Ceraolo Spurio <daniele.ceraolospurio@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Oscar Mateo <oscar.mateo@intel.com>
Cc: Zhenyu Wang <zhenyuw@linux.intel.com>
Cc: intel-gvt-dev@lists.freedesktop.org
Acked-by: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Cc: Tvrtko Ursulin <tvrtko.ursulin@intel.com>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/gpu/drm/i915/intel_engine_cs.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_engine_cs.c | 90 |
1 files changed, 87 insertions, 3 deletions
diff --git a/drivers/gpu/drm/i915/intel_engine_cs.c b/drivers/gpu/drm/i915/intel_engine_cs.c index 82a274b336c5..6d3d83876da9 100644 --- a/drivers/gpu/drm/i915/intel_engine_cs.c +++ b/drivers/gpu/drm/i915/intel_engine_cs.c | |||
@@ -26,6 +26,22 @@ | |||
26 | #include "intel_ringbuffer.h" | 26 | #include "intel_ringbuffer.h" |
27 | #include "intel_lrc.h" | 27 | #include "intel_lrc.h" |
28 | 28 | ||
29 | /* Haswell does have the CXT_SIZE register however it does not appear to be | ||
30 | * valid. Now, docs explain in dwords what is in the context object. The full | ||
31 | * size is 70720 bytes, however, the power context and execlist context will | ||
32 | * never be saved (power context is stored elsewhere, and execlists don't work | ||
33 | * on HSW) - so the final size, including the extra state required for the | ||
34 | * Resource Streamer, is 66944 bytes, which rounds to 17 pages. | ||
35 | */ | ||
36 | #define HSW_CXT_TOTAL_SIZE (17 * PAGE_SIZE) | ||
37 | /* Same as Haswell, but 72064 bytes now. */ | ||
38 | #define GEN8_CXT_TOTAL_SIZE (18 * PAGE_SIZE) | ||
39 | |||
40 | #define GEN8_LR_CONTEXT_RENDER_SIZE (20 * PAGE_SIZE) | ||
41 | #define GEN9_LR_CONTEXT_RENDER_SIZE (22 * PAGE_SIZE) | ||
42 | |||
43 | #define GEN8_LR_CONTEXT_OTHER_SIZE ( 2 * PAGE_SIZE) | ||
44 | |||
29 | struct engine_class_info { | 45 | struct engine_class_info { |
30 | const char *name; | 46 | const char *name; |
31 | int (*init_legacy)(struct intel_engine_cs *engine); | 47 | int (*init_legacy)(struct intel_engine_cs *engine); |
@@ -107,6 +123,69 @@ static const struct engine_info intel_engines[] = { | |||
107 | }, | 123 | }, |
108 | }; | 124 | }; |
109 | 125 | ||
126 | /** | ||
127 | * ___intel_engine_context_size() - return the size of the context for an engine | ||
128 | * @dev_priv: i915 device private | ||
129 | * @class: engine class | ||
130 | * | ||
131 | * Each engine class may require a different amount of space for a context | ||
132 | * image. | ||
133 | * | ||
134 | * Return: size (in bytes) of an engine class specific context image | ||
135 | * | ||
136 | * Note: this size includes the HWSP, which is part of the context image | ||
137 | * in LRC mode, but does not include the "shared data page" used with | ||
138 | * GuC submission. The caller should account for this if using the GuC. | ||
139 | */ | ||
140 | static u32 | ||
141 | __intel_engine_context_size(struct drm_i915_private *dev_priv, u8 class) | ||
142 | { | ||
143 | u32 cxt_size; | ||
144 | |||
145 | BUILD_BUG_ON(I915_GTT_PAGE_SIZE != PAGE_SIZE); | ||
146 | |||
147 | switch (class) { | ||
148 | case RENDER_CLASS: | ||
149 | switch (INTEL_GEN(dev_priv)) { | ||
150 | default: | ||
151 | MISSING_CASE(INTEL_GEN(dev_priv)); | ||
152 | case 9: | ||
153 | return GEN9_LR_CONTEXT_RENDER_SIZE; | ||
154 | case 8: | ||
155 | return i915.enable_execlists ? | ||
156 | GEN8_LR_CONTEXT_RENDER_SIZE : | ||
157 | GEN8_CXT_TOTAL_SIZE; | ||
158 | case 7: | ||
159 | if (IS_HASWELL(dev_priv)) | ||
160 | return HSW_CXT_TOTAL_SIZE; | ||
161 | |||
162 | cxt_size = I915_READ(GEN7_CXT_SIZE); | ||
163 | return round_up(GEN7_CXT_TOTAL_SIZE(cxt_size) * 64, | ||
164 | PAGE_SIZE); | ||
165 | case 6: | ||
166 | cxt_size = I915_READ(CXT_SIZE); | ||
167 | return round_up(GEN6_CXT_TOTAL_SIZE(cxt_size) * 64, | ||
168 | PAGE_SIZE); | ||
169 | case 5: | ||
170 | case 4: | ||
171 | case 3: | ||
172 | case 2: | ||
173 | /* For the special day when i810 gets merged. */ | ||
174 | case 1: | ||
175 | return 0; | ||
176 | } | ||
177 | break; | ||
178 | default: | ||
179 | MISSING_CASE(class); | ||
180 | case VIDEO_DECODE_CLASS: | ||
181 | case VIDEO_ENHANCEMENT_CLASS: | ||
182 | case COPY_ENGINE_CLASS: | ||
183 | if (INTEL_GEN(dev_priv) < 8) | ||
184 | return 0; | ||
185 | return GEN8_LR_CONTEXT_OTHER_SIZE; | ||
186 | } | ||
187 | } | ||
188 | |||
110 | static int | 189 | static int |
111 | intel_engine_setup(struct drm_i915_private *dev_priv, | 190 | intel_engine_setup(struct drm_i915_private *dev_priv, |
112 | enum intel_engine_id id) | 191 | enum intel_engine_id id) |
@@ -135,6 +214,11 @@ intel_engine_setup(struct drm_i915_private *dev_priv, | |||
135 | engine->class = info->class; | 214 | engine->class = info->class; |
136 | engine->instance = info->instance; | 215 | engine->instance = info->instance; |
137 | 216 | ||
217 | engine->context_size = __intel_engine_context_size(dev_priv, | ||
218 | engine->class); | ||
219 | if (WARN_ON(engine->context_size > BIT(20))) | ||
220 | engine->context_size = 0; | ||
221 | |||
138 | /* Nothing to do here, execute in order of dependencies */ | 222 | /* Nothing to do here, execute in order of dependencies */ |
139 | engine->schedule = NULL; | 223 | engine->schedule = NULL; |
140 | 224 | ||
@@ -145,12 +229,12 @@ intel_engine_setup(struct drm_i915_private *dev_priv, | |||
145 | } | 229 | } |
146 | 230 | ||
147 | /** | 231 | /** |
148 | * intel_engines_init_early() - allocate the Engine Command Streamers | 232 | * intel_engines_init_mmio() - allocate and prepare the Engine Command Streamers |
149 | * @dev_priv: i915 device private | 233 | * @dev_priv: i915 device private |
150 | * | 234 | * |
151 | * Return: non-zero if the initialization failed. | 235 | * Return: non-zero if the initialization failed. |
152 | */ | 236 | */ |
153 | int intel_engines_init_early(struct drm_i915_private *dev_priv) | 237 | int intel_engines_init_mmio(struct drm_i915_private *dev_priv) |
154 | { | 238 | { |
155 | struct intel_device_info *device_info = mkwrite_device_info(dev_priv); | 239 | struct intel_device_info *device_info = mkwrite_device_info(dev_priv); |
156 | const unsigned int ring_mask = INTEL_INFO(dev_priv)->ring_mask; | 240 | const unsigned int ring_mask = INTEL_INFO(dev_priv)->ring_mask; |
@@ -200,7 +284,7 @@ cleanup: | |||
200 | } | 284 | } |
201 | 285 | ||
202 | /** | 286 | /** |
203 | * intel_engines_init() - allocate, populate and init the Engine Command Streamers | 287 | * intel_engines_init() - init the Engine Command Streamers |
204 | * @dev_priv: i915 device private | 288 | * @dev_priv: i915 device private |
205 | * | 289 | * |
206 | * Return: non-zero if the initialization failed. | 290 | * Return: non-zero if the initialization failed. |