Subversion Repositories Kolibri OS

Rev

Rev 5271 | Rev 6938 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  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. #define iowrite32(v, addr)      writel((v), (addr))
  31. #define ioread32(addr)          readl(addr)
  32.  
  33. #include <drm/ttm/ttm_bo_driver.h>
  34. #include <drm/ttm/ttm_placement.h>
  35. #include <drm/drm_vma_manager.h>
  36. #include <linux/io.h>
  37. //#include <linux/highmem.h>
  38. #include <linux/wait.h>
  39. #include <linux/slab.h>
  40. #include <linux/vmalloc.h>
  41. #include <linux/module.h>
  42.  
  43. #define __pgprot(x)     ((pgprot_t) { (x) } )
  44.  
  45. void *vmap(struct page **pages, unsigned int count,
  46.            unsigned long flags, pgprot_t prot);
  47.  
  48. void ttm_bo_free_old_node(struct ttm_buffer_object *bo)
  49. {
  50.         ttm_bo_mem_put(bo, &bo->mem);
  51. }
  52.  
  53. int ttm_bo_move_ttm(struct ttm_buffer_object *bo,
  54.                     bool evict,
  55.                     bool no_wait_gpu, struct ttm_mem_reg *new_mem)
  56. {
  57.         struct ttm_tt *ttm = bo->ttm;
  58.         struct ttm_mem_reg *old_mem = &bo->mem;
  59.         int ret;
  60.  
  61.         if (old_mem->mem_type != TTM_PL_SYSTEM) {
  62.                 ttm_tt_unbind(ttm);
  63.                 ttm_bo_free_old_node(bo);
  64.                 ttm_flag_masked(&old_mem->placement, TTM_PL_FLAG_SYSTEM,
  65.                                 TTM_PL_MASK_MEM);
  66.                 old_mem->mem_type = TTM_PL_SYSTEM;
  67.         }
  68.  
  69.         ret = ttm_tt_set_placement_caching(ttm, new_mem->placement);
  70.         if (unlikely(ret != 0))
  71.                 return ret;
  72.  
  73.         if (new_mem->mem_type != TTM_PL_SYSTEM) {
  74.                 ret = ttm_tt_bind(ttm, new_mem);
  75.                 if (unlikely(ret != 0))
  76.                         return ret;
  77.         }
  78.  
  79.         *old_mem = *new_mem;
  80.         new_mem->mm_node = NULL;
  81.  
  82.         return 0;
  83. }
  84. EXPORT_SYMBOL(ttm_bo_move_ttm);
  85.  
  86. int ttm_mem_io_lock(struct ttm_mem_type_manager *man, bool interruptible)
  87. {
  88.         if (likely(man->io_reserve_fastpath))
  89.                 return 0;
  90.  
  91.         if (interruptible)
  92.                 return mutex_lock_interruptible(&man->io_reserve_mutex);
  93.  
  94.         mutex_lock(&man->io_reserve_mutex);
  95.         return 0;
  96. }
  97. EXPORT_SYMBOL(ttm_mem_io_lock);
  98.  
  99. void ttm_mem_io_unlock(struct ttm_mem_type_manager *man)
  100. {
  101.         if (likely(man->io_reserve_fastpath))
  102.                 return;
  103.  
  104.         mutex_unlock(&man->io_reserve_mutex);
  105. }
  106. EXPORT_SYMBOL(ttm_mem_io_unlock);
  107.  
  108. static int ttm_mem_io_evict(struct ttm_mem_type_manager *man)
  109. {
  110.         struct ttm_buffer_object *bo;
  111.  
  112.         if (!man->use_io_reserve_lru || list_empty(&man->io_reserve_lru))
  113.                 return -EAGAIN;
  114.  
  115.         bo = list_first_entry(&man->io_reserve_lru,
  116.                               struct ttm_buffer_object,
  117.                               io_reserve_lru);
  118.         list_del_init(&bo->io_reserve_lru);
  119.         ttm_bo_unmap_virtual_locked(bo);
  120.  
  121.         return 0;
  122. }
  123.  
  124.  
  125. int ttm_mem_io_reserve(struct ttm_bo_device *bdev,
  126.                        struct ttm_mem_reg *mem)
  127. {
  128.         struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
  129.         int ret = 0;
  130.  
  131.         if (!bdev->driver->io_mem_reserve)
  132.                 return 0;
  133.         if (likely(man->io_reserve_fastpath))
  134.                 return bdev->driver->io_mem_reserve(bdev, mem);
  135.  
  136.         if (bdev->driver->io_mem_reserve &&
  137.             mem->bus.io_reserved_count++ == 0) {
  138. retry:
  139.                 ret = bdev->driver->io_mem_reserve(bdev, mem);
  140.                 if (ret == -EAGAIN) {
  141.                         ret = ttm_mem_io_evict(man);
  142.                         if (ret == 0)
  143.                                 goto retry;
  144.                 }
  145.         }
  146.         return ret;
  147. }
  148. EXPORT_SYMBOL(ttm_mem_io_reserve);
  149.  
  150. void ttm_mem_io_free(struct ttm_bo_device *bdev,
  151.                      struct ttm_mem_reg *mem)
  152. {
  153.         struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
  154.  
  155.         if (likely(man->io_reserve_fastpath))
  156.                 return;
  157.  
  158.         if (bdev->driver->io_mem_reserve &&
  159.             --mem->bus.io_reserved_count == 0 &&
  160.             bdev->driver->io_mem_free)
  161.                 bdev->driver->io_mem_free(bdev, mem);
  162.  
  163. }
  164. EXPORT_SYMBOL(ttm_mem_io_free);
  165.  
  166. int ttm_mem_io_reserve_vm(struct ttm_buffer_object *bo)
  167. {
  168.         struct ttm_mem_reg *mem = &bo->mem;
  169.         int ret;
  170.  
  171.         if (!mem->bus.io_reserved_vm) {
  172.                 struct ttm_mem_type_manager *man =
  173.                         &bo->bdev->man[mem->mem_type];
  174.  
  175.                 ret = ttm_mem_io_reserve(bo->bdev, mem);
  176.                 if (unlikely(ret != 0))
  177.                         return ret;
  178.                 mem->bus.io_reserved_vm = true;
  179.                 if (man->use_io_reserve_lru)
  180.                         list_add_tail(&bo->io_reserve_lru,
  181.                                       &man->io_reserve_lru);
  182.         }
  183.         return 0;
  184. }
  185.  
  186. void ttm_mem_io_free_vm(struct ttm_buffer_object *bo)
  187. {
  188.         struct ttm_mem_reg *mem = &bo->mem;
  189.  
  190.         if (mem->bus.io_reserved_vm) {
  191.                 mem->bus.io_reserved_vm = false;
  192.                 list_del_init(&bo->io_reserve_lru);
  193.                 ttm_mem_io_free(bo->bdev, mem);
  194.         }
  195. }
  196.  
  197. static int ttm_mem_reg_ioremap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem,
  198.                         void **virtual)
  199. {
  200.         struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
  201.         int ret;
  202.         void *addr;
  203.  
  204.         *virtual = NULL;
  205.         (void) ttm_mem_io_lock(man, false);
  206.         ret = ttm_mem_io_reserve(bdev, mem);
  207.         ttm_mem_io_unlock(man);
  208.         if (ret || !mem->bus.is_iomem)
  209.                 return ret;
  210.  
  211.         if (mem->bus.addr) {
  212.                 addr = mem->bus.addr;
  213.         } else {
  214.                 if (mem->placement & TTM_PL_FLAG_WC)
  215.                         addr = ioremap_wc(mem->bus.base + mem->bus.offset, mem->bus.size);
  216.                 else
  217.                         addr = ioremap_nocache(mem->bus.base + mem->bus.offset, mem->bus.size);
  218.                 if (!addr) {
  219.                         (void) ttm_mem_io_lock(man, false);
  220.                         ttm_mem_io_free(bdev, mem);
  221.                         ttm_mem_io_unlock(man);
  222.                         return -ENOMEM;
  223.                 }
  224.         }
  225.         *virtual = addr;
  226.         return 0;
  227. }
  228.  
  229. static void ttm_mem_reg_iounmap(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem,
  230.                          void *virtual)
  231. {
  232.         struct ttm_mem_type_manager *man;
  233.  
  234.         man = &bdev->man[mem->mem_type];
  235.  
  236.         if (virtual && mem->bus.addr == NULL)
  237.                 iounmap(virtual);
  238.         (void) ttm_mem_io_lock(man, false);
  239.         ttm_mem_io_free(bdev, mem);
  240.         ttm_mem_io_unlock(man);
  241. }
  242.  
  243. static int ttm_copy_io_page(void *dst, void *src, unsigned long page)
  244. {
  245.         uint32_t *dstP =
  246.             (uint32_t *) ((unsigned long)dst + (page << PAGE_SHIFT));
  247.         uint32_t *srcP =
  248.             (uint32_t *) ((unsigned long)src + (page << PAGE_SHIFT));
  249.  
  250.         int i;
  251.         for (i = 0; i < PAGE_SIZE / sizeof(uint32_t); ++i)
  252.                 iowrite32(ioread32(srcP++), dstP++);
  253.         return 0;
  254. }
  255.  
  256. static int ttm_copy_io_ttm_page(struct ttm_tt *ttm, void *src,
  257.                                 unsigned long page,
  258.                                 pgprot_t prot)
  259. {
  260.         struct page *d = ttm->pages[page];
  261.         void *dst;
  262.  
  263.         if (!d)
  264.                 return -ENOMEM;
  265.  
  266.         src = (void *)((unsigned long)src + (page << PAGE_SHIFT));
  267.  
  268.     dst = (void*)MapIoMem((addr_t)d, 4096, PG_SW);
  269.  
  270.         if (!dst)
  271.                 return -ENOMEM;
  272.  
  273.     memcpy(dst, src, PAGE_SIZE);
  274.  
  275.     FreeKernelSpace(dst);
  276.  
  277.         return 0;
  278. }
  279.  
  280. static int ttm_copy_ttm_io_page(struct ttm_tt *ttm, void *dst,
  281.                                 unsigned long page,
  282.                                 pgprot_t prot)
  283. {
  284.         struct page *s = ttm->pages[page];
  285.         void *src;
  286.  
  287.         if (!s)
  288.                 return -ENOMEM;
  289.  
  290.         dst = (void *)((unsigned long)dst + (page << PAGE_SHIFT));
  291.  
  292.     src = (void*)MapIoMem((addr_t)s, 4096, PG_SW);
  293.  
  294.         if (!src)
  295.                 return -ENOMEM;
  296.  
  297.     memcpy(dst, src, PAGE_SIZE);
  298.  
  299.     FreeKernelSpace(src);
  300.  
  301.         return 0;
  302. }
  303.  
  304. int ttm_bo_move_memcpy(struct ttm_buffer_object *bo,
  305.                        bool evict, bool no_wait_gpu,
  306.                        struct ttm_mem_reg *new_mem)
  307. {
  308.         struct ttm_bo_device *bdev = bo->bdev;
  309.         struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type];
  310.         struct ttm_tt *ttm = bo->ttm;
  311.         struct ttm_mem_reg *old_mem = &bo->mem;
  312.         struct ttm_mem_reg old_copy = *old_mem;
  313.         void *old_iomap;
  314.         void *new_iomap;
  315.         int ret;
  316.         unsigned long i;
  317.         unsigned long page;
  318.         unsigned long add = 0;
  319.         int dir;
  320.  
  321.         ret = ttm_mem_reg_ioremap(bdev, old_mem, &old_iomap);
  322.         if (ret)
  323.                 return ret;
  324.         ret = ttm_mem_reg_ioremap(bdev, new_mem, &new_iomap);
  325.         if (ret)
  326.                 goto out;
  327.  
  328.         /*
  329.          * Single TTM move. NOP.
  330.          */
  331.         if (old_iomap == NULL && new_iomap == NULL)
  332.                 goto out2;
  333.  
  334.         /*
  335.          * Don't move nonexistent data. Clear destination instead.
  336.          */
  337.         if (old_iomap == NULL &&
  338.             (ttm == NULL || (ttm->state == tt_unpopulated &&
  339.                              !(ttm->page_flags & TTM_PAGE_FLAG_SWAPPED)))) {
  340.         memset(new_iomap, 0, new_mem->num_pages*PAGE_SIZE);
  341.                 goto out2;
  342.         }
  343.  
  344.         /*
  345.          * TTM might be null for moves within the same region.
  346.          */
  347.         if (ttm && ttm->state == tt_unpopulated) {
  348.                 ret = ttm->bdev->driver->ttm_tt_populate(ttm);
  349.                 if (ret)
  350.                         goto out1;
  351.         }
  352.  
  353.         add = 0;
  354.         dir = 1;
  355.  
  356.         if ((old_mem->mem_type == new_mem->mem_type) &&
  357.             (new_mem->start < old_mem->start + old_mem->size)) {
  358.                 dir = -1;
  359.                 add = new_mem->num_pages - 1;
  360.         }
  361.  
  362.         for (i = 0; i < new_mem->num_pages; ++i) {
  363.                 page = i * dir + add;
  364.                 if (old_iomap == NULL) {
  365.                         pgprot_t prot = ttm_io_prot(old_mem->placement,
  366.                                                     PAGE_KERNEL);
  367.                         ret = ttm_copy_ttm_io_page(ttm, new_iomap, page,
  368.                                                    prot);
  369.                 } else if (new_iomap == NULL) {
  370.                         pgprot_t prot = ttm_io_prot(new_mem->placement,
  371.                                                     PAGE_KERNEL);
  372.                         ret = ttm_copy_io_ttm_page(ttm, old_iomap, page,
  373.                                                    prot);
  374.                 } else
  375.                         ret = ttm_copy_io_page(new_iomap, old_iomap, page);
  376.                 if (ret)
  377.                         goto out1;
  378.         }
  379.         mb();
  380. out2:
  381.         old_copy = *old_mem;
  382.         *old_mem = *new_mem;
  383.         new_mem->mm_node = NULL;
  384.  
  385.         if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) && (ttm != NULL)) {
  386.                 ttm_tt_unbind(ttm);
  387.                 ttm_tt_destroy(ttm);
  388.                 bo->ttm = NULL;
  389.         }
  390.  
  391. out1:
  392.         ttm_mem_reg_iounmap(bdev, old_mem, new_iomap);
  393. out:
  394.         ttm_mem_reg_iounmap(bdev, &old_copy, old_iomap);
  395.  
  396.         /*
  397.          * On error, keep the mm node!
  398.          */
  399.         if (!ret)
  400.                 ttm_bo_mem_put(bo, &old_copy);
  401.         return ret;
  402. }
  403. EXPORT_SYMBOL(ttm_bo_move_memcpy);
  404.  
  405. static void ttm_transfered_destroy(struct ttm_buffer_object *bo)
  406. {
  407.         kfree(bo);
  408. }
  409.  
  410. /**
  411.  * ttm_buffer_object_transfer
  412.  *
  413.  * @bo: A pointer to a struct ttm_buffer_object.
  414.  * @new_obj: A pointer to a pointer to a newly created ttm_buffer_object,
  415.  * holding the data of @bo with the old placement.
  416.  *
  417.  * This is a utility function that may be called after an accelerated move
  418.  * has been scheduled. A new buffer object is created as a placeholder for
  419.  * the old data while it's being copied. When that buffer object is idle,
  420.  * it can be destroyed, releasing the space of the old placement.
  421.  * Returns:
  422.  * !0: Failure.
  423.  */
  424.  
  425. static int ttm_buffer_object_transfer(struct ttm_buffer_object *bo,
  426.                                       struct ttm_buffer_object **new_obj)
  427. {
  428.         struct ttm_buffer_object *fbo;
  429.         int ret;
  430.  
  431.         fbo = kmalloc(sizeof(*fbo), GFP_KERNEL);
  432.         if (!fbo)
  433.                 return -ENOMEM;
  434.  
  435.         *fbo = *bo;
  436.  
  437.         /**
  438.          * Fix up members that we shouldn't copy directly:
  439.          * TODO: Explicit member copy would probably be better here.
  440.          */
  441.  
  442.         INIT_LIST_HEAD(&fbo->ddestroy);
  443.         INIT_LIST_HEAD(&fbo->lru);
  444.         INIT_LIST_HEAD(&fbo->swap);
  445.         INIT_LIST_HEAD(&fbo->io_reserve_lru);
  446.         drm_vma_node_reset(&fbo->vma_node);
  447.         atomic_set(&fbo->cpu_writers, 0);
  448.  
  449.         kref_init(&fbo->list_kref);
  450.         kref_init(&fbo->kref);
  451.         fbo->destroy = &ttm_transfered_destroy;
  452.         fbo->acc_size = 0;
  453.         fbo->resv = &fbo->ttm_resv;
  454.         reservation_object_init(fbo->resv);
  455.         ret = ww_mutex_trylock(&fbo->resv->lock);
  456.         WARN_ON(!ret);
  457.  
  458.         *new_obj = fbo;
  459.         return 0;
  460. }
  461.  
  462. pgprot_t ttm_io_prot(uint32_t caching_flags, pgprot_t tmp)
  463. {
  464.         return tmp;
  465. }
  466. EXPORT_SYMBOL(ttm_io_prot);
  467.  
  468. static int ttm_bo_ioremap(struct ttm_buffer_object *bo,
  469.                           unsigned long offset,
  470.                           unsigned long size,
  471.                           struct ttm_bo_kmap_obj *map)
  472. {
  473.         struct ttm_mem_reg *mem = &bo->mem;
  474.  
  475.         if (bo->mem.bus.addr) {
  476.                 map->bo_kmap_type = ttm_bo_map_premapped;
  477.                 map->virtual = (void *)(((u8 *)bo->mem.bus.addr) + offset);
  478.         } else {
  479.                 map->bo_kmap_type = ttm_bo_map_iomap;
  480.                 if (mem->placement & TTM_PL_FLAG_WC)
  481.                         map->virtual = ioremap_wc(bo->mem.bus.base + bo->mem.bus.offset + offset,
  482.                                                   size);
  483.                 else
  484.                         map->virtual = ioremap_nocache(bo->mem.bus.base + bo->mem.bus.offset + offset,
  485.                                                        size);
  486.         }
  487.         return (!map->virtual) ? -ENOMEM : 0;
  488. }
  489.  
  490. static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo,
  491.                            unsigned long start_page,
  492.                            unsigned long num_pages,
  493.                            struct ttm_bo_kmap_obj *map)
  494. {
  495.         struct ttm_mem_reg *mem = &bo->mem; pgprot_t prot;
  496.         struct ttm_tt *ttm = bo->ttm;
  497.         int ret;
  498.  
  499.         BUG_ON(!ttm);
  500.  
  501.         if (ttm->state == tt_unpopulated) {
  502.                 ret = ttm->bdev->driver->ttm_tt_populate(ttm);
  503.                 if (ret)
  504.                         return ret;
  505.         }
  506.  
  507.         if (num_pages == 1 && (mem->placement & TTM_PL_FLAG_CACHED)) {
  508.                 /*
  509.                  * We're mapping a single page, and the desired
  510.                  * page protection is consistent with the bo.
  511.                  */
  512.  
  513.                 map->bo_kmap_type = ttm_bo_map_kmap;
  514.                 map->page = ttm->pages[start_page];
  515.                 map->virtual = kmap(map->page);
  516.         } else {
  517.                 /*
  518.                  * We need to use vmap to get the desired page protection
  519.                  * or to make the buffer object look contiguous.
  520.                  */
  521.                 prot = ttm_io_prot(mem->placement, PAGE_KERNEL);
  522.                 map->bo_kmap_type = ttm_bo_map_vmap;
  523.                 map->virtual = vmap(ttm->pages + start_page, num_pages,
  524.                                     0, prot);
  525.         }
  526.         return (!map->virtual) ? -ENOMEM : 0;
  527. }
  528.  
  529. int ttm_bo_kmap(struct ttm_buffer_object *bo,
  530.                 unsigned long start_page, unsigned long num_pages,
  531.                 struct ttm_bo_kmap_obj *map)
  532. {
  533.         struct ttm_mem_type_manager *man =
  534.                 &bo->bdev->man[bo->mem.mem_type];
  535.         unsigned long offset, size;
  536.         int ret;
  537.  
  538.         BUG_ON(!list_empty(&bo->swap));
  539.         map->virtual = NULL;
  540.         map->bo = bo;
  541.         if (num_pages > bo->num_pages)
  542.                 return -EINVAL;
  543.         if (start_page > bo->num_pages)
  544.                 return -EINVAL;
  545. #if 0
  546.         if (num_pages > 1 && !capable(CAP_SYS_ADMIN))
  547.                 return -EPERM;
  548. #endif
  549.         (void) ttm_mem_io_lock(man, false);
  550.         ret = ttm_mem_io_reserve(bo->bdev, &bo->mem);
  551.         ttm_mem_io_unlock(man);
  552.         if (ret)
  553.                 return ret;
  554.         if (!bo->mem.bus.is_iomem) {
  555.                 return ttm_bo_kmap_ttm(bo, start_page, num_pages, map);
  556.         } else {
  557.                 offset = start_page << PAGE_SHIFT;
  558.                 size = num_pages << PAGE_SHIFT;
  559.                 return ttm_bo_ioremap(bo, offset, size, map);
  560.         }
  561. }
  562. EXPORT_SYMBOL(ttm_bo_kmap);
  563.  
  564. void ttm_bo_kunmap(struct ttm_bo_kmap_obj *map)
  565. {
  566.         struct ttm_buffer_object *bo = map->bo;
  567.         struct ttm_mem_type_manager *man =
  568.                 &bo->bdev->man[bo->mem.mem_type];
  569.  
  570.         if (!map->virtual)
  571.                 return;
  572.         switch (map->bo_kmap_type) {
  573.         case ttm_bo_map_iomap:
  574.                 iounmap(map->virtual);
  575.                 break;
  576.         case ttm_bo_map_vmap:
  577.                 break;
  578.         case ttm_bo_map_kmap:
  579.                 kunmap(map->page);
  580.                 break;
  581.         case ttm_bo_map_premapped:
  582.                 break;
  583.         default:
  584.                 BUG();
  585.         }
  586.         (void) ttm_mem_io_lock(man, false);
  587.         ttm_mem_io_free(map->bo->bdev, &map->bo->mem);
  588.         ttm_mem_io_unlock(man);
  589.         map->virtual = NULL;
  590.         map->page = NULL;
  591. }
  592. EXPORT_SYMBOL(ttm_bo_kunmap);
  593.  
  594. int ttm_bo_move_accel_cleanup(struct ttm_buffer_object *bo,
  595.                               struct fence *fence,
  596.                               bool evict,
  597.                               bool no_wait_gpu,
  598.                               struct ttm_mem_reg *new_mem)
  599. {
  600.         struct ttm_bo_device *bdev = bo->bdev;
  601.         struct ttm_mem_type_manager *man = &bdev->man[new_mem->mem_type];
  602.         struct ttm_mem_reg *old_mem = &bo->mem;
  603.         int ret;
  604.         struct ttm_buffer_object *ghost_obj;
  605.  
  606.         reservation_object_add_excl_fence(bo->resv, fence);
  607.         if (evict) {
  608.                 ret = ttm_bo_wait(bo, false, false, false);
  609.                 if (ret)
  610.                         return ret;
  611.  
  612.                 if ((man->flags & TTM_MEMTYPE_FLAG_FIXED) &&
  613.                     (bo->ttm != NULL)) {
  614.                         ttm_tt_unbind(bo->ttm);
  615.                         ttm_tt_destroy(bo->ttm);
  616.                         bo->ttm = NULL;
  617.                 }
  618.                 ttm_bo_free_old_node(bo);
  619.         } else {
  620.                 /**
  621.                  * This should help pipeline ordinary buffer moves.
  622.                  *
  623.                  * Hang old buffer memory on a new buffer object,
  624.                  * and leave it to be released when the GPU
  625.                  * operation has completed.
  626.                  */
  627.  
  628.                 set_bit(TTM_BO_PRIV_FLAG_MOVING, &bo->priv_flags);
  629.  
  630.                 ret = ttm_buffer_object_transfer(bo, &ghost_obj);
  631.                 if (ret)
  632.                         return ret;
  633.  
  634.                 reservation_object_add_excl_fence(ghost_obj->resv, fence);
  635.  
  636.                 /**
  637.                  * If we're not moving to fixed memory, the TTM object
  638.                  * needs to stay alive. Otherwhise hang it on the ghost
  639.                  * bo to be unbound and destroyed.
  640.                  */
  641.  
  642.                 if (!(man->flags & TTM_MEMTYPE_FLAG_FIXED))
  643.                         ghost_obj->ttm = NULL;
  644.                 else
  645.                         bo->ttm = NULL;
  646.  
  647.                 ttm_bo_unreserve(ghost_obj);
  648.                 ttm_bo_unref(&ghost_obj);
  649.         }
  650.  
  651.         *old_mem = *new_mem;
  652.         new_mem->mm_node = NULL;
  653.  
  654.         return 0;
  655. }
  656. EXPORT_SYMBOL(ttm_bo_move_accel_cleanup);
  657.  
  658.  
  659. void *vmap(struct page **pages, unsigned int count,
  660.            unsigned long flags, pgprot_t prot)
  661. {
  662.     void *vaddr;
  663.     char *tmp;
  664.     int i;
  665.  
  666.     vaddr = AllocKernelSpace(count << 12);
  667.     if(vaddr == NULL)
  668.         return NULL;
  669.  
  670.     for(i = 0, tmp = vaddr; i < count; i++)
  671.     {
  672.         MapPage(tmp, page_to_phys(pages[i]), PG_SW);
  673.         tmp+= 4096;
  674.     };
  675.  
  676.     return vaddr;
  677. };
  678.  
  679.