diff options
Diffstat (limited to 'drivers/gpu/nvgpu/common/linux')
5 files changed, 62 insertions, 75 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; | |||
32 | struct secure_page_buffer { | 32 | struct 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 | ||
38 | struct gk20a_platform { | 39 | struct 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 | ||
112 | int 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 | |||
137 | static 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 | |||
154 | static int gk20a_tegra_secure_alloc(struct gk20a *g, | 112 | static 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 | ||
198 | fail_sgt: | 159 | fail_sgt: |
199 | nvgpu_kfree(platform->g, sgt); | 160 | nvgpu_kfree(platform->g, sgt); |
200 | fail: | ||
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 | ||
667 | void gk20a_tegra_init_secure_alloc(struct gk20a *g) | 625 | int 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 | ||
852 | static int gk20a_tegra_late_probe(struct device *dev) | 834 | static 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 | ||
19 | struct device; | 19 | struct gk20a_platform; |
20 | struct gk20a; | ||
21 | 20 | ||
22 | void gk20a_tegra_init_secure_alloc(struct gk20a *g); | 21 | int gk20a_tegra_init_secure_alloc(struct gk20a_platform *platform); |
23 | int 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 | ||
157 | static int gp10b_tegra_late_probe(struct device *dev) | 160 | static 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 | ||
101 | static int gv11b_tegra_late_probe(struct device *dev) | 104 | static 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 | ||
268 | static struct device_attribute *dev_attr_sm_l1_tag_ecc_corrected_err_count_array; | 271 | static struct device_attribute *dev_attr_sm_l1_tag_ecc_corrected_err_count_array; |