linux/drivers/gpu/drm/nouveau/nouveau_bo.c
<<
>>
Prefs
   1/*
   2 * Copyright 2007 Dave Airlied
   3 * All Rights Reserved.
   4 *
   5 * Permission is hereby granted, free of charge, to any person obtaining a
   6 * copy of this software and associated documentation files (the "Software"),
   7 * to deal in the Software without restriction, including without limitation
   8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   9 * and/or sell copies of the Software, and to permit persons to whom the
  10 * Software is furnished to do so, subject to the following conditions:
  11 *
  12 * The above copyright notice and this permission notice (including the next
  13 * paragraph) shall be included in all copies or substantial portions of the
  14 * Software.
  15 *
  16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  19 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  22 * OTHER DEALINGS IN THE SOFTWARE.
  23 */
  24/*
  25 * Authors: Dave Airlied <airlied@linux.ie>
  26 *          Ben Skeggs   <darktama@iinet.net.au>
  27 *          Jeremy Kolb  <jkolb@brandeis.edu>
  28 */
  29
  30#include <core/engine.h>
  31#include <linux/swiotlb.h>
  32
  33#include <subdev/fb.h>
  34#include <subdev/vm.h>
  35#include <subdev/bar.h>
  36
  37#include "nouveau_drm.h"
  38#include "nouveau_dma.h"
  39#include "nouveau_fence.h"
  40
  41#include "nouveau_bo.h"
  42#include "nouveau_ttm.h"
  43#include "nouveau_gem.h"
  44
  45/*
  46 * NV10-NV40 tiling helpers
  47 */
  48
  49static void
  50nv10_bo_update_tile_region(struct drm_device *dev, struct nouveau_drm_tile *reg,
  51                           u32 addr, u32 size, u32 pitch, u32 flags)
  52{
  53        struct nouveau_drm *drm = nouveau_drm(dev);
  54        int i = reg - drm->tile.reg;
  55        struct nouveau_fb *pfb = nouveau_fb(drm->device);
  56        struct nouveau_fb_tile *tile = &pfb->tile.region[i];
  57        struct nouveau_engine *engine;
  58
  59        nouveau_fence_unref(&reg->fence);
  60
  61        if (tile->pitch)
  62                pfb->tile.fini(pfb, i, tile);
  63
  64        if (pitch)
  65                pfb->tile.init(pfb, i, addr, size, pitch, flags, tile);
  66
  67        pfb->tile.prog(pfb, i, tile);
  68
  69        if ((engine = nouveau_engine(pfb, NVDEV_ENGINE_GR)))
  70                engine->tile_prog(engine, i);
  71        if ((engine = nouveau_engine(pfb, NVDEV_ENGINE_MPEG)))
  72                engine->tile_prog(engine, i);
  73}
  74
  75static struct nouveau_drm_tile *
  76nv10_bo_get_tile_region(struct drm_device *dev, int i)
  77{
  78        struct nouveau_drm *drm = nouveau_drm(dev);
  79        struct nouveau_drm_tile *tile = &drm->tile.reg[i];
  80
  81        spin_lock(&drm->tile.lock);
  82
  83        if (!tile->used &&
  84            (!tile->fence || nouveau_fence_done(tile->fence)))
  85                tile->used = true;
  86        else
  87                tile = NULL;
  88
  89        spin_unlock(&drm->tile.lock);
  90        return tile;
  91}
  92
  93static void
  94nv10_bo_put_tile_region(struct drm_device *dev, struct nouveau_drm_tile *tile,
  95                        struct nouveau_fence *fence)
  96{
  97        struct nouveau_drm *drm = nouveau_drm(dev);
  98
  99        if (tile) {
 100                spin_lock(&drm->tile.lock);
 101                if (fence) {
 102                        /* Mark it as pending. */
 103                        tile->fence = fence;
 104                        nouveau_fence_ref(fence);
 105                }
 106
 107                tile->used = false;
 108                spin_unlock(&drm->tile.lock);
 109        }
 110}
 111
 112static struct nouveau_drm_tile *
 113nv10_bo_set_tiling(struct drm_device *dev, u32 addr,
 114                   u32 size, u32 pitch, u32 flags)
 115{
 116        struct nouveau_drm *drm = nouveau_drm(dev);
 117        struct nouveau_fb *pfb = nouveau_fb(drm->device);
 118        struct nouveau_drm_tile *tile, *found = NULL;
 119        int i;
 120
 121        for (i = 0; i < pfb->tile.regions; i++) {
 122                tile = nv10_bo_get_tile_region(dev, i);
 123
 124                if (pitch && !found) {
 125                        found = tile;
 126                        continue;
 127
 128                } else if (tile && pfb->tile.region[i].pitch) {
 129                        /* Kill an unused tile region. */
 130                        nv10_bo_update_tile_region(dev, tile, 0, 0, 0, 0);
 131                }
 132
 133                nv10_bo_put_tile_region(dev, tile, NULL);
 134        }
 135
 136        if (found)
 137                nv10_bo_update_tile_region(dev, found, addr, size,
 138                                            pitch, flags);
 139        return found;
 140}
 141
 142static void
 143nouveau_bo_del_ttm(struct ttm_buffer_object *bo)
 144{
 145        struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
 146        struct drm_device *dev = drm->dev;
 147        struct nouveau_bo *nvbo = nouveau_bo(bo);
 148
 149        if (unlikely(nvbo->gem))
 150                DRM_ERROR("bo %p still attached to GEM object\n", bo);
 151        nv10_bo_put_tile_region(dev, nvbo->tile, NULL);
 152        kfree(nvbo);
 153}
 154
 155static void
 156nouveau_bo_fixup_align(struct nouveau_bo *nvbo, u32 flags,
 157                       int *align, int *size)
 158{
 159        struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
 160        struct nouveau_device *device = nv_device(drm->device);
 161
 162        if (device->card_type < NV_50) {
 163                if (nvbo->tile_mode) {
 164                        if (device->chipset >= 0x40) {
 165                                *align = 65536;
 166                                *size = roundup(*size, 64 * nvbo->tile_mode);
 167
 168                        } else if (device->chipset >= 0x30) {
 169                                *align = 32768;
 170                                *size = roundup(*size, 64 * nvbo->tile_mode);
 171
 172                        } else if (device->chipset >= 0x20) {
 173                                *align = 16384;
 174                                *size = roundup(*size, 64 * nvbo->tile_mode);
 175
 176                        } else if (device->chipset >= 0x10) {
 177                                *align = 16384;
 178                                *size = roundup(*size, 32 * nvbo->tile_mode);
 179                        }
 180                }
 181        } else {
 182                *size = roundup(*size, (1 << nvbo->page_shift));
 183                *align = max((1 <<  nvbo->page_shift), *align);
 184        }
 185
 186        *size = roundup(*size, PAGE_SIZE);
 187}
 188
 189int
 190nouveau_bo_new(struct drm_device *dev, int size, int align,
 191               uint32_t flags, uint32_t tile_mode, uint32_t tile_flags,
 192               struct sg_table *sg,
 193               struct nouveau_bo **pnvbo)
 194{
 195        struct nouveau_drm *drm = nouveau_drm(dev);
 196        struct nouveau_bo *nvbo;
 197        size_t acc_size;
 198        int ret;
 199        int type = ttm_bo_type_device;
 200
 201        if (sg)
 202                type = ttm_bo_type_sg;
 203
 204        nvbo = kzalloc(sizeof(struct nouveau_bo), GFP_KERNEL);
 205        if (!nvbo)
 206                return -ENOMEM;
 207        INIT_LIST_HEAD(&nvbo->head);
 208        INIT_LIST_HEAD(&nvbo->entry);
 209        INIT_LIST_HEAD(&nvbo->vma_list);
 210        nvbo->tile_mode = tile_mode;
 211        nvbo->tile_flags = tile_flags;
 212        nvbo->bo.bdev = &drm->ttm.bdev;
 213
 214        nvbo->page_shift = 12;
 215        if (drm->client.base.vm) {
 216                if (!(flags & TTM_PL_FLAG_TT) && size > 256 * 1024)
 217                        nvbo->page_shift = drm->client.base.vm->vmm->lpg_shift;
 218        }
 219
 220        nouveau_bo_fixup_align(nvbo, flags, &align, &size);
 221        nvbo->bo.mem.num_pages = size >> PAGE_SHIFT;
 222        nouveau_bo_placement_set(nvbo, flags, 0);
 223
 224        acc_size = ttm_bo_dma_acc_size(&drm->ttm.bdev, size,
 225                                       sizeof(struct nouveau_bo));
 226
 227        ret = ttm_bo_init(&drm->ttm.bdev, &nvbo->bo, size,
 228                          type, &nvbo->placement,
 229                          align >> PAGE_SHIFT, false, NULL, acc_size, sg,
 230                          nouveau_bo_del_ttm);
 231        if (ret) {
 232                /* ttm will call nouveau_bo_del_ttm if it fails.. */
 233                return ret;
 234        }
 235
 236        *pnvbo = nvbo;
 237        return 0;
 238}
 239
 240static void
 241set_placement_list(uint32_t *pl, unsigned *n, uint32_t type, uint32_t flags)
 242{
 243        *n = 0;
 244
 245        if (type & TTM_PL_FLAG_VRAM)
 246                pl[(*n)++] = TTM_PL_FLAG_VRAM | flags;
 247        if (type & TTM_PL_FLAG_TT)
 248                pl[(*n)++] = TTM_PL_FLAG_TT | flags;
 249        if (type & TTM_PL_FLAG_SYSTEM)
 250                pl[(*n)++] = TTM_PL_FLAG_SYSTEM | flags;
 251}
 252
 253static void
 254set_placement_range(struct nouveau_bo *nvbo, uint32_t type)
 255{
 256        struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
 257        struct nouveau_fb *pfb = nouveau_fb(drm->device);
 258        u32 vram_pages = pfb->ram.size >> PAGE_SHIFT;
 259
 260        if (nv_device(drm->device)->card_type == NV_10 &&
 261            nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) &&
 262            nvbo->bo.mem.num_pages < vram_pages / 4) {
 263                /*
 264                 * Make sure that the color and depth buffers are handled
 265                 * by independent memory controller units. Up to a 9x
 266                 * speed up when alpha-blending and depth-test are enabled
 267                 * at the same time.
 268                 */
 269                if (nvbo->tile_flags & NOUVEAU_GEM_TILE_ZETA) {
 270                        nvbo->placement.fpfn = vram_pages / 2;
 271                        nvbo->placement.lpfn = ~0;
 272                } else {
 273                        nvbo->placement.fpfn = 0;
 274                        nvbo->placement.lpfn = vram_pages / 2;
 275                }
 276        }
 277}
 278
 279void
 280nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy)
 281{
 282        struct ttm_placement *pl = &nvbo->placement;
 283        uint32_t flags = TTM_PL_MASK_CACHING |
 284                (nvbo->pin_refcnt ? TTM_PL_FLAG_NO_EVICT : 0);
 285
 286        pl->placement = nvbo->placements;
 287        set_placement_list(nvbo->placements, &pl->num_placement,
 288                           type, flags);
 289
 290        pl->busy_placement = nvbo->busy_placements;
 291        set_placement_list(nvbo->busy_placements, &pl->num_busy_placement,
 292                           type | busy, flags);
 293
 294        set_placement_range(nvbo, type);
 295}
 296
 297int
 298nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t memtype)
 299{
 300        struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
 301        struct ttm_buffer_object *bo = &nvbo->bo;
 302        int ret;
 303
 304        ret = ttm_bo_reserve(bo, false, false, false, 0);
 305        if (ret)
 306                goto out;
 307
 308        if (nvbo->pin_refcnt && !(memtype & (1 << bo->mem.mem_type))) {
 309                NV_ERROR(drm, "bo %p pinned elsewhere: 0x%08x vs 0x%08x\n", bo,
 310                         1 << bo->mem.mem_type, memtype);
 311                ret = -EINVAL;
 312                goto out;
 313        }
 314
 315        if (nvbo->pin_refcnt++)
 316                goto out;
 317
 318        nouveau_bo_placement_set(nvbo, memtype, 0);
 319
 320        ret = nouveau_bo_validate(nvbo, false, false);
 321        if (ret == 0) {
 322                switch (bo->mem.mem_type) {
 323                case TTM_PL_VRAM:
 324                        drm->gem.vram_available -= bo->mem.size;
 325                        break;
 326                case TTM_PL_TT:
 327                        drm->gem.gart_available -= bo->mem.size;
 328                        break;
 329                default:
 330                        break;
 331                }
 332        }
 333out:
 334        ttm_bo_unreserve(bo);
 335        return ret;
 336}
 337
 338int
 339nouveau_bo_unpin(struct nouveau_bo *nvbo)
 340{
 341        struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
 342        struct ttm_buffer_object *bo = &nvbo->bo;
 343        int ret;
 344
 345        ret = ttm_bo_reserve(bo, false, false, false, 0);
 346        if (ret)
 347                return ret;
 348
 349        if (--nvbo->pin_refcnt)
 350                goto out;
 351
 352        nouveau_bo_placement_set(nvbo, bo->mem.placement, 0);
 353
 354        ret = nouveau_bo_validate(nvbo, false, false);
 355        if (ret == 0) {
 356                switch (bo->mem.mem_type) {
 357                case TTM_PL_VRAM:
 358                        drm->gem.vram_available += bo->mem.size;
 359                        break;
 360                case TTM_PL_TT:
 361                        drm->gem.gart_available += bo->mem.size;
 362                        break;
 363                default:
 364                        break;
 365                }
 366        }
 367
 368out:
 369        ttm_bo_unreserve(bo);
 370        return ret;
 371}
 372
 373int
 374nouveau_bo_map(struct nouveau_bo *nvbo)
 375{
 376        int ret;
 377
 378        ret = ttm_bo_reserve(&nvbo->bo, false, false, false, 0);
 379        if (ret)
 380                return ret;
 381
 382        ret = ttm_bo_kmap(&nvbo->bo, 0, nvbo->bo.mem.num_pages, &nvbo->kmap);
 383        ttm_bo_unreserve(&nvbo->bo);
 384        return ret;
 385}
 386
 387void
 388nouveau_bo_unmap(struct nouveau_bo *nvbo)
 389{
 390        if (nvbo)
 391                ttm_bo_kunmap(&nvbo->kmap);
 392}
 393
 394int
 395nouveau_bo_validate(struct nouveau_bo *nvbo, bool interruptible,
 396                    bool no_wait_gpu)
 397{
 398        int ret;
 399
 400        ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement,
 401                              interruptible, no_wait_gpu);
 402        if (ret)
 403                return ret;
 404
 405        return 0;
 406}
 407
 408u16
 409nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index)
 410{
 411        bool is_iomem;
 412        u16 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem);
 413        mem = &mem[index];
 414        if (is_iomem)
 415                return ioread16_native((void __force __iomem *)mem);
 416        else
 417                return *mem;
 418}
 419
 420void
 421nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val)
 422{
 423        bool is_iomem;
 424        u16 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem);
 425        mem = &mem[index];
 426        if (is_iomem)
 427                iowrite16_native(val, (void __force __iomem *)mem);
 428        else
 429                *mem = val;
 430}
 431
 432u32
 433nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index)
 434{
 435        bool is_iomem;
 436        u32 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem);
 437        mem = &mem[index];
 438        if (is_iomem)
 439                return ioread32_native((void __force __iomem *)mem);
 440        else
 441                return *mem;
 442}
 443
 444void
 445nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val)
 446{
 447        bool is_iomem;
 448        u32 *mem = ttm_kmap_obj_virtual(&nvbo->kmap, &is_iomem);
 449        mem = &mem[index];
 450        if (is_iomem)
 451                iowrite32_native(val, (void __force __iomem *)mem);
 452        else
 453                *mem = val;
 454}
 455
 456static struct ttm_tt *
 457nouveau_ttm_tt_create(struct ttm_bo_device *bdev, unsigned long size,
 458                      uint32_t page_flags, struct page *dummy_read)
 459{
 460#if __OS_HAS_AGP
 461        struct nouveau_drm *drm = nouveau_bdev(bdev);
 462        struct drm_device *dev = drm->dev;
 463
 464        if (drm->agp.stat == ENABLED) {
 465                return ttm_agp_tt_create(bdev, dev->agp->bridge, size,
 466                                         page_flags, dummy_read);
 467        }
 468#endif
 469
 470        return nouveau_sgdma_create_ttm(bdev, size, page_flags, dummy_read);
 471}
 472
 473static int
 474nouveau_bo_invalidate_caches(struct ttm_bo_device *bdev, uint32_t flags)
 475{
 476        /* We'll do this from user space. */
 477        return 0;
 478}
 479
 480static int
 481nouveau_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
 482                         struct ttm_mem_type_manager *man)
 483{
 484        struct nouveau_drm *drm = nouveau_bdev(bdev);
 485
 486        switch (type) {
 487        case TTM_PL_SYSTEM:
 488                man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
 489                man->available_caching = TTM_PL_MASK_CACHING;
 490                man->default_caching = TTM_PL_FLAG_CACHED;
 491                break;
 492        case TTM_PL_VRAM:
 493                if (nv_device(drm->device)->card_type >= NV_50) {
 494                        man->func = &nouveau_vram_manager;
 495                        man->io_reserve_fastpath = false;
 496                        man->use_io_reserve_lru = true;
 497                } else {
 498                        man->func = &ttm_bo_manager_func;
 499                }
 500                man->flags = TTM_MEMTYPE_FLAG_FIXED |
 501                             TTM_MEMTYPE_FLAG_MAPPABLE;
 502                man->available_caching = TTM_PL_FLAG_UNCACHED |
 503                                         TTM_PL_FLAG_WC;
 504                man->default_caching = TTM_PL_FLAG_WC;
 505                break;
 506        case TTM_PL_TT:
 507                if (nv_device(drm->device)->card_type >= NV_50)
 508                        man->func = &nouveau_gart_manager;
 509                else
 510                if (drm->agp.stat != ENABLED)
 511                        man->func = &nv04_gart_manager;
 512                else
 513                        man->func = &ttm_bo_manager_func;
 514
 515                if (drm->agp.stat == ENABLED) {
 516                        man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
 517                        man->available_caching = TTM_PL_FLAG_UNCACHED |
 518                                TTM_PL_FLAG_WC;
 519                        man->default_caching = TTM_PL_FLAG_WC;
 520                } else {
 521                        man->flags = TTM_MEMTYPE_FLAG_MAPPABLE |
 522                                     TTM_MEMTYPE_FLAG_CMA;
 523                        man->available_caching = TTM_PL_MASK_CACHING;
 524                        man->default_caching = TTM_PL_FLAG_CACHED;
 525                }
 526
 527                break;
 528        default:
 529                return -EINVAL;
 530        }
 531        return 0;
 532}
 533
 534static void
 535nouveau_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
 536{
 537        struct nouveau_bo *nvbo = nouveau_bo(bo);
 538
 539        switch (bo->mem.mem_type) {
 540        case TTM_PL_VRAM:
 541                nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_TT,
 542                                         TTM_PL_FLAG_SYSTEM);
 543                break;
 544        default:
 545                nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_SYSTEM, 0);
 546                break;
 547        }
 548
 549        *pl = nvbo->placement;
 550}
 551
 552
 553/* GPU-assisted copy using NV_MEMORY_TO_MEMORY_FORMAT, can access
 554 * TTM_PL_{VRAM,TT} directly.
 555 */
 556
 557static int
 558nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan,
 559                              struct nouveau_bo *nvbo, bool evict,
 560                              bool no_wait_gpu, struct ttm_mem_reg *new_mem)
 561{
 562        struct nouveau_fence *fence = NULL;
 563        int ret;
 564
 565        ret = nouveau_fence_new(chan, false, &fence);
 566        if (ret)
 567                return ret;
 568
 569        ret = ttm_bo_move_accel_cleanup(&nvbo->bo, fence, evict,
 570                                        no_wait_gpu, new_mem);
 571        nouveau_fence_unref(&fence);
 572        return ret;
 573}
 574
 575static int
 576nve0_bo_move_init(struct nouveau_channel *chan, u32 handle)
 577{
 578        int ret = RING_SPACE(chan, 2);
 579        if (ret == 0) {
 580                BEGIN_NVC0(chan, NvSubCopy, 0x0000, 1);
 581                OUT_RING  (chan, handle);
 582                FIRE_RING (chan);
 583        }
 584        return ret;
 585}
 586
 587static int
 588nve0_bo_move_copy(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
 589                  struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
 590{
 591        struct nouveau_mem *node = old_mem->mm_node;
 592        int ret = RING_SPACE(chan, 10);
 593        if (ret == 0) {
 594                BEGIN_NVC0(chan, NvSubCopy, 0x0400, 8);
 595                OUT_RING  (chan, upper_32_bits(node->vma[0].offset));
 596                OUT_RING  (chan, lower_32_bits(node->vma[0].offset));
 597                OUT_RING  (chan, upper_32_bits(node->vma[1].offset));
 598                OUT_RING  (chan, lower_32_bits(node->vma[1].offset));
 599                OUT_RING  (chan, PAGE_SIZE);
 600                OUT_RING  (chan, PAGE_SIZE);
 601                OUT_RING  (chan, PAGE_SIZE);
 602                OUT_RING  (chan, new_mem->num_pages);
 603                BEGIN_IMC0(chan, NvSubCopy, 0x0300, 0x0386);
 604        }
 605        return ret;
 606}
 607
 608static int
 609nvc0_bo_move_init(struct nouveau_channel *chan, u32 handle)
 610{
 611        int ret = RING_SPACE(chan, 2);
 612        if (ret == 0) {
 613                BEGIN_NVC0(chan, NvSubCopy, 0x0000, 1);
 614                OUT_RING  (chan, handle);
 615        }
 616        return ret;
 617}
 618
 619static int
 620nvc0_bo_move_copy(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
 621                  struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
 622{
 623        struct nouveau_mem *node = old_mem->mm_node;
 624        u64 src_offset = node->vma[0].offset;
 625        u64 dst_offset = node->vma[1].offset;
 626        u32 page_count = new_mem->num_pages;
 627        int ret;
 628
 629        page_count = new_mem->num_pages;
 630        while (page_count) {
 631                int line_count = (page_count > 8191) ? 8191 : page_count;
 632
 633                ret = RING_SPACE(chan, 11);
 634                if (ret)
 635                        return ret;
 636
 637                BEGIN_NVC0(chan, NvSubCopy, 0x030c, 8);
 638                OUT_RING  (chan, upper_32_bits(src_offset));
 639                OUT_RING  (chan, lower_32_bits(src_offset));
 640                OUT_RING  (chan, upper_32_bits(dst_offset));
 641                OUT_RING  (chan, lower_32_bits(dst_offset));
 642                OUT_RING  (chan, PAGE_SIZE);
 643                OUT_RING  (chan, PAGE_SIZE);
 644                OUT_RING  (chan, PAGE_SIZE);
 645                OUT_RING  (chan, line_count);
 646                BEGIN_NVC0(chan, NvSubCopy, 0x0300, 1);
 647                OUT_RING  (chan, 0x00000110);
 648
 649                page_count -= line_count;
 650                src_offset += (PAGE_SIZE * line_count);
 651                dst_offset += (PAGE_SIZE * line_count);
 652        }
 653
 654        return 0;
 655}
 656
 657static int
 658nvc0_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
 659                  struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
 660{
 661        struct nouveau_mem *node = old_mem->mm_node;
 662        u64 src_offset = node->vma[0].offset;
 663        u64 dst_offset = node->vma[1].offset;
 664        u32 page_count = new_mem->num_pages;
 665        int ret;
 666
 667        page_count = new_mem->num_pages;
 668        while (page_count) {
 669                int line_count = (page_count > 2047) ? 2047 : page_count;
 670
 671                ret = RING_SPACE(chan, 12);
 672                if (ret)
 673                        return ret;
 674
 675                BEGIN_NVC0(chan, NvSubCopy, 0x0238, 2);
 676                OUT_RING  (chan, upper_32_bits(dst_offset));
 677                OUT_RING  (chan, lower_32_bits(dst_offset));
 678                BEGIN_NVC0(chan, NvSubCopy, 0x030c, 6);
 679                OUT_RING  (chan, upper_32_bits(src_offset));
 680                OUT_RING  (chan, lower_32_bits(src_offset));
 681                OUT_RING  (chan, PAGE_SIZE); /* src_pitch */
 682                OUT_RING  (chan, PAGE_SIZE); /* dst_pitch */
 683                OUT_RING  (chan, PAGE_SIZE); /* line_length */
 684                OUT_RING  (chan, line_count);
 685                BEGIN_NVC0(chan, NvSubCopy, 0x0300, 1);
 686                OUT_RING  (chan, 0x00100110);
 687
 688                page_count -= line_count;
 689                src_offset += (PAGE_SIZE * line_count);
 690                dst_offset += (PAGE_SIZE * line_count);
 691        }
 692
 693        return 0;
 694}
 695
 696static int
 697nva3_bo_move_copy(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
 698                  struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
 699{
 700        struct nouveau_mem *node = old_mem->mm_node;
 701        u64 src_offset = node->vma[0].offset;
 702        u64 dst_offset = node->vma[1].offset;
 703        u32 page_count = new_mem->num_pages;
 704        int ret;
 705
 706        page_count = new_mem->num_pages;
 707        while (page_count) {
 708                int line_count = (page_count > 8191) ? 8191 : page_count;
 709
 710                ret = RING_SPACE(chan, 11);
 711                if (ret)
 712                        return ret;
 713
 714                BEGIN_NV04(chan, NvSubCopy, 0x030c, 8);
 715                OUT_RING  (chan, upper_32_bits(src_offset));
 716                OUT_RING  (chan, lower_32_bits(src_offset));
 717                OUT_RING  (chan, upper_32_bits(dst_offset));
 718                OUT_RING  (chan, lower_32_bits(dst_offset));
 719                OUT_RING  (chan, PAGE_SIZE);
 720                OUT_RING  (chan, PAGE_SIZE);
 721                OUT_RING  (chan, PAGE_SIZE);
 722                OUT_RING  (chan, line_count);
 723                BEGIN_NV04(chan, NvSubCopy, 0x0300, 1);
 724                OUT_RING  (chan, 0x00000110);
 725
 726                page_count -= line_count;
 727                src_offset += (PAGE_SIZE * line_count);
 728                dst_offset += (PAGE_SIZE * line_count);
 729        }
 730
 731        return 0;
 732}
 733
 734static int
 735nv98_bo_move_exec(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
 736                  struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
 737{
 738        struct nouveau_mem *node = old_mem->mm_node;
 739        int ret = RING_SPACE(chan, 7);
 740        if (ret == 0) {
 741                BEGIN_NV04(chan, NvSubCopy, 0x0320, 6);
 742                OUT_RING  (chan, upper_32_bits(node->vma[0].offset));
 743                OUT_RING  (chan, lower_32_bits(node->vma[0].offset));
 744                OUT_RING  (chan, upper_32_bits(node->vma[1].offset));
 745                OUT_RING  (chan, lower_32_bits(node->vma[1].offset));
 746                OUT_RING  (chan, 0x00000000 /* COPY */);
 747                OUT_RING  (chan, new_mem->num_pages << PAGE_SHIFT);
 748        }
 749        return ret;
 750}
 751
 752static int
 753nv84_bo_move_exec(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
 754                  struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
 755{
 756        struct nouveau_mem *node = old_mem->mm_node;
 757        int ret = RING_SPACE(chan, 7);
 758        if (ret == 0) {
 759                BEGIN_NV04(chan, NvSubCopy, 0x0304, 6);
 760                OUT_RING  (chan, new_mem->num_pages << PAGE_SHIFT);
 761                OUT_RING  (chan, upper_32_bits(node->vma[0].offset));
 762                OUT_RING  (chan, lower_32_bits(node->vma[0].offset));
 763                OUT_RING  (chan, upper_32_bits(node->vma[1].offset));
 764                OUT_RING  (chan, lower_32_bits(node->vma[1].offset));
 765                OUT_RING  (chan, 0x00000000 /* MODE_COPY, QUERY_NONE */);
 766        }
 767        return ret;
 768}
 769
 770static int
 771nv50_bo_move_init(struct nouveau_channel *chan, u32 handle)
 772{
 773        int ret = RING_SPACE(chan, 6);
 774        if (ret == 0) {
 775                BEGIN_NV04(chan, NvSubCopy, 0x0000, 1);
 776                OUT_RING  (chan, handle);
 777                BEGIN_NV04(chan, NvSubCopy, 0x0180, 3);
 778                OUT_RING  (chan, NvNotify0);
 779                OUT_RING  (chan, NvDmaFB);
 780                OUT_RING  (chan, NvDmaFB);
 781        }
 782
 783        return ret;
 784}
 785
 786static int
 787nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
 788                  struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
 789{
 790        struct nouveau_mem *node = old_mem->mm_node;
 791        struct nouveau_bo *nvbo = nouveau_bo(bo);
 792        u64 length = (new_mem->num_pages << PAGE_SHIFT);
 793        u64 src_offset = node->vma[0].offset;
 794        u64 dst_offset = node->vma[1].offset;
 795        int ret;
 796
 797        while (length) {
 798                u32 amount, stride, height;
 799
 800                amount  = min(length, (u64)(4 * 1024 * 1024));
 801                stride  = 16 * 4;
 802                height  = amount / stride;
 803
 804                if (old_mem->mem_type == TTM_PL_VRAM &&
 805                    nouveau_bo_tile_layout(nvbo)) {
 806                        ret = RING_SPACE(chan, 8);
 807                        if (ret)
 808                                return ret;
 809
 810                        BEGIN_NV04(chan, NvSubCopy, 0x0200, 7);
 811                        OUT_RING  (chan, 0);
 812                        OUT_RING  (chan, 0);
 813                        OUT_RING  (chan, stride);
 814                        OUT_RING  (chan, height);
 815                        OUT_RING  (chan, 1);
 816                        OUT_RING  (chan, 0);
 817                        OUT_RING  (chan, 0);
 818                } else {
 819                        ret = RING_SPACE(chan, 2);
 820                        if (ret)
 821                                return ret;
 822
 823                        BEGIN_NV04(chan, NvSubCopy, 0x0200, 1);
 824                        OUT_RING  (chan, 1);
 825                }
 826                if (new_mem->mem_type == TTM_PL_VRAM &&
 827                    nouveau_bo_tile_layout(nvbo)) {
 828                        ret = RING_SPACE(chan, 8);
 829                        if (ret)
 830                                return ret;
 831
 832                        BEGIN_NV04(chan, NvSubCopy, 0x021c, 7);
 833                        OUT_RING  (chan, 0);
 834                        OUT_RING  (chan, 0);
 835                        OUT_RING  (chan, stride);
 836                        OUT_RING  (chan, height);
 837                        OUT_RING  (chan, 1);
 838                        OUT_RING  (chan, 0);
 839                        OUT_RING  (chan, 0);
 840                } else {
 841                        ret = RING_SPACE(chan, 2);
 842                        if (ret)
 843                                return ret;
 844
 845                        BEGIN_NV04(chan, NvSubCopy, 0x021c, 1);
 846                        OUT_RING  (chan, 1);
 847                }
 848
 849                ret = RING_SPACE(chan, 14);
 850                if (ret)
 851                        return ret;
 852
 853                BEGIN_NV04(chan, NvSubCopy, 0x0238, 2);
 854                OUT_RING  (chan, upper_32_bits(src_offset));
 855                OUT_RING  (chan, upper_32_bits(dst_offset));
 856                BEGIN_NV04(chan, NvSubCopy, 0x030c, 8);
 857                OUT_RING  (chan, lower_32_bits(src_offset));
 858                OUT_RING  (chan, lower_32_bits(dst_offset));
 859                OUT_RING  (chan, stride);
 860                OUT_RING  (chan, stride);
 861                OUT_RING  (chan, stride);
 862                OUT_RING  (chan, height);
 863                OUT_RING  (chan, 0x00000101);
 864                OUT_RING  (chan, 0x00000000);
 865                BEGIN_NV04(chan, NvSubCopy, NV_MEMORY_TO_MEMORY_FORMAT_NOP, 1);
 866                OUT_RING  (chan, 0);
 867
 868                length -= amount;
 869                src_offset += amount;
 870                dst_offset += amount;
 871        }
 872
 873        return 0;
 874}
 875
 876static int
 877nv04_bo_move_init(struct nouveau_channel *chan, u32 handle)
 878{
 879        int ret = RING_SPACE(chan, 4);
 880        if (ret == 0) {
 881                BEGIN_NV04(chan, NvSubCopy, 0x0000, 1);
 882                OUT_RING  (chan, handle);
 883                BEGIN_NV04(chan, NvSubCopy, 0x0180, 1);
 884                OUT_RING  (chan, NvNotify0);
 885        }
 886
 887        return ret;
 888}
 889
 890static inline uint32_t
 891nouveau_bo_mem_ctxdma(struct ttm_buffer_object *bo,
 892                      struct nouveau_channel *chan, struct ttm_mem_reg *mem)
 893{
 894        if (mem->mem_type == TTM_PL_TT)
 895                return NvDmaTT;
 896        return NvDmaFB;
 897}
 898
 899static int
 900nv04_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
 901                  struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
 902{
 903        u32 src_offset = old_mem->start << PAGE_SHIFT;
 904        u32 dst_offset = new_mem->start << PAGE_SHIFT;
 905        u32 page_count = new_mem->num_pages;
 906        int ret;
 907
 908        ret = RING_SPACE(chan, 3);
 909        if (ret)
 910                return ret;
 911
 912        BEGIN_NV04(chan, NvSubCopy, NV_MEMORY_TO_MEMORY_FORMAT_DMA_SOURCE, 2);
 913        OUT_RING  (chan, nouveau_bo_mem_ctxdma(bo, chan, old_mem));
 914        OUT_RING  (chan, nouveau_bo_mem_ctxdma(bo, chan, new_mem));
 915
 916        page_count = new_mem->num_pages;
 917        while (page_count) {
 918                int line_count = (page_count > 2047) ? 2047 : page_count;
 919
 920                ret = RING_SPACE(chan, 11);
 921                if (ret)
 922                        return ret;
 923
 924                BEGIN_NV04(chan, NvSubCopy,
 925                                 NV_MEMORY_TO_MEMORY_FORMAT_OFFSET_IN, 8);
 926                OUT_RING  (chan, src_offset);
 927                OUT_RING  (chan, dst_offset);
 928                OUT_RING  (chan, PAGE_SIZE); /* src_pitch */
 929                OUT_RING  (chan, PAGE_SIZE); /* dst_pitch */
 930                OUT_RING  (chan, PAGE_SIZE); /* line_length */
 931                OUT_RING  (chan, line_count);
 932                OUT_RING  (chan, 0x00000101);
 933                OUT_RING  (chan, 0x00000000);
 934                BEGIN_NV04(chan, NvSubCopy, NV_MEMORY_TO_MEMORY_FORMAT_NOP, 1);
 935                OUT_RING  (chan, 0);
 936
 937                page_count -= line_count;
 938                src_offset += (PAGE_SIZE * line_count);
 939                dst_offset += (PAGE_SIZE * line_count);
 940        }
 941
 942        return 0;
 943}
 944
 945static int
 946nouveau_vma_getmap(struct nouveau_channel *chan, struct nouveau_bo *nvbo,
 947                   struct ttm_mem_reg *mem, struct nouveau_vma *vma)
 948{
 949        struct nouveau_mem *node = mem->mm_node;
 950        int ret;
 951
 952        ret = nouveau_vm_get(nv_client(chan->cli)->vm, mem->num_pages <<
 953                             PAGE_SHIFT, node->page_shift,
 954                             NV_MEM_ACCESS_RW, vma);
 955        if (ret)
 956                return ret;
 957
 958        if (mem->mem_type == TTM_PL_VRAM)
 959                nouveau_vm_map(vma, node);
 960        else
 961                nouveau_vm_map_sg(vma, 0, mem->num_pages << PAGE_SHIFT, node);
 962
 963        return 0;
 964}
 965
 966static int
 967nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr,
 968                     bool no_wait_gpu, struct ttm_mem_reg *new_mem)
 969{
 970        struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
 971        struct nouveau_channel *chan = chan = drm->channel;
 972        struct nouveau_bo *nvbo = nouveau_bo(bo);
 973        struct ttm_mem_reg *old_mem = &bo->mem;
 974        int ret;
 975
 976        mutex_lock(&chan->cli->mutex);
 977
 978        /* create temporary vmas for the transfer and attach them to the
 979         * old nouveau_mem node, these will get cleaned up after ttm has
 980         * destroyed the ttm_mem_reg
 981         */
 982        if (nv_device(drm->device)->card_type >= NV_50) {
 983                struct nouveau_mem *node = old_mem->mm_node;
 984
 985                ret = nouveau_vma_getmap(chan, nvbo, old_mem, &node->vma[0]);
 986                if (ret)
 987                        goto out;
 988
 989                ret = nouveau_vma_getmap(chan, nvbo, new_mem, &node->vma[1]);
 990                if (ret)
 991                        goto out;
 992        }
 993
 994        ret = drm->ttm.move(chan, bo, &bo->mem, new_mem);
 995        if (ret == 0) {
 996                ret = nouveau_bo_move_accel_cleanup(chan, nvbo, evict,
 997                                                    no_wait_gpu, new_mem);
 998        }
 999
1000out:
1001        mutex_unlock(&chan->cli->mutex);
1002        return ret;
1003}
1004
1005void
1006nouveau_bo_move_init(struct nouveau_drm *drm)
1007{
1008        static const struct {
1009                const char *name;
1010                int engine;
1011                u32 oclass;
1012                int (*exec)(struct nouveau_channel *,
1013                            struct ttm_buffer_object *,
1014                            struct ttm_mem_reg *, struct ttm_mem_reg *);
1015                int (*init)(struct nouveau_channel *, u32 handle);
1016        } _methods[] = {
1017                {  "COPY", 0, 0xa0b5, nve0_bo_move_copy, nve0_bo_move_init },
1018                {  "GRCE", 0, 0xa0b5, nve0_bo_move_copy, nvc0_bo_move_init },
1019                { "COPY1", 5, 0x90b8, nvc0_bo_move_copy, nvc0_bo_move_init },
1020                { "COPY0", 4, 0x90b5, nvc0_bo_move_copy, nvc0_bo_move_init },
1021                {  "COPY", 0, 0x85b5, nva3_bo_move_copy, nv50_bo_move_init },
1022                { "CRYPT", 0, 0x74c1, nv84_bo_move_exec, nv50_bo_move_init },
1023                {  "M2MF", 0, 0x9039, nvc0_bo_move_m2mf, nvc0_bo_move_init },
1024                {  "M2MF", 0, 0x5039, nv50_bo_move_m2mf, nv50_bo_move_init },
1025                {  "M2MF", 0, 0x0039, nv04_bo_move_m2mf, nv04_bo_move_init },
1026                {},
1027                { "CRYPT", 0, 0x88b4, nv98_bo_move_exec, nv50_bo_move_init },
1028        }, *mthd = _methods;
1029        const char *name = "CPU";
1030        int ret;
1031
1032        do {
1033                struct nouveau_object *object;
1034                struct nouveau_channel *chan;
1035                u32 handle = (mthd->engine << 16) | mthd->oclass;
1036
1037                if (mthd->init == nve0_bo_move_init)
1038                        chan = drm->cechan;
1039                else
1040                        chan = drm->channel;
1041                if (chan == NULL)
1042                        continue;
1043
1044                ret = nouveau_object_new(nv_object(drm), chan->handle, handle,
1045                                         mthd->oclass, NULL, 0, &object);
1046                if (ret == 0) {
1047                        ret = mthd->init(chan, handle);
1048                        if (ret) {
1049                                nouveau_object_del(nv_object(drm),
1050                                                   chan->handle, handle);
1051                                continue;
1052                        }
1053
1054                        drm->ttm.move = mthd->exec;
1055                        name = mthd->name;
1056                        break;
1057                }
1058        } while ((++mthd)->exec);
1059
1060        NV_INFO(drm, "MM: using %s for buffer copies\n", name);
1061}
1062
1063static int
1064nouveau_bo_move_flipd(struct ttm_buffer_object *bo, bool evict, bool intr,
1065                      bool no_wait_gpu, struct ttm_mem_reg *new_mem)
1066{
1067        u32 placement_memtype = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
1068        struct ttm_placement placement;
1069        struct ttm_mem_reg tmp_mem;
1070        int ret;
1071
1072        placement.fpfn = placement.lpfn = 0;
1073        placement.num_placement = placement.num_busy_placement = 1;
1074        placement.placement = placement.busy_placement = &placement_memtype;
1075
1076        tmp_mem = *new_mem;
1077        tmp_mem.mm_node = NULL;
1078        ret = ttm_bo_mem_space(bo, &placement, &tmp_mem, intr, no_wait_gpu);
1079        if (ret)
1080                return ret;
1081
1082        ret = ttm_tt_bind(bo->ttm, &tmp_mem);
1083        if (ret)
1084                goto out;
1085
1086        ret = nouveau_bo_move_m2mf(bo, true, intr, no_wait_gpu, &tmp_mem);
1087        if (ret)
1088                goto out;
1089
1090        ret = ttm_bo_move_ttm(bo, true, no_wait_gpu, new_mem);
1091out:
1092        ttm_bo_mem_put(bo, &tmp_mem);
1093        return ret;
1094}
1095
1096static int
1097nouveau_bo_move_flips(struct ttm_buffer_object *bo, bool evict, bool intr,
1098                      bool no_wait_gpu, struct ttm_mem_reg *new_mem)
1099{
1100        u32 placement_memtype = TTM_PL_FLAG_TT | TTM_PL_MASK_CACHING;
1101        struct ttm_placement placement;
1102        struct ttm_mem_reg tmp_mem;
1103        int ret;
1104
1105        placement.fpfn = placement.lpfn = 0;
1106        placement.num_placement = placement.num_busy_placement = 1;
1107        placement.placement = placement.busy_placement = &placement_memtype;
1108
1109        tmp_mem = *new_mem;
1110        tmp_mem.mm_node = NULL;
1111        ret = ttm_bo_mem_space(bo, &placement, &tmp_mem, intr, no_wait_gpu);
1112        if (ret)
1113                return ret;
1114
1115        ret = ttm_bo_move_ttm(bo, true, no_wait_gpu, &tmp_mem);
1116        if (ret)
1117                goto out;
1118
1119        ret = nouveau_bo_move_m2mf(bo, true, intr, no_wait_gpu, new_mem);
1120        if (ret)
1121                goto out;
1122
1123out:
1124        ttm_bo_mem_put(bo, &tmp_mem);
1125        return ret;
1126}
1127
1128static void
1129nouveau_bo_move_ntfy(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem)
1130{
1131        struct nouveau_bo *nvbo = nouveau_bo(bo);
1132        struct nouveau_vma *vma;
1133
1134        /* ttm can now (stupidly) pass the driver bos it didn't create... */
1135        if (bo->destroy != nouveau_bo_del_ttm)
1136                return;
1137
1138        list_for_each_entry(vma, &nvbo->vma_list, head) {
1139                if (new_mem && new_mem->mem_type == TTM_PL_VRAM) {
1140                        nouveau_vm_map(vma, new_mem->mm_node);
1141                } else
1142                if (new_mem && new_mem->mem_type == TTM_PL_TT &&
1143                    nvbo->page_shift == vma->vm->vmm->spg_shift) {
1144                        if (((struct nouveau_mem *)new_mem->mm_node)->sg)
1145                                nouveau_vm_map_sg_table(vma, 0, new_mem->
1146                                                  num_pages << PAGE_SHIFT,
1147                                                  new_mem->mm_node);
1148                        else
1149                                nouveau_vm_map_sg(vma, 0, new_mem->
1150                                                  num_pages << PAGE_SHIFT,
1151                                                  new_mem->mm_node);
1152                } else {
1153                        nouveau_vm_unmap(vma);
1154                }
1155        }
1156}
1157
1158static int
1159nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem,
1160                   struct nouveau_drm_tile **new_tile)
1161{
1162        struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
1163        struct drm_device *dev = drm->dev;
1164        struct nouveau_bo *nvbo = nouveau_bo(bo);
1165        u64 offset = new_mem->start << PAGE_SHIFT;
1166
1167        *new_tile = NULL;
1168        if (new_mem->mem_type != TTM_PL_VRAM)
1169                return 0;
1170
1171        if (nv_device(drm->device)->card_type >= NV_10) {
1172                *new_tile = nv10_bo_set_tiling(dev, offset, new_mem->size,
1173                                                nvbo->tile_mode,
1174                                                nvbo->tile_flags);
1175        }
1176
1177        return 0;
1178}
1179
1180static void
1181nouveau_bo_vm_cleanup(struct ttm_buffer_object *bo,
1182                      struct nouveau_drm_tile *new_tile,
1183                      struct nouveau_drm_tile **old_tile)
1184{
1185        struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
1186        struct drm_device *dev = drm->dev;
1187
1188        nv10_bo_put_tile_region(dev, *old_tile, bo->sync_obj);
1189        *old_tile = new_tile;
1190}
1191
1192static int
1193nouveau_bo_move(struct ttm_buffer_object *bo, bool evict, bool intr,
1194                bool no_wait_gpu, struct ttm_mem_reg *new_mem)
1195{
1196        struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
1197        struct nouveau_bo *nvbo = nouveau_bo(bo);
1198        struct ttm_mem_reg *old_mem = &bo->mem;
1199        struct nouveau_drm_tile *new_tile = NULL;
1200        int ret = 0;
1201
1202        if (nv_device(drm->device)->card_type < NV_50) {
1203                ret = nouveau_bo_vm_bind(bo, new_mem, &new_tile);
1204                if (ret)
1205                        return ret;
1206        }
1207
1208        /* Fake bo copy. */
1209        if (old_mem->mem_type == TTM_PL_SYSTEM && !bo->ttm) {
1210                BUG_ON(bo->mem.mm_node != NULL);
1211                bo->mem = *new_mem;
1212                new_mem->mm_node = NULL;
1213                goto out;
1214        }
1215
1216        /* CPU copy if we have no accelerated method available */
1217        if (!drm->ttm.move) {
1218                ret = ttm_bo_move_memcpy(bo, evict, no_wait_gpu, new_mem);
1219                goto out;
1220        }
1221
1222        /* Hardware assisted copy. */
1223        if (new_mem->mem_type == TTM_PL_SYSTEM)
1224                ret = nouveau_bo_move_flipd(bo, evict, intr,
1225                                            no_wait_gpu, new_mem);
1226        else if (old_mem->mem_type == TTM_PL_SYSTEM)
1227                ret = nouveau_bo_move_flips(bo, evict, intr,
1228                                            no_wait_gpu, new_mem);
1229        else
1230                ret = nouveau_bo_move_m2mf(bo, evict, intr,
1231                                           no_wait_gpu, new_mem);
1232
1233        if (!ret)
1234                goto out;
1235
1236        /* Fallback to software copy. */
1237        ret = ttm_bo_move_memcpy(bo, evict, no_wait_gpu, new_mem);
1238
1239out:
1240        if (nv_device(drm->device)->card_type < NV_50) {
1241                if (ret)
1242                        nouveau_bo_vm_cleanup(bo, NULL, &new_tile);
1243                else
1244                        nouveau_bo_vm_cleanup(bo, new_tile, &nvbo->tile);
1245        }
1246
1247        return ret;
1248}
1249
1250static int
1251nouveau_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp)
1252{
1253        return 0;
1254}
1255
1256static int
1257nouveau_ttm_io_mem_reserve(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
1258{
1259        struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
1260        struct nouveau_drm *drm = nouveau_bdev(bdev);
1261        struct drm_device *dev = drm->dev;
1262        int ret;
1263
1264        mem->bus.addr = NULL;
1265        mem->bus.offset = 0;
1266        mem->bus.size = mem->num_pages << PAGE_SHIFT;
1267        mem->bus.base = 0;
1268        mem->bus.is_iomem = false;
1269        if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
1270                return -EINVAL;
1271        switch (mem->mem_type) {
1272        case TTM_PL_SYSTEM:
1273                /* System memory */
1274                return 0;
1275        case TTM_PL_TT:
1276#if __OS_HAS_AGP
1277                if (drm->agp.stat == ENABLED) {
1278                        mem->bus.offset = mem->start << PAGE_SHIFT;
1279                        mem->bus.base = drm->agp.base;
1280                        mem->bus.is_iomem = !dev->agp->cant_use_aperture;
1281                }
1282#endif
1283                break;
1284        case TTM_PL_VRAM:
1285                mem->bus.offset = mem->start << PAGE_SHIFT;
1286                mem->bus.base = pci_resource_start(dev->pdev, 1);
1287                mem->bus.is_iomem = true;
1288                if (nv_device(drm->device)->card_type >= NV_50) {
1289                        struct nouveau_bar *bar = nouveau_bar(drm->device);
1290                        struct nouveau_mem *node = mem->mm_node;
1291
1292                        ret = bar->umap(bar, node, NV_MEM_ACCESS_RW,
1293                                        &node->bar_vma);
1294                        if (ret)
1295                                return ret;
1296
1297                        mem->bus.offset = node->bar_vma.offset;
1298                }
1299                break;
1300        default:
1301                return -EINVAL;
1302        }
1303        return 0;
1304}
1305
1306static void
1307nouveau_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
1308{
1309        struct nouveau_drm *drm = nouveau_bdev(bdev);
1310        struct nouveau_bar *bar = nouveau_bar(drm->device);
1311        struct nouveau_mem *node = mem->mm_node;
1312
1313        if (!node->bar_vma.node)
1314                return;
1315
1316        bar->unmap(bar, &node->bar_vma);
1317}
1318
1319static int
1320nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo)
1321{
1322        struct nouveau_drm *drm = nouveau_bdev(bo->bdev);
1323        struct nouveau_bo *nvbo = nouveau_bo(bo);
1324        struct nouveau_device *device = nv_device(drm->device);
1325        u32 mappable = pci_resource_len(device->pdev, 1) >> PAGE_SHIFT;
1326
1327        /* as long as the bo isn't in vram, and isn't tiled, we've got
1328         * nothing to do here.
1329         */
1330        if (bo->mem.mem_type != TTM_PL_VRAM) {
1331                if (nv_device(drm->device)->card_type < NV_50 ||
1332                    !nouveau_bo_tile_layout(nvbo))
1333                        return 0;
1334        }
1335
1336        /* make sure bo is in mappable vram */
1337        if (bo->mem.start + bo->mem.num_pages < mappable)
1338                return 0;
1339
1340
1341        nvbo->placement.fpfn = 0;
1342        nvbo->placement.lpfn = mappable;
1343        nouveau_bo_placement_set(nvbo, TTM_PL_FLAG_VRAM, 0);
1344        return nouveau_bo_validate(nvbo, false, false);
1345}
1346
1347static int
1348nouveau_ttm_tt_populate(struct ttm_tt *ttm)
1349{
1350        struct ttm_dma_tt *ttm_dma = (void *)ttm;
1351        struct nouveau_drm *drm;
1352        struct drm_device *dev;
1353        unsigned i;
1354        int r;
1355        bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
1356
1357        if (ttm->state != tt_unpopulated)
1358                return 0;
1359
1360        if (slave && ttm->sg) {
1361                /* make userspace faulting work */
1362                drm_prime_sg_to_page_addr_arrays(ttm->sg, ttm->pages,
1363                                                 ttm_dma->dma_address, ttm->num_pages);
1364                ttm->state = tt_unbound;
1365                return 0;
1366        }
1367
1368        drm = nouveau_bdev(ttm->bdev);
1369        dev = drm->dev;
1370
1371#if __OS_HAS_AGP
1372        if (drm->agp.stat == ENABLED) {
1373                return ttm_agp_tt_populate(ttm);
1374        }
1375#endif
1376
1377#ifdef CONFIG_SWIOTLB
1378        if (swiotlb_nr_tbl()) {
1379                return ttm_dma_populate((void *)ttm, dev->dev);
1380        }
1381#endif
1382
1383        r = ttm_pool_populate(ttm);
1384        if (r) {
1385                return r;
1386        }
1387
1388        for (i = 0; i < ttm->num_pages; i++) {
1389                ttm_dma->dma_address[i] = pci_map_page(dev->pdev, ttm->pages[i],
1390                                                   0, PAGE_SIZE,
1391                                                   PCI_DMA_BIDIRECTIONAL);
1392                if (pci_dma_mapping_error(dev->pdev, ttm_dma->dma_address[i])) {
1393                        while (--i) {
1394                                pci_unmap_page(dev->pdev, ttm_dma->dma_address[i],
1395                                               PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
1396                                ttm_dma->dma_address[i] = 0;
1397                        }
1398                        ttm_pool_unpopulate(ttm);
1399                        return -EFAULT;
1400                }
1401        }
1402        return 0;
1403}
1404
1405static void
1406nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
1407{
1408        struct ttm_dma_tt *ttm_dma = (void *)ttm;
1409        struct nouveau_drm *drm;
1410        struct drm_device *dev;
1411        unsigned i;
1412        bool slave = !!(ttm->page_flags & TTM_PAGE_FLAG_SG);
1413
1414        if (slave)
1415                return;
1416
1417        drm = nouveau_bdev(ttm->bdev);
1418        dev = drm->dev;
1419
1420#if __OS_HAS_AGP
1421        if (drm->agp.stat == ENABLED) {
1422                ttm_agp_tt_unpopulate(ttm);
1423                return;
1424        }
1425#endif
1426
1427#ifdef CONFIG_SWIOTLB
1428        if (swiotlb_nr_tbl()) {
1429                ttm_dma_unpopulate((void *)ttm, dev->dev);
1430                return;
1431        }
1432#endif
1433
1434        for (i = 0; i < ttm->num_pages; i++) {
1435                if (ttm_dma->dma_address[i]) {
1436                        pci_unmap_page(dev->pdev, ttm_dma->dma_address[i],
1437                                       PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
1438                }
1439        }
1440
1441        ttm_pool_unpopulate(ttm);
1442}
1443
1444void
1445nouveau_bo_fence(struct nouveau_bo *nvbo, struct nouveau_fence *fence)
1446{
1447        struct nouveau_fence *old_fence = NULL;
1448
1449        if (likely(fence))
1450                nouveau_fence_ref(fence);
1451
1452        spin_lock(&nvbo->bo.bdev->fence_lock);
1453        old_fence = nvbo->bo.sync_obj;
1454        nvbo->bo.sync_obj = fence;
1455        spin_unlock(&nvbo->bo.bdev->fence_lock);
1456
1457        nouveau_fence_unref(&old_fence);
1458}
1459
1460static void
1461nouveau_bo_fence_unref(void **sync_obj)
1462{
1463        nouveau_fence_unref((struct nouveau_fence **)sync_obj);
1464}
1465
1466static void *
1467nouveau_bo_fence_ref(void *sync_obj)
1468{
1469        return nouveau_fence_ref(sync_obj);
1470}
1471
1472static bool
1473nouveau_bo_fence_signalled(void *sync_obj)
1474{
1475        return nouveau_fence_done(sync_obj);
1476}
1477
1478static int
1479nouveau_bo_fence_wait(void *sync_obj, bool lazy, bool intr)
1480{
1481        return nouveau_fence_wait(sync_obj, lazy, intr);
1482}
1483
1484static int
1485nouveau_bo_fence_flush(void *sync_obj)
1486{
1487        return 0;
1488}
1489
1490struct ttm_bo_driver nouveau_bo_driver = {
1491        .ttm_tt_create = &nouveau_ttm_tt_create,
1492        .ttm_tt_populate = &nouveau_ttm_tt_populate,
1493        .ttm_tt_unpopulate = &nouveau_ttm_tt_unpopulate,
1494        .invalidate_caches = nouveau_bo_invalidate_caches,
1495        .init_mem_type = nouveau_bo_init_mem_type,
1496        .evict_flags = nouveau_bo_evict_flags,
1497        .move_notify = nouveau_bo_move_ntfy,
1498        .move = nouveau_bo_move,
1499        .verify_access = nouveau_bo_verify_access,
1500        .sync_obj_signaled = nouveau_bo_fence_signalled,
1501        .sync_obj_wait = nouveau_bo_fence_wait,
1502        .sync_obj_flush = nouveau_bo_fence_flush,
1503        .sync_obj_unref = nouveau_bo_fence_unref,
1504        .sync_obj_ref = nouveau_bo_fence_ref,
1505        .fault_reserve_notify = &nouveau_ttm_fault_reserve_notify,
1506        .io_mem_reserve = &nouveau_ttm_io_mem_reserve,
1507        .io_mem_free = &nouveau_ttm_io_mem_free,
1508};
1509
1510struct nouveau_vma *
1511nouveau_bo_vma_find(struct nouveau_bo *nvbo, struct nouveau_vm *vm)
1512{
1513        struct nouveau_vma *vma;
1514        list_for_each_entry(vma, &nvbo->vma_list, head) {
1515                if (vma->vm == vm)
1516                        return vma;
1517        }
1518
1519        return NULL;
1520}
1521
1522int
1523nouveau_bo_vma_add(struct nouveau_bo *nvbo, struct nouveau_vm *vm,
1524                   struct nouveau_vma *vma)
1525{
1526        const u32 size = nvbo->bo.mem.num_pages << PAGE_SHIFT;
1527        struct nouveau_mem *node = nvbo->bo.mem.mm_node;
1528        int ret;
1529
1530        ret = nouveau_vm_get(vm, size, nvbo->page_shift,
1531                             NV_MEM_ACCESS_RW, vma);
1532        if (ret)
1533                return ret;
1534
1535        if (nvbo->bo.mem.mem_type == TTM_PL_VRAM)
1536                nouveau_vm_map(vma, nvbo->bo.mem.mm_node);
1537        else if (nvbo->bo.mem.mem_type == TTM_PL_TT) {
1538                if (node->sg)
1539                        nouveau_vm_map_sg_table(vma, 0, size, node);
1540                else
1541                        nouveau_vm_map_sg(vma, 0, size, node);
1542        }
1543
1544        list_add_tail(&vma->head, &nvbo->vma_list);
1545        vma->refcount = 1;
1546        return 0;
1547}
1548
1549void
1550nouveau_bo_vma_del(struct nouveau_bo *nvbo, struct nouveau_vma *vma)
1551{
1552        if (vma->node) {
1553                if (nvbo->bo.mem.mem_type != TTM_PL_SYSTEM) {
1554                        spin_lock(&nvbo->bo.bdev->fence_lock);
1555                        ttm_bo_wait(&nvbo->bo, false, false, false);
1556                        spin_unlock(&nvbo->bo.bdev->fence_lock);
1557                        nouveau_vm_unmap(vma);
1558                }
1559
1560                nouveau_vm_put(vma);
1561                list_del(&vma->head);
1562        }
1563}
1564