summaryrefslogtreecommitdiffstats
path: root/drivers/gpu/nvgpu/gk20a/ltc_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/nvgpu/gk20a/ltc_common.c')
-rw-r--r--drivers/gpu/nvgpu/gk20a/ltc_common.c94
1 files changed, 90 insertions, 4 deletions
diff --git a/drivers/gpu/nvgpu/gk20a/ltc_common.c b/drivers/gpu/nvgpu/gk20a/ltc_common.c
index 8af8c687..2d2516d9 100644
--- a/drivers/gpu/nvgpu/gk20a/ltc_common.c
+++ b/drivers/gpu/nvgpu/gk20a/ltc_common.c
@@ -180,6 +180,85 @@ static int gk20a_ltc_init_zbc(struct gk20a *g, struct gr_gk20a *gr)
180 return 0; 180 return 0;
181} 181}
182 182
183static int gk20a_ltc_alloc_phys_cbc(struct gk20a *g,
184 size_t compbit_backing_size)
185{
186 struct gr_gk20a *gr = &g->gr;
187 int order = ffs(compbit_backing_size >> PAGE_SHIFT);
188 struct page *pages;
189 struct sg_table *sgt;
190 int err = 0;
191
192 /* allocate few pages */
193 pages = alloc_pages(GFP_KERNEL, order);
194 if (!pages) {
195 gk20a_dbg(gpu_dbg_pte, "alloc_pages failed\n");
196 err = -ENOMEM;
197 goto err_alloc_pages;
198 }
199
200 /* clean up the pages */
201 memset(page_address(pages), 0, compbit_backing_size);
202
203 /* allocate room for placing the pages pointer.. */
204 gr->compbit_store.pages =
205 kzalloc(sizeof(*gr->compbit_store.pages), GFP_KERNEL);
206 if (!gr->compbit_store.pages) {
207 gk20a_dbg(gpu_dbg_pte, "failed to allocate pages struct");
208 err = -ENOMEM;
209 goto err_alloc_compbit_store;
210 }
211
212 err = gk20a_get_sgtable_from_pages(&g->dev->dev, &sgt, &pages, 0,
213 compbit_backing_size);
214 if (err) {
215 gk20a_dbg(gpu_dbg_pte, "could not get sg table for pages\n");
216 goto err_alloc_sg_table;
217 }
218
219 /* store the parameters to gr structure */
220 *gr->compbit_store.pages = pages;
221 gr->compbit_store.base_iova = sg_phys(sgt->sgl);
222 gr->compbit_store.size = compbit_backing_size;
223
224 kfree(sgt);
225
226 return 0;
227
228err_alloc_sg_table:
229 kfree(gr->compbit_store.pages);
230 gr->compbit_store.pages = NULL;
231err_alloc_compbit_store:
232 __free_pages(pages, order);
233err_alloc_pages:
234 return err;
235}
236
237static int gk20a_ltc_alloc_virt_cbc(struct gk20a *g,
238 size_t compbit_backing_size)
239{
240 struct device *d = dev_from_gk20a(g);
241 struct gr_gk20a *gr = &g->gr;
242 DEFINE_DMA_ATTRS(attrs);
243 dma_addr_t iova;
244
245 dma_set_attr(DMA_ATTR_NO_KERNEL_MAPPING, &attrs);
246
247 gr->compbit_store.pages =
248 dma_alloc_attrs(d, compbit_backing_size, &iova,
249 GFP_KERNEL, &attrs);
250 if (!gr->compbit_store.pages) {
251 gk20a_err(dev_from_gk20a(g), "failed to allocate backing store for compbit : size %zu",
252 compbit_backing_size);
253 return -ENOMEM;
254 }
255
256 gr->compbit_store.base_iova = iova;
257 gr->compbit_store.size = compbit_backing_size;
258
259 return 0;
260}
261
183static void gk20a_ltc_init_cbc(struct gk20a *g, struct gr_gk20a *gr) 262static void gk20a_ltc_init_cbc(struct gk20a *g, struct gr_gk20a *gr)
184{ 263{
185 u32 max_size = gr->max_comptag_mem; 264 u32 max_size = gr->max_comptag_mem;
@@ -187,10 +266,17 @@ static void gk20a_ltc_init_cbc(struct gk20a *g, struct gr_gk20a *gr)
187 266
188 u32 compbit_base_post_divide; 267 u32 compbit_base_post_divide;
189 u64 compbit_base_post_multiply64; 268 u64 compbit_base_post_multiply64;
190 u64 compbit_store_base_iova = 269 u64 compbit_store_base_iova;
191 NV_MC_SMMU_VADDR_TRANSLATE(gr->compbit_store.base_iova); 270 u64 compbit_base_post_divide64;
192 u64 compbit_base_post_divide64 = (compbit_store_base_iova >> 271
193 ltc_ltcs_ltss_cbc_base_alignment_shift_v()); 272 if (IS_ENABLED(CONFIG_GK20A_PHYS_PAGE_TABLES))
273 compbit_store_base_iova = gr->compbit_store.base_iova;
274 else
275 compbit_store_base_iova = NV_MC_SMMU_VADDR_TRANSLATE(
276 gr->compbit_store.base_iova);
277
278 compbit_base_post_divide64 = compbit_store_base_iova >>
279 ltc_ltcs_ltss_cbc_base_alignment_shift_v();
194 280
195 do_div(compbit_base_post_divide64, gr->num_fbps); 281 do_div(compbit_base_post_divide64, gr->num_fbps);
196 compbit_base_post_divide = u64_lo32(compbit_base_post_divide64); 282 compbit_base_post_divide = u64_lo32(compbit_base_post_divide64);