diff options
author | Rafael Barbalho <rafael.barbalho@intel.com> | 2013-08-21 12:10:51 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-08-23 08:52:31 -0400 |
commit | 5032d871f7d300aee10c309ea004eb4f851553fe (patch) | |
tree | 28e145929fe243527037a4c8b287f60ca333783a | |
parent | 1403c0d4d46f2eed2ab13b89561c853988ad7513 (diff) |
drm/i915: Cleaning up the relocate entry function
As the relocate entry function was getting a bit too big I've moved
the code that used to use either the cpu or the gtt to for the
relocation into two separate functions.
Signed-off-by: Rafael Barbalho <rafael.barbalho@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_execbuffer.c | 88 |
1 files changed, 54 insertions, 34 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 7dcf78cf6781..792c52a235ee 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -172,6 +172,56 @@ static inline int use_cpu_reloc(struct drm_i915_gem_object *obj) | |||
172 | } | 172 | } |
173 | 173 | ||
174 | static int | 174 | static int |
175 | relocate_entry_cpu(struct drm_i915_gem_object *obj, | ||
176 | struct drm_i915_gem_relocation_entry *reloc) | ||
177 | { | ||
178 | uint32_t page_offset = offset_in_page(reloc->offset); | ||
179 | char *vaddr; | ||
180 | int ret = -EINVAL; | ||
181 | |||
182 | ret = i915_gem_object_set_to_cpu_domain(obj, 1); | ||
183 | if (ret) | ||
184 | return ret; | ||
185 | |||
186 | vaddr = kmap_atomic(i915_gem_object_get_page(obj, | ||
187 | reloc->offset >> PAGE_SHIFT)); | ||
188 | *(uint32_t *)(vaddr + page_offset) = reloc->delta; | ||
189 | kunmap_atomic(vaddr); | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | static int | ||
195 | relocate_entry_gtt(struct drm_i915_gem_object *obj, | ||
196 | struct drm_i915_gem_relocation_entry *reloc) | ||
197 | { | ||
198 | struct drm_device *dev = obj->base.dev; | ||
199 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
200 | uint32_t __iomem *reloc_entry; | ||
201 | void __iomem *reloc_page; | ||
202 | int ret = -EINVAL; | ||
203 | |||
204 | ret = i915_gem_object_set_to_gtt_domain(obj, true); | ||
205 | if (ret) | ||
206 | return ret; | ||
207 | |||
208 | ret = i915_gem_object_put_fence(obj); | ||
209 | if (ret) | ||
210 | return ret; | ||
211 | |||
212 | /* Map the page containing the relocation we're going to perform. */ | ||
213 | reloc->offset += i915_gem_obj_ggtt_offset(obj); | ||
214 | reloc_page = io_mapping_map_atomic_wc(dev_priv->gtt.mappable, | ||
215 | reloc->offset & PAGE_MASK); | ||
216 | reloc_entry = (uint32_t __iomem *) | ||
217 | (reloc_page + offset_in_page(reloc->offset)); | ||
218 | iowrite32(reloc->delta, reloc_entry); | ||
219 | io_mapping_unmap_atomic(reloc_page); | ||
220 | |||
221 | return 0; | ||
222 | } | ||
223 | |||
224 | static int | ||
175 | i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | 225 | i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, |
176 | struct eb_objects *eb, | 226 | struct eb_objects *eb, |
177 | struct drm_i915_gem_relocation_entry *reloc, | 227 | struct drm_i915_gem_relocation_entry *reloc, |
@@ -255,40 +305,10 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
255 | return -EFAULT; | 305 | return -EFAULT; |
256 | 306 | ||
257 | reloc->delta += target_offset; | 307 | reloc->delta += target_offset; |
258 | if (use_cpu_reloc(obj)) { | 308 | if (use_cpu_reloc(obj)) |
259 | uint32_t page_offset = offset_in_page(reloc->offset); | 309 | ret = relocate_entry_cpu(obj, reloc); |
260 | char *vaddr; | 310 | else |
261 | 311 | ret = relocate_entry_gtt(obj, reloc); | |
262 | ret = i915_gem_object_set_to_cpu_domain(obj, 1); | ||
263 | if (ret) | ||
264 | return ret; | ||
265 | |||
266 | vaddr = kmap_atomic(i915_gem_object_get_page(obj, | ||
267 | reloc->offset >> PAGE_SHIFT)); | ||
268 | *(uint32_t *)(vaddr + page_offset) = reloc->delta; | ||
269 | kunmap_atomic(vaddr); | ||
270 | } else { | ||
271 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
272 | uint32_t __iomem *reloc_entry; | ||
273 | void __iomem *reloc_page; | ||
274 | |||
275 | ret = i915_gem_object_set_to_gtt_domain(obj, true); | ||
276 | if (ret) | ||
277 | return ret; | ||
278 | |||
279 | ret = i915_gem_object_put_fence(obj); | ||
280 | if (ret) | ||
281 | return ret; | ||
282 | |||
283 | /* Map the page containing the relocation we're going to perform. */ | ||
284 | reloc->offset += i915_gem_obj_ggtt_offset(obj); | ||
285 | reloc_page = io_mapping_map_atomic_wc(dev_priv->gtt.mappable, | ||
286 | reloc->offset & PAGE_MASK); | ||
287 | reloc_entry = (uint32_t __iomem *) | ||
288 | (reloc_page + offset_in_page(reloc->offset)); | ||
289 | iowrite32(reloc->delta, reloc_entry); | ||
290 | io_mapping_unmap_atomic(reloc_page); | ||
291 | } | ||
292 | 312 | ||
293 | /* and update the user's relocation entry */ | 313 | /* and update the user's relocation entry */ |
294 | reloc->presumed_offset = target_offset; | 314 | reloc->presumed_offset = target_offset; |