diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_dma.c')
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_dma.c | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index 703553687b20..7afbe8b40d51 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c | |||
| @@ -29,12 +29,22 @@ | |||
| 29 | #include "nouveau_drv.h" | 29 | #include "nouveau_drv.h" |
| 30 | #include "nouveau_dma.h" | 30 | #include "nouveau_dma.h" |
| 31 | 31 | ||
| 32 | void | ||
| 33 | nouveau_dma_pre_init(struct nouveau_channel *chan) | ||
| 34 | { | ||
| 35 | chan->dma.max = (chan->pushbuf_bo->bo.mem.size >> 2) - 2; | ||
| 36 | chan->dma.put = 0; | ||
| 37 | chan->dma.cur = chan->dma.put; | ||
| 38 | chan->dma.free = chan->dma.max - chan->dma.cur; | ||
| 39 | } | ||
| 40 | |||
| 32 | int | 41 | int |
| 33 | nouveau_dma_init(struct nouveau_channel *chan) | 42 | nouveau_dma_init(struct nouveau_channel *chan) |
| 34 | { | 43 | { |
| 35 | struct drm_device *dev = chan->dev; | 44 | struct drm_device *dev = chan->dev; |
| 36 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 45 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 37 | struct nouveau_gpuobj *m2mf = NULL; | 46 | struct nouveau_gpuobj *m2mf = NULL; |
| 47 | struct nouveau_gpuobj *nvsw = NULL; | ||
| 38 | int ret, i; | 48 | int ret, i; |
| 39 | 49 | ||
| 40 | /* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */ | 50 | /* Create NV_MEMORY_TO_MEMORY_FORMAT for buffer moves */ |
| @@ -47,6 +57,15 @@ nouveau_dma_init(struct nouveau_channel *chan) | |||
| 47 | if (ret) | 57 | if (ret) |
| 48 | return ret; | 58 | return ret; |
| 49 | 59 | ||
| 60 | /* Create an NV_SW object for various sync purposes */ | ||
| 61 | ret = nouveau_gpuobj_sw_new(chan, NV_SW, &nvsw); | ||
| 62 | if (ret) | ||
| 63 | return ret; | ||
| 64 | |||
| 65 | ret = nouveau_gpuobj_ref_add(dev, chan, NvSw, nvsw, NULL); | ||
| 66 | if (ret) | ||
| 67 | return ret; | ||
| 68 | |||
| 50 | /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */ | 69 | /* NV_MEMORY_TO_MEMORY_FORMAT requires a notifier object */ |
| 51 | ret = nouveau_notifier_alloc(chan, NvNotify0, 32, &chan->m2mf_ntfy); | 70 | ret = nouveau_notifier_alloc(chan, NvNotify0, 32, &chan->m2mf_ntfy); |
| 52 | if (ret) | 71 | if (ret) |
| @@ -64,12 +83,6 @@ nouveau_dma_init(struct nouveau_channel *chan) | |||
| 64 | return ret; | 83 | return ret; |
| 65 | } | 84 | } |
| 66 | 85 | ||
| 67 | /* Initialise DMA vars */ | ||
| 68 | chan->dma.max = (chan->pushbuf_bo->bo.mem.size >> 2) - 2; | ||
| 69 | chan->dma.put = 0; | ||
| 70 | chan->dma.cur = chan->dma.put; | ||
| 71 | chan->dma.free = chan->dma.max - chan->dma.cur; | ||
| 72 | |||
| 73 | /* Insert NOPS for NOUVEAU_DMA_SKIPS */ | 86 | /* Insert NOPS for NOUVEAU_DMA_SKIPS */ |
| 74 | ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS); | 87 | ret = RING_SPACE(chan, NOUVEAU_DMA_SKIPS); |
| 75 | if (ret) | 88 | if (ret) |
| @@ -87,6 +100,13 @@ nouveau_dma_init(struct nouveau_channel *chan) | |||
| 87 | BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); | 100 | BEGIN_RING(chan, NvSubM2MF, NV_MEMORY_TO_MEMORY_FORMAT_DMA_NOTIFY, 1); |
| 88 | OUT_RING(chan, NvNotify0); | 101 | OUT_RING(chan, NvNotify0); |
| 89 | 102 | ||
| 103 | /* Initialise NV_SW */ | ||
| 104 | ret = RING_SPACE(chan, 2); | ||
| 105 | if (ret) | ||
| 106 | return ret; | ||
| 107 | BEGIN_RING(chan, NvSubSw, 0, 1); | ||
| 108 | OUT_RING(chan, NvSw); | ||
| 109 | |||
| 90 | /* Sit back and pray the channel works.. */ | 110 | /* Sit back and pray the channel works.. */ |
| 91 | FIRE_RING(chan); | 111 | FIRE_RING(chan); |
| 92 | 112 | ||
| @@ -113,7 +133,7 @@ READ_GET(struct nouveau_channel *chan, uint32_t *get) | |||
| 113 | 133 | ||
| 114 | val = nvchan_rd32(chan, chan->user_get); | 134 | val = nvchan_rd32(chan, chan->user_get); |
| 115 | if (val < chan->pushbuf_base || | 135 | if (val < chan->pushbuf_base || |
| 116 | val >= chan->pushbuf_base + chan->pushbuf_bo->bo.mem.size) { | 136 | val > chan->pushbuf_base + (chan->dma.max << 2)) { |
| 117 | /* meaningless to dma_wait() except to know whether the | 137 | /* meaningless to dma_wait() except to know whether the |
| 118 | * GPU has stalled or not | 138 | * GPU has stalled or not |
| 119 | */ | 139 | */ |
