diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_notifier.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_notifier.c | 44 |
1 files changed, 16 insertions, 28 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_notifier.c b/drivers/gpu/drm/nouveau/nouveau_notifier.c index 2cc59f8c658b..fe29d604b820 100644 --- a/drivers/gpu/drm/nouveau/nouveau_notifier.c +++ b/drivers/gpu/drm/nouveau/nouveau_notifier.c | |||
@@ -99,7 +99,6 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, | |||
99 | int size, uint32_t *b_offset) | 99 | int size, uint32_t *b_offset) |
100 | { | 100 | { |
101 | struct drm_device *dev = chan->dev; | 101 | struct drm_device *dev = chan->dev; |
102 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
103 | struct nouveau_gpuobj *nobj = NULL; | 102 | struct nouveau_gpuobj *nobj = NULL; |
104 | struct drm_mm_node *mem; | 103 | struct drm_mm_node *mem; |
105 | uint32_t offset; | 104 | uint32_t offset; |
@@ -113,31 +112,15 @@ nouveau_notifier_alloc(struct nouveau_channel *chan, uint32_t handle, | |||
113 | return -ENOMEM; | 112 | return -ENOMEM; |
114 | } | 113 | } |
115 | 114 | ||
116 | offset = chan->notifier_bo->bo.mem.start << PAGE_SHIFT; | 115 | if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_VRAM) |
117 | if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_VRAM) { | 116 | target = NV_MEM_TARGET_VRAM; |
118 | target = NV_DMA_TARGET_VIDMEM; | 117 | else |
119 | } else | 118 | target = NV_MEM_TARGET_GART; |
120 | if (chan->notifier_bo->bo.mem.mem_type == TTM_PL_TT) { | 119 | offset = chan->notifier_bo->bo.mem.start << PAGE_SHIFT; |
121 | if (dev_priv->gart_info.type == NOUVEAU_GART_SGDMA && | ||
122 | dev_priv->card_type < NV_50) { | ||
123 | ret = nouveau_sgdma_get_page(dev, offset, &offset); | ||
124 | if (ret) | ||
125 | return ret; | ||
126 | target = NV_DMA_TARGET_PCI; | ||
127 | } else { | ||
128 | target = NV_DMA_TARGET_AGP; | ||
129 | if (dev_priv->card_type >= NV_50) | ||
130 | offset += dev_priv->vm_gart_base; | ||
131 | } | ||
132 | } else { | ||
133 | NV_ERROR(dev, "Bad DMA target, mem_type %d!\n", | ||
134 | chan->notifier_bo->bo.mem.mem_type); | ||
135 | return -EINVAL; | ||
136 | } | ||
137 | offset += mem->start; | 120 | offset += mem->start; |
138 | 121 | ||
139 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, offset, | 122 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, offset, |
140 | mem->size, NV_DMA_ACCESS_RW, target, | 123 | mem->size, NV_MEM_ACCESS_RW, target, |
141 | &nobj); | 124 | &nobj); |
142 | if (ret) { | 125 | if (ret) { |
143 | drm_mm_put_block(mem); | 126 | drm_mm_put_block(mem); |
@@ -181,15 +164,20 @@ int | |||
181 | nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, | 164 | nouveau_ioctl_notifier_alloc(struct drm_device *dev, void *data, |
182 | struct drm_file *file_priv) | 165 | struct drm_file *file_priv) |
183 | { | 166 | { |
167 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
184 | struct drm_nouveau_notifierobj_alloc *na = data; | 168 | struct drm_nouveau_notifierobj_alloc *na = data; |
185 | struct nouveau_channel *chan; | 169 | struct nouveau_channel *chan; |
186 | int ret; | 170 | int ret; |
187 | 171 | ||
188 | NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(na->channel, file_priv, chan); | 172 | /* completely unnecessary for these chipsets... */ |
173 | if (unlikely(dev_priv->card_type >= NV_C0)) | ||
174 | return -EINVAL; | ||
175 | |||
176 | chan = nouveau_channel_get(dev, file_priv, na->channel); | ||
177 | if (IS_ERR(chan)) | ||
178 | return PTR_ERR(chan); | ||
189 | 179 | ||
190 | ret = nouveau_notifier_alloc(chan, na->handle, na->size, &na->offset); | 180 | ret = nouveau_notifier_alloc(chan, na->handle, na->size, &na->offset); |
191 | if (ret) | 181 | nouveau_channel_put(&chan); |
192 | return ret; | 182 | return ret; |
193 | |||
194 | return 0; | ||
195 | } | 183 | } |