Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Copyright 2007 Dave Airlied
0003  * All Rights Reserved.
0004  *
0005  * Permission is hereby granted, free of charge, to any person obtaining a
0006  * copy of this software and associated documentation files (the "Software"),
0007  * to deal in the Software without restriction, including without limitation
0008  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
0009  * and/or sell copies of the Software, and to permit persons to whom the
0010  * Software is furnished to do so, subject to the following conditions:
0011  *
0012  * The above copyright notice and this permission notice (including the next
0013  * paragraph) shall be included in all copies or substantial portions of the
0014  * Software.
0015  *
0016  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0017  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0018  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
0019  * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
0020  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
0021  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
0022  * OTHER DEALINGS IN THE SOFTWARE.
0023  */
0024 /*
0025  * Authors: Dave Airlied <airlied@linux.ie>
0026  *      Ben Skeggs   <darktama@iinet.net.au>
0027  *      Jeremy Kolb  <jkolb@brandeis.edu>
0028  */
0029 #include "nouveau_bo.h"
0030 #include "nouveau_dma.h"
0031 #include "nouveau_drv.h"
0032 #include "nouveau_mem.h"
0033 
0034 #include <nvif/push206e.h>
0035 
0036 #include <nvhw/class/cl5039.h>
0037 
0038 int
0039 nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
0040           struct ttm_resource *old_reg, struct ttm_resource *new_reg)
0041 {
0042     struct nouveau_mem *mem = nouveau_mem(old_reg);
0043     struct nvif_push *push = chan->chan.push;
0044     u64 length = (new_reg->num_pages << PAGE_SHIFT);
0045     u64 src_offset = mem->vma[0].addr;
0046     u64 dst_offset = mem->vma[1].addr;
0047     int src_tiled = !!mem->kind;
0048     int dst_tiled = !!nouveau_mem(new_reg)->kind;
0049     int ret;
0050 
0051     while (length) {
0052         u32 amount, stride, height;
0053 
0054         ret = PUSH_WAIT(push, 18 + 6 * (src_tiled + dst_tiled));
0055         if (ret)
0056             return ret;
0057 
0058         amount  = min(length, (u64)(4 * 1024 * 1024));
0059         stride  = 16 * 4;
0060         height  = amount / stride;
0061 
0062         if (src_tiled) {
0063             PUSH_MTHD(push, NV5039, SET_SRC_MEMORY_LAYOUT,
0064                   NVDEF(NV5039, SET_SRC_MEMORY_LAYOUT, V, BLOCKLINEAR),
0065 
0066                         SET_SRC_BLOCK_SIZE,
0067                   NVDEF(NV5039, SET_SRC_BLOCK_SIZE, WIDTH, ONE_GOB) |
0068                   NVDEF(NV5039, SET_SRC_BLOCK_SIZE, HEIGHT, ONE_GOB) |
0069                   NVDEF(NV5039, SET_SRC_BLOCK_SIZE, DEPTH, ONE_GOB),
0070 
0071                         SET_SRC_WIDTH, stride,
0072                         SET_SRC_HEIGHT, height,
0073                         SET_SRC_DEPTH, 1,
0074                         SET_SRC_LAYER, 0,
0075 
0076                         SET_SRC_ORIGIN,
0077                   NVVAL(NV5039, SET_SRC_ORIGIN, X, 0) |
0078                   NVVAL(NV5039, SET_SRC_ORIGIN, Y, 0));
0079         } else {
0080             PUSH_MTHD(push, NV5039, SET_SRC_MEMORY_LAYOUT,
0081                   NVDEF(NV5039, SET_SRC_MEMORY_LAYOUT, V, PITCH));
0082         }
0083 
0084         if (dst_tiled) {
0085             PUSH_MTHD(push, NV5039, SET_DST_MEMORY_LAYOUT,
0086                   NVDEF(NV5039, SET_DST_MEMORY_LAYOUT, V, BLOCKLINEAR),
0087 
0088                         SET_DST_BLOCK_SIZE,
0089                   NVDEF(NV5039, SET_DST_BLOCK_SIZE, WIDTH, ONE_GOB) |
0090                   NVDEF(NV5039, SET_DST_BLOCK_SIZE, HEIGHT, ONE_GOB) |
0091                   NVDEF(NV5039, SET_DST_BLOCK_SIZE, DEPTH, ONE_GOB),
0092 
0093                         SET_DST_WIDTH, stride,
0094                         SET_DST_HEIGHT, height,
0095                         SET_DST_DEPTH, 1,
0096                         SET_DST_LAYER, 0,
0097 
0098                         SET_DST_ORIGIN,
0099                   NVVAL(NV5039, SET_DST_ORIGIN, X, 0) |
0100                   NVVAL(NV5039, SET_DST_ORIGIN, Y, 0));
0101         } else {
0102             PUSH_MTHD(push, NV5039, SET_DST_MEMORY_LAYOUT,
0103                   NVDEF(NV5039, SET_DST_MEMORY_LAYOUT, V, PITCH));
0104         }
0105 
0106         PUSH_MTHD(push, NV5039, OFFSET_IN_UPPER,
0107               NVVAL(NV5039, OFFSET_IN_UPPER, VALUE, upper_32_bits(src_offset)),
0108 
0109                     OFFSET_OUT_UPPER,
0110               NVVAL(NV5039, OFFSET_OUT_UPPER, VALUE, upper_32_bits(dst_offset)));
0111 
0112         PUSH_MTHD(push, NV5039, OFFSET_IN, lower_32_bits(src_offset),
0113                     OFFSET_OUT, lower_32_bits(dst_offset),
0114                     PITCH_IN, stride,
0115                     PITCH_OUT, stride,
0116                     LINE_LENGTH_IN, stride,
0117                     LINE_COUNT, height,
0118 
0119                     FORMAT,
0120               NVDEF(NV5039, FORMAT, IN, ONE) |
0121               NVDEF(NV5039, FORMAT, OUT, ONE),
0122 
0123                     BUFFER_NOTIFY,
0124               NVDEF(NV5039, BUFFER_NOTIFY, TYPE, WRITE_ONLY));
0125 
0126         PUSH_MTHD(push, NV5039, NO_OPERATION, 0x00000000);
0127 
0128         length -= amount;
0129         src_offset += amount;
0130         dst_offset += amount;
0131     }
0132 
0133     return 0;
0134 }
0135 
0136 int
0137 nv50_bo_move_init(struct nouveau_channel *chan, u32 handle)
0138 {
0139     struct nvif_push *push = chan->chan.push;
0140     int ret;
0141 
0142     ret = PUSH_WAIT(push, 6);
0143     if (ret)
0144         return ret;
0145 
0146     PUSH_MTHD(push, NV5039, SET_OBJECT, handle);
0147     PUSH_MTHD(push, NV5039, SET_CONTEXT_DMA_NOTIFY, chan->drm->ntfy.handle,
0148                 SET_CONTEXT_DMA_BUFFER_IN, chan->vram.handle,
0149                 SET_CONTEXT_DMA_BUFFER_OUT, chan->vram.handle);
0150     return 0;
0151 }