drm/nouveau/bo: split buffer move functions into their own source files
[linux-2.6-microblaze.git] / drivers / gpu / drm / nouveau / nouveau_bo5039.c
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 #include "nouveau_bo.h"
30 #include "nouveau_dma.h"
31 #include "nouveau_drv.h"
32 #include "nouveau_mem.h"
33
34 int
35 nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
36                   struct ttm_mem_reg *old_reg, struct ttm_mem_reg *new_reg)
37 {
38         struct nouveau_mem *mem = nouveau_mem(old_reg);
39         u64 length = (new_reg->num_pages << PAGE_SHIFT);
40         u64 src_offset = mem->vma[0].addr;
41         u64 dst_offset = mem->vma[1].addr;
42         int src_tiled = !!mem->kind;
43         int dst_tiled = !!nouveau_mem(new_reg)->kind;
44         int ret;
45
46         while (length) {
47                 u32 amount, stride, height;
48
49                 ret = RING_SPACE(chan, 18 + 6 * (src_tiled + dst_tiled));
50                 if (ret)
51                         return ret;
52
53                 amount  = min(length, (u64)(4 * 1024 * 1024));
54                 stride  = 16 * 4;
55                 height  = amount / stride;
56
57                 if (src_tiled) {
58                         BEGIN_NV04(chan, NvSubCopy, 0x0200, 7);
59                         OUT_RING  (chan, 0);
60                         OUT_RING  (chan, 0);
61                         OUT_RING  (chan, stride);
62                         OUT_RING  (chan, height);
63                         OUT_RING  (chan, 1);
64                         OUT_RING  (chan, 0);
65                         OUT_RING  (chan, 0);
66                 } else {
67                         BEGIN_NV04(chan, NvSubCopy, 0x0200, 1);
68                         OUT_RING  (chan, 1);
69                 }
70                 if (dst_tiled) {
71                         BEGIN_NV04(chan, NvSubCopy, 0x021c, 7);
72                         OUT_RING  (chan, 0);
73                         OUT_RING  (chan, 0);
74                         OUT_RING  (chan, stride);
75                         OUT_RING  (chan, height);
76                         OUT_RING  (chan, 1);
77                         OUT_RING  (chan, 0);
78                         OUT_RING  (chan, 0);
79                 } else {
80                         BEGIN_NV04(chan, NvSubCopy, 0x021c, 1);
81                         OUT_RING  (chan, 1);
82                 }
83
84                 BEGIN_NV04(chan, NvSubCopy, 0x0238, 2);
85                 OUT_RING  (chan, upper_32_bits(src_offset));
86                 OUT_RING  (chan, upper_32_bits(dst_offset));
87                 BEGIN_NV04(chan, NvSubCopy, 0x030c, 8);
88                 OUT_RING  (chan, lower_32_bits(src_offset));
89                 OUT_RING  (chan, lower_32_bits(dst_offset));
90                 OUT_RING  (chan, stride);
91                 OUT_RING  (chan, stride);
92                 OUT_RING  (chan, stride);
93                 OUT_RING  (chan, height);
94                 OUT_RING  (chan, 0x00000101);
95                 OUT_RING  (chan, 0x00000000);
96                 BEGIN_NV04(chan, NvSubCopy, NV_MEMORY_TO_MEMORY_FORMAT_NOP, 1);
97                 OUT_RING  (chan, 0);
98
99                 length -= amount;
100                 src_offset += amount;
101                 dst_offset += amount;
102         }
103
104         return 0;
105 }
106
107 int
108 nv50_bo_move_init(struct nouveau_channel *chan, u32 handle)
109 {
110         int ret = RING_SPACE(chan, 6);
111         if (ret == 0) {
112                 BEGIN_NV04(chan, NvSubCopy, 0x0000, 1);
113                 OUT_RING  (chan, handle);
114                 BEGIN_NV04(chan, NvSubCopy, 0x0180, 3);
115                 OUT_RING  (chan, chan->drm->ntfy.handle);
116                 OUT_RING  (chan, chan->vram.handle);
117                 OUT_RING  (chan, chan->vram.handle);
118         }
119
120         return ret;
121 }