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 | |
| 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>
| -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 | ||
