aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@riseup.net>2009-12-25 20:42:45 -0500
committerDave Airlie <airlied@redhat.com>2010-01-10 23:41:11 -0500
commitca4362adb4c01807dfcf3f2b3152a7ee36f0d1ca (patch)
tree44129f4769ee7950d45bb1f6680418c265352b94 /drivers/gpu
parent0a2d090f99c9686e5107ed59533fc4210a9a47d1 (diff)
drm/nouveau: Allocate a per-channel instance of NV_SW.
It will be useful for various synchronization purposes, mostly stolen from "[PATCH] drm/nv50: synchronize user channel after buffer object move on kernel channel" by Maarten Maathuis. Signed-off-by: Francisco Jerez <currojerez@riseup.net>
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_channel.c4
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dma.c17
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_dma.h10
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_drv.h20
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_object.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv04_fbcon.c19
6 files changed, 48 insertions, 24 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c
index 9aaa972f8822..4f378b68fe7b 100644
--- a/drivers/gpu/drm/nouveau/nouveau_channel.c
+++ b/drivers/gpu/drm/nouveau/nouveau_channel.c
@@ -414,7 +414,9 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data,
414 init->subchan[0].grclass = 0x0039; 414 init->subchan[0].grclass = 0x0039;
415 else 415 else
416 init->subchan[0].grclass = 0x5039; 416 init->subchan[0].grclass = 0x5039;
417 init->nr_subchan = 1; 417 init->subchan[1].handle = NvSw;
418 init->subchan[1].grclass = NV_SW;
419 init->nr_subchan = 2;
418 420
419 /* Named memory object area */ 421 /* Named memory object area */
420 ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem, 422 ret = drm_gem_handle_create(file_priv, chan->notifier_bo->gem,
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c
index 703553687b20..f1fd3f2b9813 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dma.c
+++ b/drivers/gpu/drm/nouveau/nouveau_dma.c
@@ -35,6 +35,7 @@ nouveau_dma_init(struct nouveau_channel *chan)
35 struct drm_device *dev = chan->dev; 35 struct drm_device *dev = chan->dev;
36 struct drm_nouveau_private *dev_priv = dev->dev_private; 36 struct drm_nouveau_private *dev_priv = dev->dev_private;
37 struct nouveau_gpuobj *m2mf = NULL; 37 struct nouveau_gpuobj *m2mf = NULL;
38 struct nouveau_gpuobj *nvsw = NULL;
38 int ret, i; 39 int ret, i;
39 40
40 /* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */ 41 /* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */
@@ -47,6 +48,15 @@ nouveau_dma_init(struct nouveau_channel *chan)
47 if (ret) 48 if (ret)
48 return ret; 49 return ret;
49 50
51 /* Create an NV_SW object for various sync purposes */
52 ret = nouveau_gpuobj_sw_new(chan, NV_SW, &nvsw);
53 if (ret)
54 return ret;
55
56 ret = nouveau_gpuobj_ref_add(dev, chan, NvSw, nvsw, NULL);
57 if (ret)
58 return ret;
59
50 /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */ 60 /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */
51 ret = nouveau_notifier_alloc(chan, NvNotify0, 32, &chan->m2mf_ntfy); 61 ret = nouveau_notifier_alloc(chan, NvNotify0, 32, &chan->m2mf_ntfy);
52 if (ret) 62 if (ret)
@@ -87,6 +97,13 @@ nouveau_dma_init(struct nouveau_channel *chan)
87 BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); 97 BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1);
88 OUT_RING(chan, NvNotify0); 98 OUT_RING(chan, NvNotify0);
89 99
100 /* Initialise NV_SW */
101 ret = RING_SPACE(chan, 2);
102 if (ret)
103 return ret;
104 BEGIN_RING(chan, NvSubSw, 0, 1);
105 OUT_RING(chan, NvSw);
106
90 /* Sit back and pray the channel works.. */ 107 /* Sit back and pray the channel works.. */
91 FIRE_RING(chan); 108 FIRE_RING(chan);
92 109
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h
index 04e85d8f757e..dabfd655f93e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_dma.h
+++ b/drivers/gpu/drm/nouveau/nouveau_dma.h
@@ -46,10 +46,11 @@
46/* Hardcoded object assignments to subchannels (subchannel id). */ 46/* Hardcoded object assignments to subchannels (subchannel id). */
47enum { 47enum {
48 NvSubM2MF = 0, 48 NvSubM2MF = 0,
49 NvSub2D = 1, 49 NvSubSw = 1,
50 NvSubCtxSurf2D = 1, 50 NvSub2D = 2,
51 NvSubGdiRect = 2, 51 NvSubCtxSurf2D = 2,
52 NvSubImageBlit = 3 52 NvSubGdiRect = 3,
53 NvSubImageBlit = 4
53}; 54};
54 55
55/* Object handles. */ 56/* Object handles. */
@@ -67,6 +68,7 @@ enum {
67 NvClipRect = 0x8000000b, 68 NvClipRect = 0x8000000b,
68 NvGdiRect = 0x8000000c, 69 NvGdiRect = 0x8000000c,
69 NvImageBlit = 0x8000000d, 70 NvImageBlit = 0x8000000d,
71 NvSw = 0x8000000e,
70 72
71 /* G80+ display objects */ 73 /* G80+ display objects */
72 NvEvoVRAM = 0x01000000, 74 NvEvoVRAM = 0x01000000,
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h
index 7da88a92c83f..9181eaefe918 100644
--- a/drivers/gpu/drm/nouveau/nouveau_drv.h
+++ b/drivers/gpu/drm/nouveau/nouveau_drv.h
@@ -788,6 +788,8 @@ extern int nouveau_gpuobj_gart_dma_new(struct nouveau_channel *,
788 uint32_t *o_ret); 788 uint32_t *o_ret);
789extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class, 789extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class,
790 struct nouveau_gpuobj **); 790 struct nouveau_gpuobj **);
791extern int nouveau_gpuobj_sw_new(struct nouveau_channel *, int class,
792 struct nouveau_gpuobj **);
791extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data, 793extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data,
792 struct drm_file *); 794 struct drm_file *);
793extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data, 795extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data,
@@ -1330,14 +1332,14 @@ nv_two_reg_pll(struct drm_device *dev)
1330 return false; 1332 return false;
1331} 1333}
1332 1334
1333#define NV50_NVSW 0x0000506e 1335#define NV_SW 0x0000506e
1334#define NV50_NVSW_DMA_SEMAPHORE 0x00000060 1336#define NV_SW_DMA_SEMAPHORE 0x00000060
1335#define NV50_NVSW_SEMAPHORE_OFFSET 0x00000064 1337#define NV_SW_SEMAPHORE_OFFSET 0x00000064
1336#define NV50_NVSW_SEMAPHORE_ACQUIRE 0x00000068 1338#define NV_SW_SEMAPHORE_ACQUIRE 0x00000068
1337#define NV50_NVSW_SEMAPHORE_RELEASE 0x0000006c 1339#define NV_SW_SEMAPHORE_RELEASE 0x0000006c
1338#define NV50_NVSW_DMA_VBLSEM 0x0000018c 1340#define NV_SW_DMA_VBLSEM 0x0000018c
1339#define NV50_NVSW_VBLSEM_OFFSET 0x00000400 1341#define NV_SW_VBLSEM_OFFSET 0x00000400
1340#define NV50_NVSW_VBLSEM_RELEASE_VALUE 0x00000404 1342#define NV_SW_VBLSEM_RELEASE_VALUE 0x00000404
1341#define NV50_NVSW_VBLSEM_RELEASE 0x00000408 1343#define NV_SW_VBLSEM_RELEASE 0x00000408
1342 1344
1343#endif /* __NOUVEAU_DRV_H__ */ 1345#endif /* __NOUVEAU_DRV_H__ */
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c
index 93379bb81bea..6c2cf81716df 100644
--- a/drivers/gpu/drm/nouveau/nouveau_object.c
+++ b/drivers/gpu/drm/nouveau/nouveau_object.c
@@ -881,7 +881,7 @@ nouveau_gpuobj_gr_new(struct nouveau_channel *chan, int class,
881 return 0; 881 return 0;
882} 882}
883 883
884static int 884int
885nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, 885nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class,
886 struct nouveau_gpuobj **gpuobj_ret) 886 struct nouveau_gpuobj **gpuobj_ret)
887{ 887{
diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c
index 09a31071ee58..d2d7f0838dc9 100644
--- a/drivers/gpu/drm/nouveau/nv04_fbcon.c
+++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c
@@ -184,6 +184,7 @@ nv04_fbcon_accel_init(struct fb_info *info)
184 struct drm_device *dev = par->dev; 184 struct drm_device *dev = par->dev;
185 struct drm_nouveau_private *dev_priv = dev->dev_private; 185 struct drm_nouveau_private *dev_priv = dev->dev_private;
186 struct nouveau_channel *chan = dev_priv->channel; 186 struct nouveau_channel *chan = dev_priv->channel;
187 const int sub = NvSubCtxSurf2D;
187 int surface_fmt, pattern_fmt, rect_fmt; 188 int surface_fmt, pattern_fmt, rect_fmt;
188 int ret; 189 int ret;
189 190
@@ -247,25 +248,25 @@ nv04_fbcon_accel_init(struct fb_info *info)
247 return 0; 248 return 0;
248 } 249 }
249 250
250 BEGIN_RING(chan, 1, 0x0000, 1); 251 BEGIN_RING(chan, sub, 0x0000, 1);
251 OUT_RING(chan, NvCtxSurf2D); 252 OUT_RING(chan, NvCtxSurf2D);
252 BEGIN_RING(chan, 1, 0x0184, 2); 253 BEGIN_RING(chan, sub, 0x0184, 2);
253 OUT_RING(chan, NvDmaFB); 254 OUT_RING(chan, NvDmaFB);
254 OUT_RING(chan, NvDmaFB); 255 OUT_RING(chan, NvDmaFB);
255 BEGIN_RING(chan, 1, 0x0300, 4); 256 BEGIN_RING(chan, sub, 0x0300, 4);
256 OUT_RING(chan, surface_fmt); 257 OUT_RING(chan, surface_fmt);
257 OUT_RING(chan, info->fix.line_length | (info->fix.line_length << 16)); 258 OUT_RING(chan, info->fix.line_length | (info->fix.line_length << 16));
258 OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base); 259 OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base);
259 OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base); 260 OUT_RING(chan, info->fix.smem_start - dev->mode_config.fb_base);
260 261
261 BEGIN_RING(chan, 1, 0x0000, 1); 262 BEGIN_RING(chan, sub, 0x0000, 1);
262 OUT_RING(chan, NvRop); 263 OUT_RING(chan, NvRop);
263 BEGIN_RING(chan, 1, 0x0300, 1); 264 BEGIN_RING(chan, sub, 0x0300, 1);
264 OUT_RING(chan, 0x55); 265 OUT_RING(chan, 0x55);
265 266
266 BEGIN_RING(chan, 1, 0x0000, 1); 267 BEGIN_RING(chan, sub, 0x0000, 1);
267 OUT_RING(chan, NvImagePatt); 268 OUT_RING(chan, NvImagePatt);
268 BEGIN_RING(chan, 1, 0x0300, 8); 269 BEGIN_RING(chan, sub, 0x0300, 8);
269 OUT_RING(chan, pattern_fmt); 270 OUT_RING(chan, pattern_fmt);
270#ifdef __BIG_ENDIAN 271#ifdef __BIG_ENDIAN
271 OUT_RING(chan, 2); 272 OUT_RING(chan, 2);
@@ -279,9 +280,9 @@ nv04_fbcon_accel_init(struct fb_info *info)
279 OUT_RING(chan, ~0); 280 OUT_RING(chan, ~0);
280 OUT_RING(chan, ~0); 281 OUT_RING(chan, ~0);
281 282
282 BEGIN_RING(chan, 1, 0x0000, 1); 283 BEGIN_RING(chan, sub, 0x0000, 1);
283 OUT_RING(chan, NvClipRect); 284 OUT_RING(chan, NvClipRect);
284 BEGIN_RING(chan, 1, 0x0300, 2); 285 BEGIN_RING(chan, sub, 0x0300, 2);
285 OUT_RING(chan, 0); 286 OUT_RING(chan, 0);
286 OUT_RING(chan, (info->var.yres_virtual << 16) | info->var.xres_virtual); 287 OUT_RING(chan, (info->var.yres_virtual << 16) | info->var.xres_virtual);
287 288