aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_abi16.c5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.c31
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bo.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_chan.c35
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_chan.h2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.c22
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drm.h1
7 files changed, 72 insertions, 26 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c
index 9e6ced3b941a..cc79c796afee 100644
--- a/drivers/gpu/drm/nouveau/nouveau_abi16.c
+++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c
@@ -264,6 +264,11 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS)
264 abi16->handles |= (1 << init->channel); 264 abi16->handles |= (1 << init->channel);
265 265
266 /* create channel object and initialise dma and fence management */ 266 /* create channel object and initialise dma and fence management */
267 if (device->card_type >= NV_E0) {
268 init->fb_ctxdma_handle = NVE0_CHANNEL_IND_ENGINE_GR;
269 init->tt_ctxdma_handle = 0;
270 }
271
267 ret = nouveau_channel_new(drm, cli, NVDRM_DEVICE, NVDRM_CHAN | 272 ret = nouveau_channel_new(drm, cli, NVDRM_DEVICE, NVDRM_CHAN |
268 init->channel, init->fb_ctxdma_handle, 273 init->channel, init->fb_ctxdma_handle,
269 init->tt_ctxdma_handle, &chan->chan); 274 init->tt_ctxdma_handle, &chan->chan);
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c
index ef96bdbb5255..259e5f1adf47 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -571,6 +571,18 @@ nouveau_bo_move_accel_cleanup(struct nouveau_channel *chan,
571} 571}
572 572
573static int 573static int
574nve0_bo_move_init(struct nouveau_channel *chan, u32 handle)
575{
576 int ret = RING_SPACE(chan, 2);
577 if (ret == 0) {
578 BEGIN_NVC0(chan, NvSubCopy, 0x0000, 1);
579 OUT_RING (chan, handle);
580 FIRE_RING (chan);
581 }
582 return ret;
583}
584
585static int
574nve0_bo_move_copy(struct nouveau_channel *chan, struct ttm_buffer_object *bo, 586nve0_bo_move_copy(struct nouveau_channel *chan, struct ttm_buffer_object *bo,
575 struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem) 587 struct ttm_mem_reg *old_mem, struct ttm_mem_reg *new_mem)
576{ 588{
@@ -991,10 +1003,8 @@ out:
991} 1003}
992 1004
993void 1005void
994nouveau_bo_move_init(struct nouveau_channel *chan) 1006nouveau_bo_move_init(struct nouveau_drm *drm)
995{ 1007{
996 struct nouveau_cli *cli = chan->cli;
997 struct nouveau_drm *drm = chan->drm;
998 static const struct { 1008 static const struct {
999 const char *name; 1009 const char *name;
1000 int engine; 1010 int engine;
@@ -1004,7 +1014,8 @@ nouveau_bo_move_init(struct nouveau_channel *chan)
1004 struct ttm_mem_reg *, struct ttm_mem_reg *); 1014 struct ttm_mem_reg *, struct ttm_mem_reg *);
1005 int (*init)(struct nouveau_channel *, u32 handle); 1015 int (*init)(struct nouveau_channel *, u32 handle);
1006 } _methods[] = { 1016 } _methods[] = {
1007 { "COPY", 0, 0xa0b5, nve0_bo_move_copy, nvc0_bo_move_init }, 1017 { "COPY", 0, 0xa0b5, nve0_bo_move_copy, nve0_bo_move_init },
1018 { "GRCE", 0, 0xa0b5, nve0_bo_move_copy, nvc0_bo_move_init },
1008 { "COPY1", 5, 0x90b8, nvc0_bo_move_copy, nvc0_bo_move_init }, 1019 { "COPY1", 5, 0x90b8, nvc0_bo_move_copy, nvc0_bo_move_init },
1009 { "COPY0", 4, 0x90b5, nvc0_bo_move_copy, nvc0_bo_move_init }, 1020 { "COPY0", 4, 0x90b5, nvc0_bo_move_copy, nvc0_bo_move_init },
1010 { "COPY", 0, 0x85b5, nva3_bo_move_copy, nv50_bo_move_init }, 1021 { "COPY", 0, 0x85b5, nva3_bo_move_copy, nv50_bo_move_init },
@@ -1020,14 +1031,22 @@ nouveau_bo_move_init(struct nouveau_channel *chan)
1020 1031
1021 do { 1032 do {
1022 struct nouveau_object *object; 1033 struct nouveau_object *object;
1034 struct nouveau_channel *chan;
1023 u32 handle = (mthd->engine << 16) | mthd->oclass; 1035 u32 handle = (mthd->engine << 16) | mthd->oclass;
1024 1036
1025 ret = nouveau_object_new(nv_object(cli), chan->handle, handle, 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,
1026 mthd->oclass, NULL, 0, &object); 1045 mthd->oclass, NULL, 0, &object);
1027 if (ret == 0) { 1046 if (ret == 0) {
1028 ret = mthd->init(chan, handle); 1047 ret = mthd->init(chan, handle);
1029 if (ret) { 1048 if (ret) {
1030 nouveau_object_del(nv_object(cli), 1049 nouveau_object_del(nv_object(drm),
1031 chan->handle, handle); 1050 chan->handle, handle);
1032 continue; 1051 continue;
1033 } 1052 }
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h
index c42aea9fb546..dec51b1098fe 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.h
@@ -61,7 +61,7 @@ nouveau_bo_ref(struct nouveau_bo *ref, struct nouveau_bo **pnvbo)
61 61
62extern struct ttm_bo_driver nouveau_bo_driver; 62extern struct ttm_bo_driver nouveau_bo_driver;
63 63
64void nouveau_bo_move_init(struct nouveau_channel *); 64void nouveau_bo_move_init(struct nouveau_drm *);
65int nouveau_bo_new(struct drm_device *, int size, int align, u32 flags, 65int nouveau_bo_new(struct drm_device *, int size, int align, u32 flags,
66 u32 tile_mode, u32 tile_flags, struct sg_table *sg, 66 u32 tile_mode, u32 tile_flags, struct sg_table *sg,
67 struct nouveau_bo **); 67 struct nouveau_bo **);
diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c
index b1eea19d99a6..62c7edf08e5a 100644
--- a/drivers/gpu/drm/nouveau/nouveau_chan.c
+++ b/drivers/gpu/drm/nouveau/nouveau_chan.c
@@ -184,7 +184,8 @@ nouveau_channel_prep(struct nouveau_drm *drm, struct nouveau_cli *cli,
184 184
185int 185int
186nouveau_channel_ind(struct nouveau_drm *drm, struct nouveau_cli *cli, 186nouveau_channel_ind(struct nouveau_drm *drm, struct nouveau_cli *cli,
187 u32 parent, u32 handle, struct nouveau_channel **pchan) 187 u32 parent, u32 handle, u32 engine,
188 struct nouveau_channel **pchan)
188{ 189{
189 static const u16 oclasses[] = { 0xa06f, 0x906f, 0x826f, 0x506f, 0 }; 190 static const u16 oclasses[] = { 0xa06f, 0x906f, 0x826f, 0x506f, 0 };
190 const u16 *oclass = oclasses; 191 const u16 *oclass = oclasses;
@@ -202,7 +203,7 @@ nouveau_channel_ind(struct nouveau_drm *drm, struct nouveau_cli *cli,
202 args.pushbuf = chan->push.handle; 203 args.pushbuf = chan->push.handle;
203 args.ioffset = 0x10000 + chan->push.vma.offset; 204 args.ioffset = 0x10000 + chan->push.vma.offset;
204 args.ilength = 0x02000; 205 args.ilength = 0x02000;
205 args.engine = NVE0_CHANNEL_IND_ENGINE_GR; 206 args.engine = engine;
206 207
207 do { 208 do {
208 ret = nouveau_object_new(nv_object(cli), parent, handle, 209 ret = nouveau_object_new(nv_object(cli), parent, handle,
@@ -261,9 +262,6 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
261 struct nv_dma_class args; 262 struct nv_dma_class args;
262 int ret, i; 263 int ret, i;
263 264
264 chan->vram = vram;
265 chan->gart = gart;
266
267 /* allocate dma objects to cover all allowed vram, and gart */ 265 /* allocate dma objects to cover all allowed vram, and gart */
268 if (device->card_type < NV_C0) { 266 if (device->card_type < NV_C0) {
269 if (device->card_type >= NV_50) { 267 if (device->card_type >= NV_50) {
@@ -301,6 +299,9 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
301 0x003d, &args, sizeof(args), &object); 299 0x003d, &args, sizeof(args), &object);
302 if (ret) 300 if (ret)
303 return ret; 301 return ret;
302
303 chan->vram = vram;
304 chan->gart = gart;
304 } 305 }
305 306
306 /* initialise dma tracking parameters */ 307 /* initialise dma tracking parameters */
@@ -336,15 +337,17 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
336 /* allocate software object class (used for fences on <= nv05, and 337 /* allocate software object class (used for fences on <= nv05, and
337 * to signal flip completion), bind it to a subchannel. 338 * to signal flip completion), bind it to a subchannel.
338 */ 339 */
339 ret = nouveau_object_new(nv_object(client), chan->handle, 340 if (chan != chan->drm->cechan) {
340 NvSw, nouveau_abi16_swclass(chan->drm), 341 ret = nouveau_object_new(nv_object(client), chan->handle,
341 NULL, 0, &object); 342 NvSw, nouveau_abi16_swclass(chan->drm),
342 if (ret) 343 NULL, 0, &object);
343 return ret; 344 if (ret)
345 return ret;
344 346
345 swch = (void *)object->parent; 347 swch = (void *)object->parent;
346 swch->flip = nouveau_flip_complete; 348 swch->flip = nouveau_flip_complete;
347 swch->flip_data = chan; 349 swch->flip_data = chan;
350 }
348 351
349 if (device->card_type < NV_C0) { 352 if (device->card_type < NV_C0) {
350 ret = RING_SPACE(chan, 2); 353 ret = RING_SPACE(chan, 2);
@@ -362,12 +365,12 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart)
362 365
363int 366int
364nouveau_channel_new(struct nouveau_drm *drm, struct nouveau_cli *cli, 367nouveau_channel_new(struct nouveau_drm *drm, struct nouveau_cli *cli,
365 u32 parent, u32 handle, u32 vram, u32 gart, 368 u32 parent, u32 handle, u32 arg0, u32 arg1,
366 struct nouveau_channel **pchan) 369 struct nouveau_channel **pchan)
367{ 370{
368 int ret; 371 int ret;
369 372
370 ret = nouveau_channel_ind(drm, cli, parent, handle, pchan); 373 ret = nouveau_channel_ind(drm, cli, parent, handle, arg0, pchan);
371 if (ret) { 374 if (ret) {
372 NV_DEBUG(drm, "ib channel create, %d\n", ret); 375 NV_DEBUG(drm, "ib channel create, %d\n", ret);
373 ret = nouveau_channel_dma(drm, cli, parent, handle, pchan); 376 ret = nouveau_channel_dma(drm, cli, parent, handle, pchan);
@@ -377,7 +380,7 @@ nouveau_channel_new(struct nouveau_drm *drm, struct nouveau_cli *cli,
377 } 380 }
378 } 381 }
379 382
380 ret = nouveau_channel_init(*pchan, vram, gart); 383 ret = nouveau_channel_init(*pchan, arg0, arg1);
381 if (ret) { 384 if (ret) {
382 NV_ERROR(drm, "channel failed to initialise, %d\n", ret); 385 NV_ERROR(drm, "channel failed to initialise, %d\n", ret);
383 nouveau_channel_del(pchan); 386 nouveau_channel_del(pchan);
diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.h b/drivers/gpu/drm/nouveau/nouveau_chan.h
index 0fa94244bed1..40f97e2c47b6 100644
--- a/drivers/gpu/drm/nouveau/nouveau_chan.h
+++ b/drivers/gpu/drm/nouveau/nouveau_chan.h
@@ -39,7 +39,7 @@ struct nouveau_channel {
39 39
40 40
41int nouveau_channel_new(struct nouveau_drm *, struct nouveau_cli *, 41int nouveau_channel_new(struct nouveau_drm *, struct nouveau_cli *,
42 u32 parent, u32 handle, u32 vram, u32 gart, 42 u32 parent, u32 handle, u32 arg0, u32 arg1,
43 struct nouveau_channel **); 43 struct nouveau_channel **);
44void nouveau_channel_del(struct nouveau_channel **); 44void nouveau_channel_del(struct nouveau_channel **);
45int nouveau_channel_idle(struct nouveau_channel *); 45int nouveau_channel_idle(struct nouveau_channel *);
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c
index 8b508cec65a2..4dfc40e3dabe 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.c
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.c
@@ -109,6 +109,7 @@ nouveau_accel_fini(struct nouveau_drm *drm)
109{ 109{
110 nouveau_gpuobj_ref(NULL, &drm->notify); 110 nouveau_gpuobj_ref(NULL, &drm->notify);
111 nouveau_channel_del(&drm->channel); 111 nouveau_channel_del(&drm->channel);
112 nouveau_channel_del(&drm->cechan);
112 if (drm->fence) 113 if (drm->fence)
113 nouveau_fence(drm)->dtor(drm); 114 nouveau_fence(drm)->dtor(drm);
114} 115}
@@ -118,6 +119,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
118{ 119{
119 struct nouveau_device *device = nv_device(drm->device); 120 struct nouveau_device *device = nv_device(drm->device);
120 struct nouveau_object *object; 121 struct nouveau_object *object;
122 u32 arg0, arg1;
121 int ret; 123 int ret;
122 124
123 if (nouveau_noaccel) 125 if (nouveau_noaccel)
@@ -134,8 +136,24 @@ nouveau_accel_init(struct nouveau_drm *drm)
134 return; 136 return;
135 } 137 }
136 138
139 if (device->card_type >= NV_E0) {
140 ret = nouveau_channel_new(drm, &drm->client, NVDRM_DEVICE,
141 NVDRM_CHAN + 1,
142 NVE0_CHANNEL_IND_ENGINE_CE0 |
143 NVE0_CHANNEL_IND_ENGINE_CE1, 0,
144 &drm->cechan);
145 if (ret)
146 NV_ERROR(drm, "failed to create ce channel, %d\n", ret);
147
148 arg0 = NVE0_CHANNEL_IND_ENGINE_GR;
149 arg1 = 0;
150 } else {
151 arg0 = NvDmaFB;
152 arg1 = NvDmaTT;
153 }
154
137 ret = nouveau_channel_new(drm, &drm->client, NVDRM_DEVICE, NVDRM_CHAN, 155 ret = nouveau_channel_new(drm, &drm->client, NVDRM_DEVICE, NVDRM_CHAN,
138 NvDmaFB, NvDmaTT, &drm->channel); 156 arg0, arg1, &drm->channel);
139 if (ret) { 157 if (ret) {
140 NV_ERROR(drm, "failed to create kernel channel, %d\n", ret); 158 NV_ERROR(drm, "failed to create kernel channel, %d\n", ret);
141 nouveau_accel_fini(drm); 159 nouveau_accel_fini(drm);
@@ -167,7 +185,7 @@ nouveau_accel_init(struct nouveau_drm *drm)
167 } 185 }
168 186
169 187
170 nouveau_bo_move_init(drm->channel); 188 nouveau_bo_move_init(drm);
171} 189}
172 190
173static int __devinit 191static int __devinit
diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h
index 6abd1a15e742..ab0c17430c66 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drm.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drm.h
@@ -97,6 +97,7 @@ struct nouveau_drm {
97 void *fence; 97 void *fence;
98 98
99 /* context for accelerated drm-internal operations */ 99 /* context for accelerated drm-internal operations */
100 struct nouveau_channel *cechan;
100 struct nouveau_channel *channel; 101 struct nouveau_channel *channel;
101 struct nouveau_gpuobj *notify; 102 struct nouveau_gpuobj *notify;
102 struct nouveau_fbdev *fbcon; 103 struct nouveau_fbdev *fbcon;