aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/ttm/ttm_bo_util.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/ttm/ttm_bo_util.c')
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo_util.c85
1 files changed, 52 insertions, 33 deletions
diff --git a/drivers/gpu/drm/ttm/ttm_bo_util.c b/drivers/gpu/drm/ttm/ttm_bo_util.c
index 1f730b3f18e5..2ebbae6067ab 100644
--- a/drivers/gpu/drm/ttm/ttm_bo_util.c
+++ b/drivers/gpu/drm/ttm/ttm_bo_util.c
@@ -255,6 +255,54 @@ static int ttm_copy_io_page(void *dst, void *src, unsigned long page)
255 return 0; 255 return 0;
256} 256}
257 257
258#ifdef CONFIG_X86
259#define __ttm_kmap_atomic_prot(__page, __prot) kmap_atomic_prot(__page, __prot)
260#define __ttm_kunmap_atomic(__addr) kunmap_atomic(__addr)
261#else
262#define __ttm_kmap_atomic_prot(__page, __prot) vmap(&__page, 1, 0, __prot)
263#define __ttm_kunmap_atomic(__addr) vunmap(__addr)
264#endif
265
266
267/**
268 * ttm_kmap_atomic_prot - Efficient kernel map of a single page with
269 * specified page protection.
270 *
271 * @page: The page to map.
272 * @prot: The page protection.
273 *
274 * This function maps a TTM page using the kmap_atomic api if available,
275 * otherwise falls back to vmap. The user must make sure that the
276 * specified page does not have an aliased mapping with a different caching
277 * policy unless the architecture explicitly allows it. Also mapping and
278 * unmapping using this api must be correctly nested. Unmapping should
279 * occur in the reverse order of mapping.
280 */
281void *ttm_kmap_atomic_prot(struct page *page, pgprot_t prot)
282{
283 if (pgprot_val(prot) == pgprot_val(PAGE_KERNEL))
284 return kmap_atomic(page);
285 else
286 return __ttm_kmap_atomic_prot(page, prot);
287}
288EXPORT_SYMBOL(ttm_kmap_atomic_prot);
289
290/**
291 * ttm_kunmap_atomic_prot - Unmap a page that was mapped using
292 * ttm_kmap_atomic_prot.
293 *
294 * @addr: The virtual address from the map.
295 * @prot: The page protection.
296 */
297void ttm_kunmap_atomic_prot(void *addr, pgprot_t prot)
298{
299 if (pgprot_val(prot) == pgprot_val(PAGE_KERNEL))
300 kunmap_atomic(addr);
301 else
302 __ttm_kunmap_atomic(addr);
303}
304EXPORT_SYMBOL(ttm_kunmap_atomic_prot);
305
258static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src, 306static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src,
259 unsigned long page, 307 unsigned long page,
260 pgprot_t prot) 308 pgprot_t prot)
@@ -266,28 +314,13 @@ static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src,
266 return -ENOMEM; 314 return -ENOMEM;
267 315
268 src = (void *)((unsigned long)src + (page << PAGE_SHIFT)); 316 src = (void *)((unsigned long)src + (page << PAGE_SHIFT));
269 317 dst = ttm_kmap_atomic_prot(d, prot);
270#ifdef CONFIG_X86
271 dst = kmap_atomic_prot(d, prot);
272#else
273 if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL))
274 dst = vmap(&d, 1, 0, prot);
275 else
276 dst = kmap(d);
277#endif
278 if (!dst) 318 if (!dst)
279 return -ENOMEM; 319 return -ENOMEM;
280 320
281 memcpy_fromio(dst, src, PAGE_SIZE); 321 memcpy_fromio(dst, src, PAGE_SIZE);
282 322
283#ifdef CONFIG_X86 323 ttm_kunmap_atomic_prot(dst, prot);
284 kunmap_atomic(dst);
285#else
286 if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL))
287 vunmap(dst);
288 else
289 kunmap(d);
290#endif
291 324
292 return 0; 325 return 0;
293} 326}
@@ -303,27 +336,13 @@ static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst,
303 return -ENOMEM; 336 return -ENOMEM;
304 337
305 dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT)); 338 dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT));
306#ifdef CONFIG_X86 339 src = ttm_kmap_atomic_prot(s, prot);
307 src = kmap_atomic_prot(s, prot);
308#else
309 if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL))
310 src = vmap(&s, 1, 0, prot);
311 else
312 src = kmap(s);
313#endif
314 if (!src) 340 if (!src)
315 return -ENOMEM; 341 return -ENOMEM;
316 342
317 memcpy_toio(dst, src, PAGE_SIZE); 343 memcpy_toio(dst, src, PAGE_SIZE);
318 344
319#ifdef CONFIG_X86 345 ttm_kunmap_atomic_prot(src, prot);
320 kunmap_atomic(src);
321#else
322 if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL))
323 vunmap(src);
324 else
325 kunmap(s);
326#endif
327 346
328 return 0; 347 return 0;
329} 348}