diff options
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/mm_gk20a.c')
-rw-r--r-- | drivers/gpu/nvgpu/gk20a/mm_gk20a.c | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c index d8bd3e70..79bfb687 100644 --- a/drivers/gpu/nvgpu/gk20a/mm_gk20a.c +++ b/drivers/gpu/nvgpu/gk20a/mm_gk20a.c | |||
@@ -117,6 +117,11 @@ struct gk20a_dmabuf_priv { | |||
117 | int pin_count; | 117 | int pin_count; |
118 | 118 | ||
119 | struct list_head states; | 119 | struct list_head states; |
120 | |||
121 | /* cached cde compbits buf */ | ||
122 | struct vm_gk20a *cde_vm; | ||
123 | u64 cde_map_vaddr; | ||
124 | int map_count; | ||
120 | }; | 125 | }; |
121 | 126 | ||
122 | static void gk20a_vm_remove_support_nofree(struct vm_gk20a *vm); | 127 | static void gk20a_vm_remove_support_nofree(struct vm_gk20a *vm); |
@@ -198,6 +203,60 @@ void gk20a_mm_unpin(struct device *dev, struct dma_buf *dmabuf, | |||
198 | mutex_unlock(&priv->lock); | 203 | mutex_unlock(&priv->lock); |
199 | } | 204 | } |
200 | 205 | ||
206 | /* CDE compbits buf caching: keep compbit buffer mapped during user mappings. | ||
207 | * Call these four only after dma_buf has a drvdata allocated */ | ||
208 | |||
209 | u64 gk20a_vm_cde_mapped(struct vm_gk20a *vm, struct dma_buf *dmabuf) | ||
210 | { | ||
211 | struct device *dev = dev_from_vm(vm); | ||
212 | struct gk20a_dmabuf_priv *priv = dma_buf_get_drvdata(dmabuf, dev); | ||
213 | u64 map_vaddr; | ||
214 | |||
215 | mutex_lock(&priv->lock); | ||
216 | map_vaddr = priv->cde_map_vaddr; | ||
217 | mutex_unlock(&priv->lock); | ||
218 | |||
219 | return map_vaddr; | ||
220 | } | ||
221 | |||
222 | void gk20a_vm_mark_cde_mapped(struct vm_gk20a *vm, struct dma_buf *dmabuf, | ||
223 | u64 map_vaddr) | ||
224 | { | ||
225 | struct device *dev = dev_from_vm(vm); | ||
226 | struct gk20a_dmabuf_priv *priv = dma_buf_get_drvdata(dmabuf, dev); | ||
227 | |||
228 | mutex_lock(&priv->lock); | ||
229 | priv->cde_vm = vm; | ||
230 | priv->cde_map_vaddr = map_vaddr; | ||
231 | mutex_unlock(&priv->lock); | ||
232 | } | ||
233 | |||
234 | static void gk20a_vm_inc_maps(struct vm_gk20a *vm, struct dma_buf *dmabuf) | ||
235 | { | ||
236 | struct device *dev = dev_from_vm(vm); | ||
237 | struct gk20a_dmabuf_priv *priv = dma_buf_get_drvdata(dmabuf, dev); | ||
238 | |||
239 | mutex_lock(&priv->lock); | ||
240 | priv->map_count++; | ||
241 | mutex_unlock(&priv->lock); | ||
242 | } | ||
243 | |||
244 | static void gk20a_vm_dec_maps(struct vm_gk20a *vm, struct dma_buf *dmabuf, | ||
245 | struct vm_gk20a **cde_vm, u64 *cde_map_vaddr) | ||
246 | { | ||
247 | struct device *dev = dev_from_vm(vm); | ||
248 | struct gk20a_dmabuf_priv *priv = dma_buf_get_drvdata(dmabuf, dev); | ||
249 | |||
250 | mutex_lock(&priv->lock); | ||
251 | if (--priv->map_count == 0) { | ||
252 | *cde_vm = priv->cde_vm; | ||
253 | *cde_map_vaddr = priv->cde_map_vaddr; | ||
254 | priv->cde_vm = NULL; | ||
255 | priv->cde_map_vaddr = 0; | ||
256 | } | ||
257 | mutex_unlock(&priv->lock); | ||
258 | } | ||
259 | |||
201 | void gk20a_get_comptags(struct device *dev, struct dma_buf *dmabuf, | 260 | void gk20a_get_comptags(struct device *dev, struct dma_buf *dmabuf, |
202 | struct gk20a_comptags *comptags) | 261 | struct gk20a_comptags *comptags) |
203 | { | 262 | { |
@@ -751,6 +810,8 @@ static void gk20a_vm_unmap_user(struct vm_gk20a *vm, u64 offset) | |||
751 | struct device *d = dev_from_vm(vm); | 810 | struct device *d = dev_from_vm(vm); |
752 | int retries; | 811 | int retries; |
753 | struct mapped_buffer_node *mapped_buffer; | 812 | struct mapped_buffer_node *mapped_buffer; |
813 | struct vm_gk20a *cde_vm = NULL; | ||
814 | u64 cde_map_vaddr = 0; | ||
754 | 815 | ||
755 | mutex_lock(&vm->update_gmmu_lock); | 816 | mutex_lock(&vm->update_gmmu_lock); |
756 | 817 | ||
@@ -783,9 +844,15 @@ static void gk20a_vm_unmap_user(struct vm_gk20a *vm, u64 offset) | |||
783 | mapped_buffer->user_mapped--; | 844 | mapped_buffer->user_mapped--; |
784 | if (mapped_buffer->user_mapped == 0) | 845 | if (mapped_buffer->user_mapped == 0) |
785 | vm->num_user_mapped_buffers--; | 846 | vm->num_user_mapped_buffers--; |
847 | |||
848 | gk20a_vm_dec_maps(vm, mapped_buffer->dmabuf, &cde_vm, &cde_map_vaddr); | ||
849 | |||
786 | kref_put(&mapped_buffer->ref, gk20a_vm_unmap_locked_kref); | 850 | kref_put(&mapped_buffer->ref, gk20a_vm_unmap_locked_kref); |
787 | 851 | ||
788 | mutex_unlock(&vm->update_gmmu_lock); | 852 | mutex_unlock(&vm->update_gmmu_lock); |
853 | |||
854 | if (cde_map_vaddr) | ||
855 | gk20a_vm_unmap(cde_vm, cde_map_vaddr); | ||
789 | } | 856 | } |
790 | 857 | ||
791 | u64 gk20a_vm_alloc_va(struct vm_gk20a *vm, | 858 | u64 gk20a_vm_alloc_va(struct vm_gk20a *vm, |
@@ -2599,7 +2666,9 @@ int gk20a_vm_map_buffer(struct vm_gk20a *vm, | |||
2599 | mapping_size); | 2666 | mapping_size); |
2600 | 2667 | ||
2601 | *offset_align = ret_va; | 2668 | *offset_align = ret_va; |
2602 | if (!ret_va) { | 2669 | if (ret_va) { |
2670 | gk20a_vm_inc_maps(vm, dmabuf); | ||
2671 | } else { | ||
2603 | dma_buf_put(dmabuf); | 2672 | dma_buf_put(dmabuf); |
2604 | err = -EINVAL; | 2673 | err = -EINVAL; |
2605 | } | 2674 | } |