1 /************************************************************************** 2 * 3 * Copyright (c) 2007-2009 VMware, Inc., Palo Alto, CA., USA 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 21 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 24 * USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 /* 28 * Authors: Thomas Hellstrom <thellstrom-at-vmware-dot-com> 29 */ 30 31 #include "ttm/ttm_bo_driver.h" 32 #include "ttm/ttm_placement.h" 33 #include <linux/io.h> 34 #include <linux/highmem.h> 35 #include <linux/wait.h> 36 #include <linux/vmalloc.h> 37 #include <linux/module.h> 38 39 void ttm_bo_free_old_node(struct ttm_buffer_object *bo) 40 { 41 struct ttm_mem_reg *old_mem = &bo->mem; 42 43 if (old_mem->mm_node) { 44 spin_lock(&bo->bdev->lru_lock); 45 drm_mm_put_block(old_mem->mm_node); 46 spin_unlock(&bo->bdev->lru_lock); 47 } 48 old_mem->mm_node = NULL; 49 } 50 51 int ttm_bo_move_ttm(struct ttm_buffer_object *bo, 52 bool evict, bool no_wait, struct ttm_mem_reg *new_mem) 53 { 54 struct ttm_tt *ttm = bo->ttm; 55 struct ttm_mem_reg *old_mem = &bo->mem; 56 uint32_t save_flags = old_mem->placement; 57 int ret; 58 59 if (old_mem->mem_type != TTM_PL_SYSTEM) { 60 ttm_tt_unbind(ttm); 61 ttm_bo_free_old_node(bo); 62 ttm_flag_masked(&old_mem->placement, TTM_PL_FLAG_SYSTEM, 63 TTM_PL_MASK_MEM); 64 old_mem->mem_type = TTM_PL_SYSTEM; 65 save_flags = old_mem->placement; 66 } 67 68 ret = ttm_tt_set_placement_caching(ttm, new_mem->placement); 69 if (unlikely(ret != 0)) 70 return ret; 71 72 if (new_mem->mem_type != TTM_PL_SYSTEM) { 73 ret = ttm_tt_bind(ttm, new_mem); 74 if (unlikely(ret != 0)) 75 return ret; 76 } 77 78 *old_mem = *new_mem; 79 new_mem->mm_node = NULL; 80 ttm_flag_masked(&save_flags, new_mem->placement, TTM_PL_MASK_MEMTYPE); 81 return 0; 82 } 83 EXPORT_SYMBOL(ttm_bo_move_ttm); 84 85 int ttm_mem_reg_ioremap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem, 86 void **virtual) 87 { 88 struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; 89 unsigned long bus_offset; 90 unsigned long bus_size; 91 unsigned long bus_base; 92 int ret; 93 void *addr; 94 95 *virtual = NULL; 96 ret = ttm_bo_pci_offset(bdev, mem, &bus_base, &bus_offset, &bus_size); 97 if (ret || bus_size == 0) 98 return ret; 99 100 if (!(man->flags & TTM_MEMTYPE_FLAG_NEEDS_IOREMAP)) 101 addr = (void *)(((u8 *) man->io_addr) + bus_offset); 102 else { 103 if (mem->placement & TTM_PL_FLAG_WC) 104 addr = ioremap_wc(bus_base + bus_offset, bus_size); 105 else 106 addr = ioremap_nocache(bus_base + bus_offset, bus_size); 107 if (!addr) 108 return -ENOMEM; 109 } 110 *virtual = addr; 111 return 0; 112 } 113 114 void ttm_mem_reg_iounmap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem, 115 void *virtual) 116 { 117 struct ttm_mem_type_manager *man; 118 119 man = &bdev->man[mem->mem_type]; 120 121 if (virtual && (man->flags & TTM_MEMTYPE_FLAG_NEEDS_IOREMAP)) 122 iounmap(virtual); 123 } 124 125 static int ttm_copy_io_page(void *dst, void *src, unsigned long page) 126 { 127 uint32_t *dstP = 128 (uint32_t *) ((unsigned long)dst + (page << PAGE_SHIFT)); 129 uint32_t *srcP = 130 (uint32_t *) ((unsigned long)src + (page << PAGE_SHIFT)); 131 132 int i; 133 for (i = 0; i < PAGE_SIZE / sizeof(uint32_t); ++i) 134 iowrite32(ioread32(srcP++), dstP++); 135 return 0; 136 } 137 138 static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src, 139 unsigned long page, 140 pgprot_t prot) 141 { 142 struct page *d = ttm_tt_get_page(ttm, page); 143 void *dst; 144 145 if (!d) 146 return -ENOMEM; 147 148 src = (void *)((unsigned long)src + (page << PAGE_SHIFT)); 149 150 #ifdef CONFIG_X86 151 dst = kmap_atomic_prot(d, KM_USER0, prot); 152 #else 153 if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) 154 dst = vmap(&d, 1, 0, prot); 155 else 156 dst = kmap(d); 157 #endif 158 if (!dst) 159 return -ENOMEM; 160 161 memcpy_fromio(dst, src, PAGE_SIZE); 162 163 #ifdef CONFIG_X86 164 kunmap_atomic(dst, KM_USER0); 165 #else 166 if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) 167 vunmap(dst); 168 else 169 kunmap(d); 170 #endif 171 172 return 0; 173 } 174 175 static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst, 176 unsigned long page, 177 pgprot_t prot) 178 { 179 struct page *s = ttm_tt_get_page(ttm, page); 180 void *src; 181 182 if (!s) 183 return -ENOMEM; 184 185 dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT)); 186 #ifdef CONFIG_X86 187 src = kmap_atomic_prot(s, KM_USER0, prot); 188 #else 189 if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) 190 src = vmap(&s, 1, 0, prot); 191 else 192 src = kmap(s); 193 #endif 194 if (!src) 195 return -ENOMEM; 196 197 memcpy_toio(dst, src, PAGE_SIZE); 198 199 #ifdef CONFIG_X86 200 kunmap_atomic(src, KM_USER0); 201 #else 202 if (pgprot_val(prot) != pgprot_val(PAGE_KERNEL)) 203 vunmap(src); 204 else 205 kunmap(s); 206 #endif 207 208 return 0; 209 } 210 211 int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, 212 bool evict, bool no_wait, struct ttm_mem_reg *new_mem) 213 { 214 struct ttm_bo_device *bdev = bo->bdev; 215 struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type]; 216 struct ttm_tt *ttm = bo->ttm; 217 struct ttm_mem_reg *old_mem = &bo->mem; 218 struct ttm_mem_reg old_copy = *old_mem; 219 void *old_iomap; 220 void *new_iomap; 221 int ret; 222 uint32_t save_flags = old_mem->placement; 223 unsigned long i; 224 unsigned long page; 225 unsigned long add = 0; 226 int dir; 227 228 ret = ttm_mem_reg_ioremap(bdev, old_mem, &old_iomap); 229 if (ret) 230 return ret; 231 ret = ttm_mem_reg_ioremap(bdev, new_mem, &new_iomap); 232 if (ret) 233 goto out; 234 235 if (old_iomap == NULL && new_iomap == NULL) 236 goto out2; 237 if (old_iomap == NULL && ttm == NULL) 238 goto out2; 239 240 add = 0; 241 dir = 1; 242 243 if ((old_mem->mem_type == new_mem->mem_type) && 244 (new_mem->mm_node->start < 245 old_mem->mm_node->start + old_mem->mm_node->size)) { 246 dir = -1; 247 add = new_mem->num_pages - 1; 248 } 249 250 for (i = 0; i < new_mem->num_pages; ++i) { 251 page = i * dir + add; 252 if (old_iomap == NULL) { 253 pgprot_t prot = ttm_io_prot(old_mem->placement, 254 PAGE_KERNEL); 255 ret = ttm_copy_ttm_io_page(ttm, new_iomap, page, 256 prot); 257 } else if (new_iomap == NULL) { 258 pgprot_t prot = ttm_io_prot(new_mem->placement, 259 PAGE_KERNEL); 260 ret = ttm_copy_io_ttm_page(ttm, old_iomap, page, 261 prot); 262 } else 263 ret = ttm_copy_io_page(new_iomap, old_iomap, page); 264 if (ret) 265 goto out1; 266 } 267 mb(); 268 out2: 269 ttm_bo_free_old_node(bo); 270 271 *old_mem = *new_mem; 272 new_mem->mm_node = NULL; 273 ttm_flag_masked(&save_flags, new_mem->placement, TTM_PL_MASK_MEMTYPE); 274 275 if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) && (ttm != NULL)) { 276 ttm_tt_unbind(ttm); 277 ttm_tt_destroy(ttm); 278 bo->ttm = NULL; 279 } 280 281 out1: 282 ttm_mem_reg_iounmap(bdev, new_mem, new_iomap); 283 out: 284 ttm_mem_reg_iounmap(bdev, &old_copy, old_iomap); 285 return ret; 286 } 287 EXPORT_SYMBOL(ttm_bo_move_memcpy); 288 289 static void ttm_transfered_destroy(struct ttm_buffer_object *bo) 290 { 291 kfree(bo); 292 } 293 294 /** 295 * ttm_buffer_object_transfer 296 * 297 * @bo: A pointer to a struct ttm_buffer_object. 298 * @new_obj: A pointer to a pointer to a newly created ttm_buffer_object, 299 * holding the data of @bo with the old placement. 300 * 301 * This is a utility function that may be called after an accelerated move 302 * has been scheduled. A new buffer object is created as a placeholder for 303 * the old data while it's being copied. When that buffer object is idle, 304 * it can be destroyed, releasing the space of the old placement. 305 * Returns: 306 * !0: Failure. 307 */ 308 309 static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo, 310 struct ttm_buffer_object **new_obj) 311 { 312 struct ttm_buffer_object *fbo; 313 struct ttm_bo_device *bdev = bo->bdev; 314 struct ttm_bo_driver *driver = bdev->driver; 315 316 fbo = kzalloc(sizeof(*fbo), GFP_KERNEL); 317 if (!fbo) 318 return -ENOMEM; 319 320 *fbo = *bo; 321 322 /** 323 * Fix up members that we shouldn't copy directly: 324 * TODO: Explicit member copy would probably be better here. 325 */ 326 327 spin_lock_init(&fbo->lock); 328 init_waitqueue_head(&fbo->event_queue); 329 INIT_LIST_HEAD(&fbo->ddestroy); 330 INIT_LIST_HEAD(&fbo->lru); 331 INIT_LIST_HEAD(&fbo->swap); 332 fbo->vm_node = NULL; 333 334 fbo->sync_obj = driver->sync_obj_ref(bo->sync_obj); 335 if (fbo->mem.mm_node) 336 fbo->mem.mm_node->private = (void *)fbo; 337 kref_init(&fbo->list_kref); 338 kref_init(&fbo->kref); 339 fbo->destroy = &ttm_transfered_destroy; 340 341 *new_obj = fbo; 342 return 0; 343 } 344 345 pgprot_t ttm_io_prot(uint32_t caching_flags, pgprot_t tmp) 346 { 347 #if defined(__i386__) || defined(__x86_64__) 348 if (caching_flags & TTM_PL_FLAG_WC) 349 tmp = pgprot_writecombine(tmp); 350 else if (boot_cpu_data.x86 > 3) 351 tmp = pgprot_noncached(tmp); 352 353 #elif defined(__powerpc__) 354 if (!(caching_flags & TTM_PL_FLAG_CACHED)) { 355 pgprot_val(tmp) |= _PAGE_NO_CACHE; 356 if (caching_flags & TTM_PL_FLAG_UNCACHED) 357 pgprot_val(tmp) |= _PAGE_GUARDED; 358 } 359 #endif 360 #if defined(__ia64__) 361 if (caching_flags & TTM_PL_FLAG_WC) 362 tmp = pgprot_writecombine(tmp); 363 else 364 tmp = pgprot_noncached(tmp); 365 #endif 366 #if defined(__sparc__) 367 if (!(caching_flags & TTM_PL_FLAG_CACHED)) 368 tmp = pgprot_noncached(tmp); 369 #endif 370 return tmp; 371 } 372 373 static int ttm_bo_ioremap(struct ttm_buffer_object *bo, 374 unsigned long bus_base, 375 unsigned long bus_offset, 376 unsigned long bus_size, 377 struct ttm_bo_kmap_obj *map) 378 { 379 struct ttm_bo_device *bdev = bo->bdev; 380 struct ttm_mem_reg *mem = &bo->mem; 381 struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type]; 382 383 if (!(man->flags & TTM_MEMTYPE_FLAG_NEEDS_IOREMAP)) { 384 map->bo_kmap_type = ttm_bo_map_premapped; 385 map->virtual = (void *)(((u8 *) man->io_addr) + bus_offset); 386 } else { 387 map->bo_kmap_type = ttm_bo_map_iomap; 388 if (mem->placement & TTM_PL_FLAG_WC) 389 map->virtual = ioremap_wc(bus_base + bus_offset, 390 bus_size); 391 else 392 map->virtual = ioremap_nocache(bus_base + bus_offset, 393 bus_size); 394 } 395 return (!map->virtual) ? -ENOMEM : 0; 396 } 397 398 static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo, 399 unsigned long start_page, 400 unsigned long num_pages, 401 struct ttm_bo_kmap_obj *map) 402 { 403 struct ttm_mem_reg *mem = &bo->mem; pgprot_t prot; 404 struct ttm_tt *ttm = bo->ttm; 405 struct page *d; 406 int i; 407 408 BUG_ON(!ttm); 409 if (num_pages == 1 && (mem->placement & TTM_PL_FLAG_CACHED)) { 410 /* 411 * We're mapping a single page, and the desired 412 * page protection is consistent with the bo. 413 */ 414 415 map->bo_kmap_type = ttm_bo_map_kmap; 416 map->page = ttm_tt_get_page(ttm, start_page); 417 map->virtual = kmap(map->page); 418 } else { 419 /* 420 * Populate the part we're mapping; 421 */ 422 for (i = start_page; i < start_page + num_pages; ++i) { 423 d = ttm_tt_get_page(ttm, i); 424 if (!d) 425 return -ENOMEM; 426 } 427 428 /* 429 * We need to use vmap to get the desired page protection 430 * or to make the buffer object look contigous. 431 */ 432 prot = (mem->placement & TTM_PL_FLAG_CACHED) ? 433 PAGE_KERNEL : 434 ttm_io_prot(mem->placement, PAGE_KERNEL); 435 map->bo_kmap_type = ttm_bo_map_vmap; 436 map->virtual = vmap(ttm->pages + start_page, num_pages, 437 0, prot); 438 } 439 return (!map->virtual) ? -ENOMEM : 0; 440 } 441 442 int ttm_bo_kmap(struct ttm_buffer_object *bo, 443 unsigned long start_page, unsigned long num_pages, 444 struct ttm_bo_kmap_obj *map) 445 { 446 int ret; 447 unsigned long bus_base; 448 unsigned long bus_offset; 449 unsigned long bus_size; 450 451 BUG_ON(!list_empty(&bo->swap)); 452 map->virtual = NULL; 453 if (num_pages > bo->num_pages) 454 return -EINVAL; 455 if (start_page > bo->num_pages) 456 return -EINVAL; 457 #if 0 458 if (num_pages > 1 && !DRM_SUSER(DRM_CURPROC)) 459 return -EPERM; 460 #endif 461 ret = ttm_bo_pci_offset(bo->bdev, &bo->mem, &bus_base, 462 &bus_offset, &bus_size); 463 if (ret) 464 return ret; 465 if (bus_size == 0) { 466 return ttm_bo_kmap_ttm(bo, start_page, num_pages, map); 467 } else { 468 bus_offset += start_page << PAGE_SHIFT; 469 bus_size = num_pages << PAGE_SHIFT; 470 return ttm_bo_ioremap(bo, bus_base, bus_offset, bus_size, map); 471 } 472 } 473 EXPORT_SYMBOL(ttm_bo_kmap); 474 475 void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map) 476 { 477 if (!map->virtual) 478 return; 479 switch (map->bo_kmap_type) { 480 case ttm_bo_map_iomap: 481 iounmap(map->virtual); 482 break; 483 case ttm_bo_map_vmap: 484 vunmap(map->virtual); 485 break; 486 case ttm_bo_map_kmap: 487 kunmap(map->page); 488 break; 489 case ttm_bo_map_premapped: 490 break; 491 default: 492 BUG(); 493 } 494 map->virtual = NULL; 495 map->page = NULL; 496 } 497 EXPORT_SYMBOL(ttm_bo_kunmap); 498 499 int ttm_bo_pfn_prot(struct ttm_buffer_object *bo, 500 unsigned long dst_offset, 501 unsigned long *pfn, pgprot_t *prot) 502 { 503 struct ttm_mem_reg *mem = &bo->mem; 504 struct ttm_bo_device *bdev = bo->bdev; 505 unsigned long bus_offset; 506 unsigned long bus_size; 507 unsigned long bus_base; 508 int ret; 509 ret = ttm_bo_pci_offset(bdev, mem, &bus_base, &bus_offset, 510 &bus_size); 511 if (ret) 512 return -EINVAL; 513 if (bus_size != 0) 514 *pfn = (bus_base + bus_offset + dst_offset) >> PAGE_SHIFT; 515 else 516 if (!bo->ttm) 517 return -EINVAL; 518 else 519 *pfn = page_to_pfn(ttm_tt_get_page(bo->ttm, 520 dst_offset >> 521 PAGE_SHIFT)); 522 *prot = (mem->placement & TTM_PL_FLAG_CACHED) ? 523 PAGE_KERNEL : ttm_io_prot(mem->placement, PAGE_KERNEL); 524 525 return 0; 526 } 527 528 int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo, 529 void *sync_obj, 530 void *sync_obj_arg, 531 bool evict, bool no_wait, 532 struct ttm_mem_reg *new_mem) 533 { 534 struct ttm_bo_device *bdev = bo->bdev; 535 struct ttm_bo_driver *driver = bdev->driver; 536 struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type]; 537 struct ttm_mem_reg *old_mem = &bo->mem; 538 int ret; 539 uint32_t save_flags = old_mem->placement; 540 struct ttm_buffer_object *ghost_obj; 541 void *tmp_obj = NULL; 542 543 spin_lock(&bo->lock); 544 if (bo->sync_obj) { 545 tmp_obj = bo->sync_obj; 546 bo->sync_obj = NULL; 547 } 548 bo->sync_obj = driver->sync_obj_ref(sync_obj); 549 bo->sync_obj_arg = sync_obj_arg; 550 if (evict) { 551 ret = ttm_bo_wait(bo, false, false, false); 552 spin_unlock(&bo->lock); 553 if (tmp_obj) 554 driver->sync_obj_unref(&tmp_obj); 555 if (ret) 556 return ret; 557 558 ttm_bo_free_old_node(bo); 559 if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) && 560 (bo->ttm != NULL)) { 561 ttm_tt_unbind(bo->ttm); 562 ttm_tt_destroy(bo->ttm); 563 bo->ttm = NULL; 564 } 565 } else { 566 /** 567 * This should help pipeline ordinary buffer moves. 568 * 569 * Hang old buffer memory on a new buffer object, 570 * and leave it to be released when the GPU 571 * operation has completed. 572 */ 573 574 set_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags); 575 spin_unlock(&bo->lock); 576 if (tmp_obj) 577 driver->sync_obj_unref(&tmp_obj); 578 579 ret = ttm_buffer_object_transfer(bo, &ghost_obj); 580 if (ret) 581 return ret; 582 583 /** 584 * If we're not moving to fixed memory, the TTM object 585 * needs to stay alive. Otherwhise hang it on the ghost 586 * bo to be unbound and destroyed. 587 */ 588 589 if (!(man->flags & TTM_MEMTYPE_FLAG_FIXED)) 590 ghost_obj->ttm = NULL; 591 else 592 bo->ttm = NULL; 593 594 ttm_bo_unreserve(ghost_obj); 595 ttm_bo_unref(&ghost_obj); 596 } 597 598 *old_mem = *new_mem; 599 new_mem->mm_node = NULL; 600 ttm_flag_masked(&save_flags, new_mem->placement, TTM_PL_MASK_MEMTYPE); 601 return 0; 602 } 603 EXPORT_SYMBOL(ttm_bo_move_accel_cleanup); 604