diff options
author | Francisco Jerez <currojerez@riseup.net> | 2009-12-25 20:42:45 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2010-01-10 23:41:11 -0500 |
commit | ca4362adb4c01807dfcf3f2b3152a7ee36f0d1ca (patch) | |
tree | 44129f4769ee7950d45bb1f6680418c265352b94 /drivers/gpu | |
parent | 0a2d090f99c9686e5107ed59533fc4210a9a47d1 (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.c | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_dma.c | 17 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_dma.h | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_drv.h | 20 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_object.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv04_fbcon.c | 19 |
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). */ |
47 | enum { | 47 | enum { |
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); |
789 | extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class, | 789 | extern int nouveau_gpuobj_gr_new(struct nouveau_channel *, int class, |
790 | struct nouveau_gpuobj **); | 790 | struct nouveau_gpuobj **); |
791 | extern int nouveau_gpuobj_sw_new(struct nouveau_channel *, int class, | ||
792 | struct nouveau_gpuobj **); | ||
791 | extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data, | 793 | extern int nouveau_ioctl_grobj_alloc(struct drm_device *, void *data, |
792 | struct drm_file *); | 794 | struct drm_file *); |
793 | extern int nouveau_ioctl_gpuobj_free(struct drm_device *, void *data, | 795 | extern 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 | ||
884 | static int | 884 | int |
885 | nouveau_gpuobj_sw_new(struct nouveau_channel *chan, int class, | 885 | nouveau_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 | ||