aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nouveau_channel.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-06-02 23:59:44 -0400
committerBen Skeggs <bskeggs@redhat.com>2011-06-23 01:59:12 -0400
commitdd6a46cc922bec58e9c73782cd59f50a239c4fa7 (patch)
treef68bc2734d93721da4d92ad30a8b684efc9b2835 /drivers/gpu/drm/nouveau/nouveau_channel.c
parentb7cb6c01ee549b6c7c365c92f156983d346295a3 (diff)
drm/nouveau: initialise any vm for a channel before pushbuf/ntfy
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_channel.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_channel.c114
1 files changed, 48 insertions, 66 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
index 96ac906cfee5..23bd0c4f70b1 100644
--- a/drivers/gpu/drm/nouveau/nouveau_channel.c
+++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
@@ -30,14 +30,31 @@
30#include "nouveau_ramht.h" 30#include "nouveau_ramht.h"
31 31
32static int 32static int
33nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan) 33nouveau_channel_pushbuf_init(struct nouveau_channel *chan)
34{ 34{
35 u32 mem = nouveau_vram_pushbuf ? TTM_PL_FLAG_VRAM : TTM_PL_FLAG_TT;
35 struct drm_device *dev = chan->dev; 36 struct drm_device *dev = chan->dev;
36 struct drm_nouveau_private *dev_priv = dev->dev_private; 37 struct drm_nouveau_private *dev_priv = dev->dev_private;
37 struct nouveau_bo *pb = chan->pushbuf_bo; 38 int ret;
38 struct nouveau_gpuobj *pushbuf = NULL; 39
39 int ret = 0; 40 /* allocate buffer object */
41 ret = nouveau_bo_new(dev, NULL, 65536, 0, mem, 0, 0, &chan->pushbuf_bo);
42 if (ret)
43 goto out;
40 44
45 ret = nouveau_bo_pin(chan->pushbuf_bo, mem);
46 if (ret)
47 goto out;
48
49 ret = nouveau_bo_map(chan->pushbuf_bo);
50 if (ret)
51 goto out;
52
53 /* create DMA object covering the entire memtype where the push
54 * buffer resides, userspace can submit its own push buffers from
55 * anywhere within the same memtype.
56 */
57 chan->pushbuf_base = chan->pushbuf_bo->bo.mem.start << PAGE_SHIFT;
41 if (dev_priv->card_type >= NV_50) { 58 if (dev_priv->card_type >= NV_50) {
42 if (dev_priv->card_type < NV_C0) { 59 if (dev_priv->card_type < NV_C0) {
43 ret = nouveau_gpuobj_dma_new(chan, 60 ret = nouveau_gpuobj_dma_new(chan,
@@ -45,23 +62,23 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan)
45 (1ULL << 40), 62 (1ULL << 40),
46 NV_MEM_ACCESS_RO, 63 NV_MEM_ACCESS_RO,
47 NV_MEM_TARGET_VM, 64 NV_MEM_TARGET_VM,
48 &pushbuf); 65 &chan->pushbuf);
49 } 66 }
50 chan->pushbuf_base = pb->bo.offset; 67 chan->pushbuf_base = chan->pushbuf_bo->bo.offset;
51 } else 68 } else
52 if (pb->bo.mem.mem_type == TTM_PL_TT) { 69 if (chan->pushbuf_bo->bo.mem.mem_type == TTM_PL_TT) {
53 ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, 70 ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0,
54 dev_priv->gart_info.aper_size, 71 dev_priv->gart_info.aper_size,
55 NV_MEM_ACCESS_RO, 72 NV_MEM_ACCESS_RO,
56 NV_MEM_TARGET_GART, &pushbuf); 73 NV_MEM_TARGET_GART,
57 chan->pushbuf_base = pb->bo.mem.start << PAGE_SHIFT; 74 &chan->pushbuf);
58 } else 75 } else
59 if (dev_priv->card_type != NV_04) { 76 if (dev_priv->card_type != NV_04) {
60 ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, 77 ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0,
61 dev_priv->fb_available_size, 78 dev_priv->fb_available_size,
62 NV_MEM_ACCESS_RO, 79 NV_MEM_ACCESS_RO,
63 NV_MEM_TARGET_VRAM, &pushbuf); 80 NV_MEM_TARGET_VRAM,
64 chan->pushbuf_base = pb->bo.mem.start << PAGE_SHIFT; 81 &chan->pushbuf);
65 } else { 82 } else {
66 /* NV04 cmdbuf hack, from original ddx.. not sure of it's 83 /* NV04 cmdbuf hack, from original ddx.. not sure of it's
67 * exact reason for existing :) PCI access to cmdbuf in 84 * exact reason for existing :) PCI access to cmdbuf in
@@ -71,47 +88,21 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan)
71 pci_resource_start(dev->pdev, 1), 88 pci_resource_start(dev->pdev, 1),
72 dev_priv->fb_available_size, 89 dev_priv->fb_available_size,
73 NV_MEM_ACCESS_RO, 90 NV_MEM_ACCESS_RO,
74 NV_MEM_TARGET_PCI, &pushbuf); 91 NV_MEM_TARGET_PCI,
75 chan->pushbuf_base = pb->bo.mem.start << PAGE_SHIFT; 92 &chan->pushbuf);
76 }
77
78 nouveau_gpuobj_ref(pushbuf, &chan->pushbuf);
79 nouveau_gpuobj_ref(NULL, &pushbuf);
80 return ret;
81}
82
83static struct nouveau_bo *
84nouveau_channel_user_pushbuf_alloc(struct drm_device *dev)
85{
86 struct nouveau_bo *pushbuf = NULL;
87 int location, ret;
88
89 if (nouveau_vram_pushbuf)
90 location = TTM_PL_FLAG_VRAM;
91 else
92 location = TTM_PL_FLAG_TT;
93
94 ret = nouveau_bo_new(dev, NULL, 65536, 0, location, 0, 0x0000, &pushbuf);
95 if (ret) {
96 NV_ERROR(dev, "error allocating DMA push buffer: %d\n", ret);
97 return NULL;
98 } 93 }
99 94
100 ret = nouveau_bo_pin(pushbuf, location); 95out:
101 if (ret) { 96 if (ret) {
102 NV_ERROR(dev, "error pinning DMA push buffer: %d\n", ret); 97 NV_ERROR(dev, "error initialising pushbuf: %d\n", ret);
103 nouveau_bo_ref(NULL, &pushbuf); 98 nouveau_gpuobj_ref(NULL, &chan->pushbuf);
104 return NULL; 99 if (chan->pushbuf_bo) {
105 } 100 nouveau_bo_unmap(chan->pushbuf_bo);
106 101 nouveau_bo_ref(NULL, &chan->pushbuf_bo);
107 ret = nouveau_bo_map(pushbuf); 102 }
108 if (ret) {
109 nouveau_bo_unpin(pushbuf);
110 nouveau_bo_ref(NULL, &pushbuf);
111 return NULL;
112 } 103 }
113 104
114 return pushbuf; 105 return 0;
115} 106}
116 107
117/* allocates and initializes a fifo for user space consumption */ 108/* allocates and initializes a fifo for user space consumption */
@@ -162,19 +153,14 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
162 INIT_LIST_HEAD(&chan->nvsw.flip); 153 INIT_LIST_HEAD(&chan->nvsw.flip);
163 INIT_LIST_HEAD(&chan->fence.pending); 154 INIT_LIST_HEAD(&chan->fence.pending);
164 155
165 /* Allocate DMA push buffer */ 156 /* setup channel's memory and vm */
166 chan->pushbuf_bo = nouveau_channel_user_pushbuf_alloc(dev); 157 ret = nouveau_gpuobj_channel_init(chan, vram_handle, gart_handle);
167 if (!chan->pushbuf_bo) { 158 if (ret) {
168 ret = -ENOMEM; 159 NV_ERROR(dev, "gpuobj %d\n", ret);
169 NV_ERROR(dev, "pushbuf %d\n", ret);
170 nouveau_channel_put(&chan); 160 nouveau_channel_put(&chan);
171 return ret; 161 return ret;
172 } 162 }
173 163
174 nouveau_dma_pre_init(chan);
175 chan->user_put = 0x40;
176 chan->user_get = 0x44;
177
178 /* Allocate space for per-channel fixed notifier memory */ 164 /* Allocate space for per-channel fixed notifier memory */
179 ret = nouveau_notifier_init_channel(chan); 165 ret = nouveau_notifier_init_channel(chan);
180 if (ret) { 166 if (ret) {
@@ -183,21 +169,17 @@ nouveau_channel_alloc(struct drm_device *dev, struct nouveau_channel **chan_ret,
183 return ret; 169 return ret;
184 } 170 }
185 171
186 /* Setup channel's default objects */ 172 /* Allocate DMA push buffer */
187 ret = nouveau_gpuobj_channel_init(chan, vram_handle, gart_handle); 173 ret = nouveau_channel_pushbuf_init(chan);
188 if (ret) { 174 if (ret) {
189 NV_ERROR(dev, "gpuobj %d\n", ret); 175 NV_ERROR(dev, "pushbuf %d\n", ret);
190 nouveau_channel_put(&chan); 176 nouveau_channel_put(&chan);
191 return ret; 177 return ret;
192 } 178 }
193 179
194 /* Create a dma object for the push buffer */ 180 nouveau_dma_pre_init(chan);
195 ret = nouveau_channel_pushbuf_ctxdma_init(chan); 181 chan->user_put = 0x40;
196 if (ret) { 182 chan->user_get = 0x44;
197 NV_ERROR(dev, "pbctxdma %d\n", ret);
198 nouveau_channel_put(&chan);
199 return ret;
200 }
201 183
202 /* disable the fifo caches */ 184 /* disable the fifo caches */
203 pfifo->reassign(dev, false); 185 pfifo->reassign(dev, false);