aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/i915/intel_engine_cs.c
diff options
context:
space:
mode:
authorJoonas Lahtinen <joonas.lahtinen@linux.intel.com>2017-04-28 03:53:36 -0400
committerJoonas Lahtinen <joonas.lahtinen@linux.intel.com>2017-04-28 05:11:59 -0400
commit63ffbcdadcf2b5dde2cd6db6715fc94e77cd43b6 (patch)
treefdb59ad7c9664bf324f71fbb053535de891e22e1 /drivers/gpu/drm/i915/intel_engine_cs.c
parenta3662830e1e120e9950072a48d75a61ed921ad4a (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.c90
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
29struct engine_class_info { 45struct 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 */
140static 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
110static int 189static int
111intel_engine_setup(struct drm_i915_private *dev_priv, 190intel_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 */
153int intel_engines_init_early(struct drm_i915_private *dev_priv) 237int 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.