summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/tegra/host/chip_support.h2
-rw-r--r--drivers/video/tegra/host/host1x/host1x_vm_t186.c4
-rw-r--r--drivers/video/tegra/host/iommu_context_dev.c51
-rw-r--r--drivers/video/tegra/host/iommu_context_dev.h2
-rw-r--r--drivers/video/tegra/host/nvhost_vm.c2
5 files changed, 51 insertions, 10 deletions
diff --git a/drivers/video/tegra/host/chip_support.h b/drivers/video/tegra/host/chip_support.h
index 23fcf6f39..1fcd53c15 100644
--- a/drivers/video/tegra/host/chip_support.h
+++ b/drivers/video/tegra/host/chip_support.h
@@ -65,7 +65,7 @@ struct nvhost_cdma_ops {
65}; 65};
66 66
67struct nvhost_vm_ops { 67struct nvhost_vm_ops {
68 int (*init)(struct nvhost_vm *vm); 68 int (*init)(struct nvhost_vm *vm, void *identifier);
69 void (*deinit)(struct nvhost_vm *vm); 69 void (*deinit)(struct nvhost_vm *vm);
70 int (*pin_static_buffer)(struct platform_device *pdev, 70 int (*pin_static_buffer)(struct platform_device *pdev,
71 void *vaddr, dma_addr_t paddr, 71 void *vaddr, dma_addr_t paddr,
diff --git a/drivers/video/tegra/host/host1x/host1x_vm_t186.c b/drivers/video/tegra/host/host1x/host1x_vm_t186.c
index 65f0742c6..c198ec84e 100644
--- a/drivers/video/tegra/host/host1x/host1x_vm_t186.c
+++ b/drivers/video/tegra/host/host1x/host1x_vm_t186.c
@@ -27,14 +27,14 @@
27/* 5 second timeout */ 27/* 5 second timeout */
28#define NVHOST_VM_WAIT_TIMEOUT (5000) 28#define NVHOST_VM_WAIT_TIMEOUT (5000)
29 29
30static int host1x_vm_init(struct nvhost_vm *vm) 30static int host1x_vm_init(struct nvhost_vm *vm, void *identifier)
31{ 31{
32 struct platform_device *pdev; 32 struct platform_device *pdev;
33 unsigned int i = 0; 33 unsigned int i = 0;
34 34
35 /* wait until we have a context device */ 35 /* wait until we have a context device */
36 do { 36 do {
37 pdev = iommu_context_dev_allocate(); 37 pdev = iommu_context_dev_allocate(identifier);
38 if (!pdev) { 38 if (!pdev) {
39 ++i; 39 ++i;
40 mdelay(1); 40 mdelay(1);
diff --git a/drivers/video/tegra/host/iommu_context_dev.c b/drivers/video/tegra/host/iommu_context_dev.c
index ead02e9dd..af9de61f3 100644
--- a/drivers/video/tegra/host/iommu_context_dev.c
+++ b/drivers/video/tegra/host/iommu_context_dev.c
@@ -47,24 +47,65 @@ struct iommu_ctx {
47 struct list_head list; 47 struct list_head list;
48 struct device_dma_parameters dma_parms; 48 struct device_dma_parameters dma_parms;
49 bool allocated; 49 bool allocated;
50 void *prev_identifier;
50}; 51};
51 52
52static LIST_HEAD(iommu_ctx_list); 53static LIST_HEAD(iommu_ctx_list);
53static LIST_HEAD(iommu_static_mappings_list); 54static LIST_HEAD(iommu_static_mappings_list);
54static DEFINE_MUTEX(iommu_ctx_list_mutex); 55static DEFINE_MUTEX(iommu_ctx_list_mutex);
55 56
56struct platform_device *iommu_context_dev_allocate(void) 57struct platform_device *iommu_context_dev_allocate(void *identifier)
57{ 58{
58 struct iommu_ctx *ctx; 59 struct iommu_ctx *ctx, *ctx_new = NULL;
60 bool dirty = false;
59 61
60 mutex_lock(&iommu_ctx_list_mutex); 62 mutex_lock(&iommu_ctx_list_mutex);
63 /*
64 * First check if we have same identifier stashed into
65 * some context device
66 * If yes, use that context device since it will have all
67 * the mappings stashed too
68 */
61 list_for_each_entry(ctx, &iommu_ctx_list, list) { 69 list_for_each_entry(ctx, &iommu_ctx_list, list) {
62 if (!ctx->allocated) { 70 if (!ctx->allocated && identifier == ctx->prev_identifier) {
63 ctx->allocated = true; 71 ctx->allocated = true;
64 mutex_unlock(&iommu_ctx_list_mutex); 72 mutex_unlock(&iommu_ctx_list_mutex);
65 return ctx->pdev; 73 return ctx->pdev;
66 } 74 }
67 } 75 }
76
77 /*
78 * Otherwise, find a device which does not have any identifier stashed
79 * If there is no device left without identifier stashed, use any of
80 * the free device and explicitly remove all the stashings from it
81 */
82 list_for_each_entry(ctx, &iommu_ctx_list, list) {
83 if (!ctx->allocated && !ctx_new) {
84 ctx_new = ctx;
85 dirty = true;
86 }
87 if (!ctx->allocated && !ctx->prev_identifier) {
88 ctx_new = ctx;
89 dirty = false;
90 break;
91 }
92 }
93
94 if (ctx_new) {
95 if (dirty) {
96 /*
97 * Ensure that all stashed mappings are removed from this context device
98 * before this context device gets reassigned to some other process
99 */
100 dma_buf_release_stash(&ctx_new->pdev->dev);
101 }
102
103 ctx_new->prev_identifier = identifier;
104 ctx_new->allocated = true;
105 mutex_unlock(&iommu_ctx_list_mutex);
106 return ctx_new->pdev;
107 }
108
68 mutex_unlock(&iommu_ctx_list_mutex); 109 mutex_unlock(&iommu_ctx_list_mutex);
69 110
70 return NULL; 111 return NULL;
@@ -200,8 +241,8 @@ static int iommu_context_dev_probe(struct platform_device *pdev)
200 pdev->dev.dma_parms = &ctx->dma_parms; 241 pdev->dev.dma_parms = &ctx->dma_parms;
201 dma_set_max_seg_size(&pdev->dev, UINT_MAX); 242 dma_set_max_seg_size(&pdev->dev, UINT_MAX);
202 243
203 /* disable lazy unmapping for context devices */ 244 /* flag required to handle stashings in context devices */
204 dma_buf_disable_lazy_unmapping(&pdev->dev); 245 pdev->dev.context_dev = true;
205 246
206 dev_info(&pdev->dev, "initialized (streamid=%d)", 247 dev_info(&pdev->dev, "initialized (streamid=%d)",
207 iommu_get_hwid(pdev->dev.archdata.iommu, &pdev->dev, 0)); 248 iommu_get_hwid(pdev->dev.archdata.iommu, &pdev->dev, 0));
diff --git a/drivers/video/tegra/host/iommu_context_dev.h b/drivers/video/tegra/host/iommu_context_dev.h
index e219265c2..9f0f40519 100644
--- a/drivers/video/tegra/host/iommu_context_dev.h
+++ b/drivers/video/tegra/host/iommu_context_dev.h
@@ -19,7 +19,7 @@
19#ifndef IOMMU_CONTEXT_DEV_H 19#ifndef IOMMU_CONTEXT_DEV_H
20#define IOMMU_CONTEXT_DEV_H 20#define IOMMU_CONTEXT_DEV_H
21 21
22struct platform_device *iommu_context_dev_allocate(void); 22struct platform_device *iommu_context_dev_allocate(void *identifier);
23void iommu_context_dev_release(struct platform_device *pdev); 23void iommu_context_dev_release(struct platform_device *pdev);
24int iommu_context_dev_get_streamid(struct platform_device *pdev); 24int iommu_context_dev_get_streamid(struct platform_device *pdev);
25int iommu_context_dev_map_static(void *vaddr, dma_addr_t paddr, size_t size); 25int iommu_context_dev_map_static(void *vaddr, dma_addr_t paddr, size_t size);
diff --git a/drivers/video/tegra/host/nvhost_vm.c b/drivers/video/tegra/host/nvhost_vm.c
index aaa03eb9b..979bb31fd 100644
--- a/drivers/video/tegra/host/nvhost_vm.c
+++ b/drivers/video/tegra/host/nvhost_vm.c
@@ -224,7 +224,7 @@ struct nvhost_vm *nvhost_vm_allocate(struct platform_device *pdev,
224 mutex_unlock(&host->vm_mutex); 224 mutex_unlock(&host->vm_mutex);
225 225
226 if (vm_op().init && vm->enable_hw) { 226 if (vm_op().init && vm->enable_hw) {
227 err = vm_op().init(vm); 227 err = vm_op().init(vm, identifier);
228 if (err) 228 if (err)
229 goto err_init; 229 goto err_init;
230 } 230 }