summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/nvgpu/common/linux/platform_gk20a.h5
-rw-r--r--drivers/gpu/nvgpu/common/linux/platform_gk20a_tegra.c107
-rw-r--r--drivers/gpu/nvgpu/common/linux/platform_gk20a_tegra.h6
-rw-r--r--drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c10
-rw-r--r--drivers/gpu/nvgpu/common/linux/platform_gv11b_tegra.c9
-rw-r--r--drivers/gpu/nvgpu/gk20a/gr_gk20a.c21
6 files changed, 77 insertions, 81 deletions
diff --git a/drivers/gpu/nvgpu/common/linux/platform_gk20a.h b/drivers/gpu/nvgpu/common/linux/platform_gk20a.h
index 6994677e..ba4880af 100644
--- a/drivers/gpu/nvgpu/common/linux/platform_gk20a.h
+++ b/drivers/gpu/nvgpu/common/linux/platform_gk20a.h
@@ -32,7 +32,8 @@ struct gk20a_scale_profile;
32struct secure_page_buffer { 32struct secure_page_buffer {
33 void (*destroy)(struct gk20a *, struct secure_page_buffer *); 33 void (*destroy)(struct gk20a *, struct secure_page_buffer *);
34 size_t size; 34 size_t size;
35 u64 iova; 35 dma_addr_t phys;
36 size_t used;
36}; 37};
37 38
38struct gk20a_platform { 39struct gk20a_platform {
@@ -148,6 +149,8 @@ struct gk20a_platform {
148 /* Powerdown platform dependencies */ 149 /* Powerdown platform dependencies */
149 void (*idle)(struct device *dev); 150 void (*idle)(struct device *dev);
150 151
152 /* Preallocated VPR buffer for kernel */
153 size_t secure_buffer_size;
151 struct secure_page_buffer secure_buffer; 154 struct secure_page_buffer secure_buffer;
152 155
153 /* Device is going to be suspended */ 156 /* Device is going to be suspended */
diff --git a/drivers/gpu/nvgpu/common/linux/platform_gk20a_tegra.c b/drivers/gpu/nvgpu/common/linux/platform_gk20a_tegra.c
index 127a8ce9..219dcd40 100644
--- a/drivers/gpu/nvgpu/common/linux/platform_gk20a_tegra.c
+++ b/drivers/gpu/nvgpu/common/linux/platform_gk20a_tegra.c
@@ -103,103 +103,61 @@ static void gk20a_tegra_secure_page_destroy(struct gk20a *g,
103 DEFINE_DMA_ATTRS(attrs); 103 DEFINE_DMA_ATTRS(attrs);
104 dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, __DMA_ATTR(attrs)); 104 dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, __DMA_ATTR(attrs));
105 dma_free_attrs(&tegra_vpr_dev, secure_buffer->size, 105 dma_free_attrs(&tegra_vpr_dev, secure_buffer->size,
106 (void *)(uintptr_t)secure_buffer->iova, 106 (void *)(uintptr_t)secure_buffer->phys,
107 secure_buffer->iova, __DMA_ATTR(attrs)); 107 secure_buffer->phys, __DMA_ATTR(attrs));
108 108
109 secure_buffer->destroy = NULL; 109 secure_buffer->destroy = NULL;
110} 110}
111 111
112int gk20a_tegra_secure_page_alloc(struct device *dev)
113{
114 struct gk20a_platform *platform = dev_get_drvdata(dev);
115 struct gk20a *g = get_gk20a(dev);
116 struct secure_page_buffer *secure_buffer = &platform->secure_buffer;
117 DEFINE_DMA_ATTRS(attrs);
118 dma_addr_t iova;
119 size_t size = PAGE_SIZE;
120
121 if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL))
122 return -EINVAL;
123
124 dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, __DMA_ATTR(attrs));
125 (void)dma_alloc_attrs(&tegra_vpr_dev, size, &iova,
126 GFP_KERNEL, __DMA_ATTR(attrs));
127 if (dma_mapping_error(&tegra_vpr_dev, iova))
128 return -ENOMEM;
129
130 secure_buffer->size = size;
131 secure_buffer->iova = iova;
132 secure_buffer->destroy = gk20a_tegra_secure_page_destroy;
133
134 return 0;
135}
136
137static void gk20a_tegra_secure_destroy(struct gk20a *g,
138 struct gr_ctx_buffer_desc *desc)
139{
140 DEFINE_DMA_ATTRS(attrs);
141
142 if (desc->mem.priv.sgt) {
143 u64 pa = nvgpu_mem_get_phys_addr(g, &desc->mem);
144
145 dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, __DMA_ATTR(attrs));
146 dma_free_attrs(&tegra_vpr_dev, desc->mem.size,
147 (void *)(uintptr_t)pa,
148 pa, __DMA_ATTR(attrs));
149 nvgpu_free_sgtable(g, &desc->mem.priv.sgt);
150 desc->mem.priv.sgt = NULL;
151 }
152}
153
154static int gk20a_tegra_secure_alloc(struct gk20a *g, 112static int gk20a_tegra_secure_alloc(struct gk20a *g,
155 struct gr_ctx_buffer_desc *desc, 113 struct gr_ctx_buffer_desc *desc,
156 size_t size) 114 size_t size)
157{ 115{
158 struct device *dev = dev_from_gk20a(g); 116 struct device *dev = dev_from_gk20a(g);
159 struct gk20a_platform *platform = dev_get_drvdata(dev); 117 struct gk20a_platform *platform = dev_get_drvdata(dev);
160 DEFINE_DMA_ATTRS(attrs); 118 struct secure_page_buffer *secure_buffer = &platform->secure_buffer;
161 dma_addr_t iova; 119 dma_addr_t phys;
162 struct sg_table *sgt; 120 struct sg_table *sgt;
163 struct page *page; 121 struct page *page;
164 int err = 0; 122 int err = 0;
123 size_t aligned_size = PAGE_ALIGN(size);
165 124
166 dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, __DMA_ATTR(attrs)); 125 /* We ran out of preallocated memory */
167 (void)dma_alloc_attrs(&tegra_vpr_dev, size, &iova, 126 if (secure_buffer->used + aligned_size > secure_buffer->size) {
168 GFP_KERNEL, __DMA_ATTR(attrs)); 127 nvgpu_err(platform->g, "failed to alloc %zu bytes of VPR, %zu/%zu used",
169 if (dma_mapping_error(&tegra_vpr_dev, iova)) 128 size, secure_buffer->used, secure_buffer->size);
170 return -ENOMEM; 129 return -ENOMEM;
130 }
131
132 phys = secure_buffer->phys + secure_buffer->used;
171 133
172 sgt = nvgpu_kzalloc(platform->g, sizeof(*sgt)); 134 sgt = nvgpu_kzalloc(platform->g, sizeof(*sgt));
173 if (!sgt) { 135 if (!sgt) {
174 nvgpu_err(platform->g, "failed to allocate memory"); 136 nvgpu_err(platform->g, "failed to allocate memory");
175 goto fail; 137 return -ENOMEM;
176 } 138 }
177 err = sg_alloc_table(sgt, 1, GFP_KERNEL); 139 err = sg_alloc_table(sgt, 1, GFP_KERNEL);
178 if (err) { 140 if (err) {
179 nvgpu_err(platform->g, "failed to allocate sg_table"); 141 nvgpu_err(platform->g, "failed to allocate sg_table");
180 goto fail_sgt; 142 goto fail_sgt;
181 } 143 }
182 page = phys_to_page(iova); 144 page = phys_to_page(phys);
183 sg_set_page(sgt->sgl, page, size, 0); 145 sg_set_page(sgt->sgl, page, size, 0);
184 /* This bypasses SMMU for VPR during gmmu_map. */ 146 /* This bypasses SMMU for VPR during gmmu_map. */
185 sg_dma_address(sgt->sgl) = 0; 147 sg_dma_address(sgt->sgl) = 0;
186 148
187 desc->destroy = gk20a_tegra_secure_destroy; 149 desc->destroy = NULL;
188 150
189 desc->mem.priv.sgt = sgt; 151 desc->mem.priv.sgt = sgt;
190 desc->mem.size = size; 152 desc->mem.size = size;
191 desc->mem.aperture = APERTURE_SYSMEM; 153 desc->mem.aperture = APERTURE_SYSMEM;
192 154
193 if (platform->secure_buffer.destroy) 155 secure_buffer->used += aligned_size;
194 platform->secure_buffer.destroy(g, &platform->secure_buffer);
195 156
196 return err; 157 return err;
197 158
198fail_sgt: 159fail_sgt:
199 nvgpu_kfree(platform->g, sgt); 160 nvgpu_kfree(platform->g, sgt);
200fail:
201 dma_free_attrs(&tegra_vpr_dev, desc->mem.size,
202 (void *)(uintptr_t)iova, iova, __DMA_ATTR(attrs));
203 return err; 161 return err;
204} 162}
205 163
@@ -664,10 +622,32 @@ void gk20a_tegra_idle(struct device *dev)
664#endif 622#endif
665} 623}
666 624
667void gk20a_tegra_init_secure_alloc(struct gk20a *g) 625int gk20a_tegra_init_secure_alloc(struct gk20a_platform *platform)
668{ 626{
627 struct gk20a *g = platform->g;
628 struct secure_page_buffer *secure_buffer = &platform->secure_buffer;
629 DEFINE_DMA_ATTRS(attrs);
630 dma_addr_t iova;
631
632 if (nvgpu_is_enabled(g, NVGPU_IS_FMODEL))
633 return 0;
634
635 dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, __DMA_ATTR(attrs));
636 (void)dma_alloc_attrs(&tegra_vpr_dev, platform->secure_buffer_size, &iova,
637 GFP_KERNEL, __DMA_ATTR(attrs));
638 /* Some platforms disable VPR. In that case VPR allocations always
639 * fail. Just disable VPR usage in nvgpu in that case. */
640 if (dma_mapping_error(&tegra_vpr_dev, iova))
641 return 0;
642
643 secure_buffer->size = platform->secure_buffer_size;
644 secure_buffer->phys = iova;
645 secure_buffer->destroy = gk20a_tegra_secure_page_destroy;
646
669 g->ops.secure_alloc = gk20a_tegra_secure_alloc; 647 g->ops.secure_alloc = gk20a_tegra_secure_alloc;
670 __nvgpu_set_enabled(g, NVGPU_SUPPORT_VPR, true); 648 __nvgpu_set_enabled(g, NVGPU_SUPPORT_VPR, true);
649
650 return 0;
671} 651}
672 652
673#ifdef CONFIG_COMMON_CLK 653#ifdef CONFIG_COMMON_CLK
@@ -836,7 +816,9 @@ static int gk20a_tegra_probe(struct device *dev)
836 816
837 gk20a_tegra_get_clocks(dev); 817 gk20a_tegra_get_clocks(dev);
838 nvgpu_linux_init_clk_support(platform->g); 818 nvgpu_linux_init_clk_support(platform->g);
839 gk20a_tegra_init_secure_alloc(platform->g); 819 ret = gk20a_tegra_init_secure_alloc(platform);
820 if (ret)
821 return ret;
840 822
841 if (platform->clk_register) { 823 if (platform->clk_register) {
842 ret = platform->clk_register(platform->g); 824 ret = platform->clk_register(platform->g);
@@ -851,9 +833,6 @@ static int gk20a_tegra_probe(struct device *dev)
851 833
852static int gk20a_tegra_late_probe(struct device *dev) 834static int gk20a_tegra_late_probe(struct device *dev)
853{ 835{
854 /* Cause early VPR resize */
855 gk20a_tegra_secure_page_alloc(dev);
856
857 return 0; 836 return 0;
858} 837}
859 838
@@ -974,4 +953,6 @@ struct gk20a_platform gm20b_tegra_platform = {
974 .soc_name = "tegra21x", 953 .soc_name = "tegra21x",
975 954
976 .unified_memory = true, 955 .unified_memory = true,
956
957 .secure_buffer_size = 335872,
977}; 958};
diff --git a/drivers/gpu/nvgpu/common/linux/platform_gk20a_tegra.h b/drivers/gpu/nvgpu/common/linux/platform_gk20a_tegra.h
index 1aa7c1e3..f7d50406 100644
--- a/drivers/gpu/nvgpu/common/linux/platform_gk20a_tegra.h
+++ b/drivers/gpu/nvgpu/common/linux/platform_gk20a_tegra.h
@@ -16,10 +16,8 @@
16#ifndef _NVGPU_PLATFORM_GK20A_TEGRA_H_ 16#ifndef _NVGPU_PLATFORM_GK20A_TEGRA_H_
17#define _NVGPU_PLATFORM_GK20A_TEGRA_H_ 17#define _NVGPU_PLATFORM_GK20A_TEGRA_H_
18 18
19struct device; 19struct gk20a_platform;
20struct gk20a;
21 20
22void gk20a_tegra_init_secure_alloc(struct gk20a *g); 21int gk20a_tegra_init_secure_alloc(struct gk20a_platform *platform);
23int gk20a_tegra_secure_page_alloc(struct device *dev);
24 22
25#endif 23#endif
diff --git a/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c b/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
index 0b0ebeeb..2bca2bd5 100644
--- a/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
+++ b/drivers/gpu/nvgpu/common/linux/platform_gp10b_tegra.c
@@ -137,6 +137,10 @@ static int gp10b_tegra_probe(struct device *dev)
137 return ret; 137 return ret;
138#endif 138#endif
139 139
140 ret = gk20a_tegra_init_secure_alloc(platform);
141 if (ret)
142 return ret;
143
140 platform->disable_bigpage = !device_is_iommuable(dev); 144 platform->disable_bigpage = !device_is_iommuable(dev);
141 145
142 platform->g->gr.ctx_vars.dump_ctxsw_stats_on_channel_close 146 platform->g->gr.ctx_vars.dump_ctxsw_stats_on_channel_close
@@ -149,16 +153,12 @@ static int gp10b_tegra_probe(struct device *dev)
149 153
150 gp10b_tegra_get_clocks(dev); 154 gp10b_tegra_get_clocks(dev);
151 nvgpu_linux_init_clk_support(platform->g); 155 nvgpu_linux_init_clk_support(platform->g);
152 gk20a_tegra_init_secure_alloc(platform->g);
153 156
154 return 0; 157 return 0;
155} 158}
156 159
157static int gp10b_tegra_late_probe(struct device *dev) 160static int gp10b_tegra_late_probe(struct device *dev)
158{ 161{
159 /* Cause early VPR resize */
160 gk20a_tegra_secure_page_alloc(dev);
161
162 return 0; 162 return 0;
163} 163}
164 164
@@ -422,6 +422,8 @@ struct gk20a_platform gp10b_tegra_platform = {
422 .unified_memory = true, 422 .unified_memory = true,
423 423
424 .ltc_streamid = TEGRA_SID_GPUB, 424 .ltc_streamid = TEGRA_SID_GPUB,
425
426 .secure_buffer_size = 401408,
425}; 427};
426 428
427 429
diff --git a/drivers/gpu/nvgpu/common/linux/platform_gv11b_tegra.c b/drivers/gpu/nvgpu/common/linux/platform_gv11b_tegra.c
index 40c75164..ad56167a 100644
--- a/drivers/gpu/nvgpu/common/linux/platform_gv11b_tegra.c
+++ b/drivers/gpu/nvgpu/common/linux/platform_gv11b_tegra.c
@@ -81,6 +81,10 @@ static int gv11b_tegra_probe(struct device *dev)
81 g->has_syncpoints = false; 81 g->has_syncpoints = false;
82#endif 82#endif
83 83
84 err = gk20a_tegra_init_secure_alloc(platform);
85 if (err)
86 return err;
87
84 platform->disable_bigpage = !device_is_iommuable(dev); 88 platform->disable_bigpage = !device_is_iommuable(dev);
85 89
86 platform->g->gr.ctx_vars.dump_ctxsw_stats_on_channel_close 90 platform->g->gr.ctx_vars.dump_ctxsw_stats_on_channel_close
@@ -93,15 +97,12 @@ static int gv11b_tegra_probe(struct device *dev)
93 97
94 gp10b_tegra_get_clocks(dev); 98 gp10b_tegra_get_clocks(dev);
95 nvgpu_linux_init_clk_support(platform->g); 99 nvgpu_linux_init_clk_support(platform->g);
96 gk20a_tegra_init_secure_alloc(platform->g);
97 100
98 return 0; 101 return 0;
99} 102}
100 103
101static int gv11b_tegra_late_probe(struct device *dev) 104static int gv11b_tegra_late_probe(struct device *dev)
102{ 105{
103 /* Cause early VPR resize */
104 gk20a_tegra_secure_page_alloc(dev);
105 return 0; 106 return 0;
106} 107}
107 108
@@ -263,6 +264,8 @@ struct gk20a_platform gv11b_tegra_platform = {
263 264
264 .reset_assert = gp10b_tegra_reset_assert, 265 .reset_assert = gp10b_tegra_reset_assert,
265 .reset_deassert = gp10b_tegra_reset_deassert, 266 .reset_deassert = gp10b_tegra_reset_deassert,
267
268 .secure_buffer_size = 667648,
266}; 269};
267 270
268static struct device_attribute *dev_attr_sm_l1_tag_ecc_corrected_err_count_array; 271static struct device_attribute *dev_attr_sm_l1_tag_ecc_corrected_err_count_array;
diff --git a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
index fb02bb81..0e21f749 100644
--- a/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
+++ b/drivers/gpu/nvgpu/gk20a/gr_gk20a.c
@@ -2532,10 +2532,13 @@ static int gr_gk20a_alloc_global_ctx_buffers(struct gk20a *g)
2532 if (err) 2532 if (err)
2533 goto clean_up; 2533 goto clean_up;
2534 2534
2535 if (g->ops.secure_alloc) 2535 if (g->ops.secure_alloc) {
2536 g->ops.secure_alloc(g, 2536 err = g->ops.secure_alloc(g,
2537 &gr->global_ctx_buffer[CIRCULAR_VPR], 2537 &gr->global_ctx_buffer[CIRCULAR_VPR],
2538 cb_buffer_size); 2538 cb_buffer_size);
2539 if (err)
2540 goto clean_up;
2541 }
2539 2542
2540 gk20a_dbg_info("pagepool_buffer_size : %d", pagepool_buffer_size); 2543 gk20a_dbg_info("pagepool_buffer_size : %d", pagepool_buffer_size);
2541 2544
@@ -2544,10 +2547,13 @@ static int gr_gk20a_alloc_global_ctx_buffers(struct gk20a *g)
2544 if (err) 2547 if (err)
2545 goto clean_up; 2548 goto clean_up;
2546 2549
2547 if (g->ops.secure_alloc) 2550 if (g->ops.secure_alloc) {
2548 g->ops.secure_alloc(g, 2551 err = g->ops.secure_alloc(g,
2549 &gr->global_ctx_buffer[PAGEPOOL_VPR], 2552 &gr->global_ctx_buffer[PAGEPOOL_VPR],
2550 pagepool_buffer_size); 2553 pagepool_buffer_size);
2554 if (err)
2555 goto clean_up;
2556 }
2551 2557
2552 gk20a_dbg_info("attr_buffer_size : %d", attr_buffer_size); 2558 gk20a_dbg_info("attr_buffer_size : %d", attr_buffer_size);
2553 2559
@@ -2556,10 +2562,13 @@ static int gr_gk20a_alloc_global_ctx_buffers(struct gk20a *g)
2556 if (err) 2562 if (err)
2557 goto clean_up; 2563 goto clean_up;
2558 2564
2559 if (g->ops.secure_alloc) 2565 if (g->ops.secure_alloc) {
2560 g->ops.secure_alloc(g, 2566 err = g->ops.secure_alloc(g,
2561 &gr->global_ctx_buffer[ATTRIBUTE_VPR], 2567 &gr->global_ctx_buffer[ATTRIBUTE_VPR],
2562 attr_buffer_size); 2568 attr_buffer_size);
2569 if (err)
2570 goto clean_up;
2571 }
2563 2572
2564 gk20a_dbg_info("golden_image_size : %d", 2573 gk20a_dbg_info("golden_image_size : %d",
2565 gr->ctx_vars.golden_image_size); 2574 gr->ctx_vars.golden_image_size);