summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/mm_gk20a.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/mm_gk20a.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/mm_gk20a.c71
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
122static void gk20a_vm_remove_support_nofree(struct vm_gk20a *vm); 127static 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
209u64 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
222void 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
234static 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
244static 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
201void gk20a_get_comptags(struct device *dev, struct dma_buf *dmabuf, 260void 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
791u64 gk20a_vm_alloc_va(struct vm_gk20a *vm, 858u64 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 }