diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-06-02 23:59:44 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-06-23 01:59:12 -0400 |
commit | dd6a46cc922bec58e9c73782cd59f50a239c4fa7 (patch) | |
tree | f68bc2734d93721da4d92ad30a8b684efc9b2835 /drivers/gpu/drm/nouveau/nouveau_channel.c | |
parent | b7cb6c01ee549b6c7c365c92f156983d346295a3 (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.c | 114 |
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 | ||
32 | static int | 32 | static int |
33 | nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan) | 33 | nouveau_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 | |||
83 | static struct nouveau_bo * | ||
84 | nouveau_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); | 95 | out: |
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); |