1 1.8 riastrad /* $NetBSD: gen6_ppgtt.c,v 1.8 2021/12/19 12:27:32 riastradh Exp $ */ 2 1.1 riastrad 3 1.1 riastrad // SPDX-License-Identifier: MIT 4 1.1 riastrad /* 5 1.1 riastrad * Copyright 2020 Intel Corporation 6 1.1 riastrad */ 7 1.1 riastrad 8 1.1 riastrad #include <sys/cdefs.h> 9 1.8 riastrad __KERNEL_RCSID(0, "$NetBSD: gen6_ppgtt.c,v 1.8 2021/12/19 12:27:32 riastradh Exp $"); 10 1.1 riastrad 11 1.1 riastrad #include <linux/log2.h> 12 1.1 riastrad 13 1.1 riastrad #include "gen6_ppgtt.h" 14 1.1 riastrad #include "i915_scatterlist.h" 15 1.1 riastrad #include "i915_trace.h" 16 1.1 riastrad #include "i915_vgpu.h" 17 1.1 riastrad #include "intel_gt.h" 18 1.4 riastrad #include <linux/nbsd-namespace.h> 19 1.1 riastrad 20 1.1 riastrad /* Write pde (index) from the page directory @pd to the page table @pt */ 21 1.1 riastrad static inline void gen6_write_pde(const struct gen6_ppgtt *ppgtt, 22 1.1 riastrad const unsigned int pde, 23 1.1 riastrad const struct i915_page_table *pt) 24 1.1 riastrad { 25 1.1 riastrad /* Caller needs to make sure the write completes if necessary */ 26 1.3 riastrad #ifdef __NetBSD__ 27 1.3 riastrad CTASSERT(sizeof(gen6_pte_t) == 4); 28 1.3 riastrad bus_space_write_4(ppgtt->pd_bst, ppgtt->pd_bsh, pde*sizeof(gen6_pte_t), 29 1.3 riastrad GEN6_PDE_ADDR_ENCODE(px_dma(pt)) | GEN6_PDE_VALID); 30 1.3 riastrad #else 31 1.1 riastrad iowrite32(GEN6_PDE_ADDR_ENCODE(px_dma(pt)) | GEN6_PDE_VALID, 32 1.1 riastrad ppgtt->pd_addr + pde); 33 1.3 riastrad #endif 34 1.1 riastrad } 35 1.1 riastrad 36 1.1 riastrad void gen7_ppgtt_enable(struct intel_gt *gt) 37 1.1 riastrad { 38 1.1 riastrad struct drm_i915_private *i915 = gt->i915; 39 1.1 riastrad struct intel_uncore *uncore = gt->uncore; 40 1.1 riastrad struct intel_engine_cs *engine; 41 1.1 riastrad enum intel_engine_id id; 42 1.1 riastrad u32 ecochk; 43 1.1 riastrad 44 1.1 riastrad intel_uncore_rmw(uncore, GAC_ECO_BITS, 0, ECOBITS_PPGTT_CACHE64B); 45 1.1 riastrad 46 1.1 riastrad ecochk = intel_uncore_read(uncore, GAM_ECOCHK); 47 1.1 riastrad if (IS_HASWELL(i915)) { 48 1.1 riastrad ecochk |= ECOCHK_PPGTT_WB_HSW; 49 1.1 riastrad } else { 50 1.1 riastrad ecochk |= ECOCHK_PPGTT_LLC_IVB; 51 1.1 riastrad ecochk &= ~ECOCHK_PPGTT_GFDT_IVB; 52 1.1 riastrad } 53 1.1 riastrad intel_uncore_write(uncore, GAM_ECOCHK, ecochk); 54 1.1 riastrad 55 1.1 riastrad for_each_engine(engine, gt, id) { 56 1.1 riastrad /* GFX_MODE is per-ring on gen7+ */ 57 1.1 riastrad ENGINE_WRITE(engine, 58 1.1 riastrad RING_MODE_GEN7, 59 1.1 riastrad _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); 60 1.1 riastrad } 61 1.1 riastrad } 62 1.1 riastrad 63 1.1 riastrad void gen6_ppgtt_enable(struct intel_gt *gt) 64 1.1 riastrad { 65 1.1 riastrad struct intel_uncore *uncore = gt->uncore; 66 1.1 riastrad 67 1.1 riastrad intel_uncore_rmw(uncore, 68 1.1 riastrad GAC_ECO_BITS, 69 1.1 riastrad 0, 70 1.1 riastrad ECOBITS_SNB_BIT | ECOBITS_PPGTT_CACHE64B); 71 1.1 riastrad 72 1.1 riastrad intel_uncore_rmw(uncore, 73 1.1 riastrad GAB_CTL, 74 1.1 riastrad 0, 75 1.1 riastrad GAB_CTL_CONT_AFTER_PAGEFAULT); 76 1.1 riastrad 77 1.1 riastrad intel_uncore_rmw(uncore, 78 1.1 riastrad GAM_ECOCHK, 79 1.1 riastrad 0, 80 1.1 riastrad ECOCHK_SNB_BIT | ECOCHK_PPGTT_CACHE64B); 81 1.1 riastrad 82 1.1 riastrad if (HAS_PPGTT(uncore->i915)) /* may be disabled for VT-d */ 83 1.1 riastrad intel_uncore_write(uncore, 84 1.1 riastrad GFX_MODE, 85 1.1 riastrad _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE)); 86 1.1 riastrad } 87 1.1 riastrad 88 1.1 riastrad /* PPGTT support for Sandybdrige/Gen6 and later */ 89 1.1 riastrad static void gen6_ppgtt_clear_range(struct i915_address_space *vm, 90 1.1 riastrad u64 start, u64 length) 91 1.1 riastrad { 92 1.1 riastrad struct gen6_ppgtt * const ppgtt = to_gen6_ppgtt(i915_vm_to_ppgtt(vm)); 93 1.1 riastrad const unsigned int first_entry = start / I915_GTT_PAGE_SIZE; 94 1.1 riastrad const gen6_pte_t scratch_pte = vm->scratch[0].encode; 95 1.1 riastrad unsigned int pde = first_entry / GEN6_PTES; 96 1.1 riastrad unsigned int pte = first_entry % GEN6_PTES; 97 1.1 riastrad unsigned int num_entries = length / I915_GTT_PAGE_SIZE; 98 1.1 riastrad 99 1.1 riastrad while (num_entries) { 100 1.1 riastrad struct i915_page_table * const pt = 101 1.1 riastrad i915_pt_entry(ppgtt->base.pd, pde++); 102 1.1 riastrad const unsigned int count = min(num_entries, GEN6_PTES - pte); 103 1.1 riastrad gen6_pte_t *vaddr; 104 1.1 riastrad 105 1.1 riastrad GEM_BUG_ON(px_base(pt) == px_base(&vm->scratch[1])); 106 1.1 riastrad 107 1.1 riastrad num_entries -= count; 108 1.1 riastrad 109 1.1 riastrad GEM_BUG_ON(count > atomic_read(&pt->used)); 110 1.1 riastrad if (!atomic_sub_return(count, &pt->used)) 111 1.1 riastrad ppgtt->scan_for_unused_pt = true; 112 1.1 riastrad 113 1.1 riastrad /* 114 1.1 riastrad * Note that the hw doesn't support removing PDE on the fly 115 1.1 riastrad * (they are cached inside the context with no means to 116 1.1 riastrad * invalidate the cache), so we can only reset the PTE 117 1.1 riastrad * entries back to scratch. 118 1.1 riastrad */ 119 1.1 riastrad 120 1.1 riastrad vaddr = kmap_atomic_px(pt); 121 1.1 riastrad memset32(vaddr + pte, scratch_pte, count); 122 1.1 riastrad kunmap_atomic(vaddr); 123 1.1 riastrad 124 1.1 riastrad pte = 0; 125 1.1 riastrad } 126 1.1 riastrad } 127 1.1 riastrad 128 1.1 riastrad static void gen6_ppgtt_insert_entries(struct i915_address_space *vm, 129 1.1 riastrad struct i915_vma *vma, 130 1.1 riastrad enum i915_cache_level cache_level, 131 1.1 riastrad u32 flags) 132 1.1 riastrad { 133 1.1 riastrad struct i915_ppgtt *ppgtt = i915_vm_to_ppgtt(vm); 134 1.1 riastrad struct i915_page_directory * const pd = ppgtt->pd; 135 1.1 riastrad unsigned int first_entry = vma->node.start / I915_GTT_PAGE_SIZE; 136 1.1 riastrad unsigned int act_pt = first_entry / GEN6_PTES; 137 1.1 riastrad unsigned int act_pte = first_entry % GEN6_PTES; 138 1.1 riastrad const u32 pte_encode = vm->pte_encode(0, cache_level, flags); 139 1.1 riastrad struct sgt_dma iter = sgt_dma(vma); 140 1.1 riastrad gen6_pte_t *vaddr; 141 1.1 riastrad 142 1.1 riastrad GEM_BUG_ON(pd->entry[act_pt] == &vm->scratch[1]); 143 1.1 riastrad 144 1.1 riastrad vaddr = kmap_atomic_px(i915_pt_entry(pd, act_pt)); 145 1.1 riastrad do { 146 1.3 riastrad #ifdef __NetBSD__ 147 1.3 riastrad KASSERT(iter.seg < iter.map->dm_nsegs); 148 1.3 riastrad KASSERT((iter.off & (PAGE_SIZE - 1)) == 0); 149 1.3 riastrad const bus_dma_segment_t *seg = &iter.map->dm_segs[iter.seg]; 150 1.3 riastrad KASSERT((seg->ds_addr & (PAGE_SIZE - 1)) == 0); 151 1.3 riastrad KASSERT((seg->ds_len & (PAGE_SIZE - 1)) == 0); 152 1.3 riastrad KASSERT(iter.off <= seg->ds_len - PAGE_SIZE); 153 1.3 riastrad vaddr[act_pte] = pte_encode | 154 1.3 riastrad GEN6_PTE_ADDR_ENCODE(seg->ds_addr + iter.off); 155 1.3 riastrad iter.off += PAGE_SIZE; 156 1.3 riastrad if (iter.off >= seg->ds_len) { 157 1.3 riastrad GEM_BUG_ON(iter.off > seg->ds_len); 158 1.3 riastrad iter.off = 0; 159 1.3 riastrad if (++iter.seg >= iter.map->dm_nsegs) { 160 1.3 riastrad GEM_BUG_ON(iter.seg > iter.map->dm_nsegs); 161 1.3 riastrad break; 162 1.3 riastrad } 163 1.3 riastrad } 164 1.3 riastrad #else 165 1.1 riastrad GEM_BUG_ON(iter.sg->length < I915_GTT_PAGE_SIZE); 166 1.1 riastrad vaddr[act_pte] = pte_encode | GEN6_PTE_ADDR_ENCODE(iter.dma); 167 1.1 riastrad 168 1.1 riastrad iter.dma += I915_GTT_PAGE_SIZE; 169 1.1 riastrad if (iter.dma == iter.max) { 170 1.1 riastrad iter.sg = __sg_next(iter.sg); 171 1.1 riastrad if (!iter.sg) 172 1.1 riastrad break; 173 1.1 riastrad 174 1.1 riastrad iter.dma = sg_dma_address(iter.sg); 175 1.1 riastrad iter.max = iter.dma + iter.sg->length; 176 1.1 riastrad } 177 1.3 riastrad #endif 178 1.1 riastrad 179 1.1 riastrad if (++act_pte == GEN6_PTES) { 180 1.1 riastrad kunmap_atomic(vaddr); 181 1.1 riastrad vaddr = kmap_atomic_px(i915_pt_entry(pd, ++act_pt)); 182 1.1 riastrad act_pte = 0; 183 1.1 riastrad } 184 1.1 riastrad } while (1); 185 1.1 riastrad kunmap_atomic(vaddr); 186 1.1 riastrad 187 1.1 riastrad vma->page_sizes.gtt = I915_GTT_PAGE_SIZE; 188 1.1 riastrad } 189 1.1 riastrad 190 1.1 riastrad static void gen6_flush_pd(struct gen6_ppgtt *ppgtt, u64 start, u64 end) 191 1.1 riastrad { 192 1.1 riastrad struct i915_page_directory * const pd = ppgtt->base.pd; 193 1.1 riastrad struct i915_page_table *pt; 194 1.1 riastrad unsigned int pde; 195 1.1 riastrad 196 1.1 riastrad start = round_down(start, SZ_64K); 197 1.1 riastrad end = round_up(end, SZ_64K) - start; 198 1.1 riastrad 199 1.1 riastrad mutex_lock(&ppgtt->flush); 200 1.1 riastrad 201 1.1 riastrad gen6_for_each_pde(pt, pd, start, end, pde) 202 1.1 riastrad gen6_write_pde(ppgtt, pde, pt); 203 1.1 riastrad 204 1.1 riastrad mb(); 205 1.5 riastrad #ifdef __NetBSD__ 206 1.5 riastrad (void)bus_space_read_4(ppgtt->pd_bst, ppgtt->pd_bsh, 4*(pde - 1)); 207 1.5 riastrad #else 208 1.1 riastrad ioread32(ppgtt->pd_addr + pde - 1); 209 1.5 riastrad #endif 210 1.1 riastrad gen6_ggtt_invalidate(ppgtt->base.vm.gt->ggtt); 211 1.1 riastrad mb(); 212 1.1 riastrad 213 1.1 riastrad mutex_unlock(&ppgtt->flush); 214 1.1 riastrad } 215 1.1 riastrad 216 1.1 riastrad static int gen6_alloc_va_range(struct i915_address_space *vm, 217 1.1 riastrad u64 start, u64 length) 218 1.1 riastrad { 219 1.1 riastrad struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(i915_vm_to_ppgtt(vm)); 220 1.1 riastrad struct i915_page_directory * const pd = ppgtt->base.pd; 221 1.1 riastrad struct i915_page_table *pt, *alloc = NULL; 222 1.1 riastrad intel_wakeref_t wakeref; 223 1.1 riastrad u64 from = start; 224 1.1 riastrad unsigned int pde; 225 1.1 riastrad int ret = 0; 226 1.1 riastrad 227 1.1 riastrad wakeref = intel_runtime_pm_get(&vm->i915->runtime_pm); 228 1.1 riastrad 229 1.1 riastrad spin_lock(&pd->lock); 230 1.1 riastrad gen6_for_each_pde(pt, pd, start, length, pde) { 231 1.1 riastrad const unsigned int count = gen6_pte_count(start, length); 232 1.1 riastrad 233 1.1 riastrad if (px_base(pt) == px_base(&vm->scratch[1])) { 234 1.1 riastrad spin_unlock(&pd->lock); 235 1.1 riastrad 236 1.1 riastrad pt = fetch_and_zero(&alloc); 237 1.1 riastrad if (!pt) 238 1.1 riastrad pt = alloc_pt(vm); 239 1.1 riastrad if (IS_ERR(pt)) { 240 1.1 riastrad ret = PTR_ERR(pt); 241 1.1 riastrad goto unwind_out; 242 1.1 riastrad } 243 1.1 riastrad 244 1.1 riastrad fill32_px(pt, vm->scratch[0].encode); 245 1.1 riastrad 246 1.1 riastrad spin_lock(&pd->lock); 247 1.1 riastrad if (pd->entry[pde] == &vm->scratch[1]) { 248 1.1 riastrad pd->entry[pde] = pt; 249 1.1 riastrad } else { 250 1.1 riastrad alloc = pt; 251 1.1 riastrad pt = pd->entry[pde]; 252 1.1 riastrad } 253 1.1 riastrad } 254 1.1 riastrad 255 1.1 riastrad atomic_add(count, &pt->used); 256 1.1 riastrad } 257 1.1 riastrad spin_unlock(&pd->lock); 258 1.1 riastrad 259 1.1 riastrad if (i915_vma_is_bound(ppgtt->vma, I915_VMA_GLOBAL_BIND)) 260 1.1 riastrad gen6_flush_pd(ppgtt, from, start); 261 1.1 riastrad 262 1.1 riastrad goto out; 263 1.1 riastrad 264 1.1 riastrad unwind_out: 265 1.1 riastrad gen6_ppgtt_clear_range(vm, from, start - from); 266 1.1 riastrad out: 267 1.1 riastrad if (alloc) 268 1.1 riastrad free_px(vm, alloc); 269 1.1 riastrad intel_runtime_pm_put(&vm->i915->runtime_pm, wakeref); 270 1.1 riastrad return ret; 271 1.1 riastrad } 272 1.1 riastrad 273 1.1 riastrad static int gen6_ppgtt_init_scratch(struct gen6_ppgtt *ppgtt) 274 1.1 riastrad { 275 1.1 riastrad struct i915_address_space * const vm = &ppgtt->base.vm; 276 1.1 riastrad struct i915_page_directory * const pd = ppgtt->base.pd; 277 1.1 riastrad int ret; 278 1.1 riastrad 279 1.1 riastrad ret = setup_scratch_page(vm, __GFP_HIGHMEM); 280 1.1 riastrad if (ret) 281 1.1 riastrad return ret; 282 1.1 riastrad 283 1.1 riastrad vm->scratch[0].encode = 284 1.1 riastrad vm->pte_encode(px_dma(&vm->scratch[0]), 285 1.1 riastrad I915_CACHE_NONE, PTE_READ_ONLY); 286 1.1 riastrad 287 1.1 riastrad if (unlikely(setup_page_dma(vm, px_base(&vm->scratch[1])))) { 288 1.1 riastrad cleanup_scratch_page(vm); 289 1.1 riastrad return -ENOMEM; 290 1.1 riastrad } 291 1.1 riastrad 292 1.1 riastrad fill32_px(&vm->scratch[1], vm->scratch[0].encode); 293 1.1 riastrad memset_p(pd->entry, &vm->scratch[1], I915_PDES); 294 1.1 riastrad 295 1.1 riastrad return 0; 296 1.1 riastrad } 297 1.1 riastrad 298 1.1 riastrad static void gen6_ppgtt_free_pd(struct gen6_ppgtt *ppgtt) 299 1.1 riastrad { 300 1.1 riastrad struct i915_page_directory * const pd = ppgtt->base.pd; 301 1.1 riastrad struct i915_page_dma * const scratch = 302 1.1 riastrad px_base(&ppgtt->base.vm.scratch[1]); 303 1.1 riastrad struct i915_page_table *pt; 304 1.1 riastrad u32 pde; 305 1.1 riastrad 306 1.1 riastrad gen6_for_all_pdes(pt, pd, pde) 307 1.1 riastrad if (px_base(pt) != scratch) 308 1.1 riastrad free_px(&ppgtt->base.vm, pt); 309 1.1 riastrad } 310 1.1 riastrad 311 1.1 riastrad static void gen6_ppgtt_cleanup(struct i915_address_space *vm) 312 1.1 riastrad { 313 1.1 riastrad struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(i915_vm_to_ppgtt(vm)); 314 1.1 riastrad 315 1.1 riastrad __i915_vma_put(ppgtt->vma); 316 1.1 riastrad 317 1.1 riastrad gen6_ppgtt_free_pd(ppgtt); 318 1.1 riastrad free_scratch(vm); 319 1.1 riastrad 320 1.1 riastrad mutex_destroy(&ppgtt->flush); 321 1.1 riastrad mutex_destroy(&ppgtt->pin_mutex); 322 1.6 riastrad spin_lock_destroy(&ppgtt->base.pd->lock); 323 1.1 riastrad kfree(ppgtt->base.pd); 324 1.1 riastrad } 325 1.1 riastrad 326 1.1 riastrad static int pd_vma_set_pages(struct i915_vma *vma) 327 1.1 riastrad { 328 1.1 riastrad vma->pages = ERR_PTR(-ENODEV); 329 1.1 riastrad return 0; 330 1.1 riastrad } 331 1.1 riastrad 332 1.1 riastrad static void pd_vma_clear_pages(struct i915_vma *vma) 333 1.1 riastrad { 334 1.1 riastrad GEM_BUG_ON(!vma->pages); 335 1.1 riastrad 336 1.1 riastrad vma->pages = NULL; 337 1.1 riastrad } 338 1.1 riastrad 339 1.1 riastrad static int pd_vma_bind(struct i915_vma *vma, 340 1.1 riastrad enum i915_cache_level cache_level, 341 1.1 riastrad u32 unused) 342 1.1 riastrad { 343 1.1 riastrad struct i915_ggtt *ggtt = i915_vm_to_ggtt(vma->vm); 344 1.1 riastrad struct gen6_ppgtt *ppgtt = vma->private; 345 1.1 riastrad u32 ggtt_offset = i915_ggtt_offset(vma) / I915_GTT_PAGE_SIZE; 346 1.1 riastrad 347 1.1 riastrad px_base(ppgtt->base.pd)->ggtt_offset = ggtt_offset * sizeof(gen6_pte_t); 348 1.3 riastrad #ifdef __NetBSD__ 349 1.3 riastrad { 350 1.8 riastrad bus_size_t npgs = vma->size >> PAGE_SHIFT; 351 1.8 riastrad bus_size_t gtt_nbytes = npgs * sizeof(gen6_pte_t); 352 1.7 riastrad bus_size_t ggtt_offset_bytes = 353 1.7 riastrad (bus_size_t)ggtt_offset * sizeof(gen6_pte_t); 354 1.3 riastrad int ret; 355 1.7 riastrad 356 1.7 riastrad KASSERTMSG(gtt_nbytes <= ggtt->gsmsz - ggtt_offset_bytes, 357 1.8 riastrad "oversize ppgtt size 0x%"PRIx64" bytes 0x%"PRIx64" pgs," 358 1.7 riastrad " requiring 0x%"PRIx64" bytes of ptes at 0x%"PRIx64";" 359 1.8 riastrad " gsm has 0x%"PRIx64" bytes total" 360 1.8 riastrad " with only 0x%"PRIx64" for ptes", 361 1.8 riastrad (uint64_t)vma->size, (uint64_t)npgs, 362 1.8 riastrad (uint64_t)gtt_nbytes, (uint64_t)ggtt_offset_bytes, 363 1.8 riastrad (uint64_t)ggtt->gsmsz, 364 1.8 riastrad (uint64_t)(ggtt->gsmsz - ggtt_offset_bytes)); 365 1.7 riastrad ret = -bus_space_subregion(ggtt->gsmt, ggtt->gsmh, ggtt_offset_bytes, 366 1.8 riastrad gtt_nbytes, &ppgtt->pd_bsh); 367 1.3 riastrad if (ret) { 368 1.3 riastrad DRM_ERROR("Unable to subregion the GGTT: %d\n", ret); 369 1.3 riastrad return ret; 370 1.3 riastrad } 371 1.7 riastrad ppgtt->pd_bst = ggtt->gsmt; 372 1.3 riastrad } 373 1.3 riastrad #else 374 1.1 riastrad ppgtt->pd_addr = (gen6_pte_t __iomem *)ggtt->gsm + ggtt_offset; 375 1.3 riastrad #endif 376 1.1 riastrad 377 1.1 riastrad gen6_flush_pd(ppgtt, 0, ppgtt->base.vm.total); 378 1.1 riastrad return 0; 379 1.1 riastrad } 380 1.1 riastrad 381 1.1 riastrad static void pd_vma_unbind(struct i915_vma *vma) 382 1.1 riastrad { 383 1.1 riastrad struct gen6_ppgtt *ppgtt = vma->private; 384 1.1 riastrad struct i915_page_directory * const pd = ppgtt->base.pd; 385 1.1 riastrad struct i915_page_dma * const scratch = 386 1.1 riastrad px_base(&ppgtt->base.vm.scratch[1]); 387 1.1 riastrad struct i915_page_table *pt; 388 1.1 riastrad unsigned int pde; 389 1.1 riastrad 390 1.1 riastrad if (!ppgtt->scan_for_unused_pt) 391 1.1 riastrad return; 392 1.1 riastrad 393 1.1 riastrad /* Free all no longer used page tables */ 394 1.1 riastrad gen6_for_all_pdes(pt, ppgtt->base.pd, pde) { 395 1.1 riastrad if (px_base(pt) == scratch || atomic_read(&pt->used)) 396 1.1 riastrad continue; 397 1.1 riastrad 398 1.1 riastrad free_px(&ppgtt->base.vm, pt); 399 1.1 riastrad pd->entry[pde] = scratch; 400 1.1 riastrad } 401 1.1 riastrad 402 1.1 riastrad ppgtt->scan_for_unused_pt = false; 403 1.1 riastrad } 404 1.1 riastrad 405 1.1 riastrad static const struct i915_vma_ops pd_vma_ops = { 406 1.1 riastrad .set_pages = pd_vma_set_pages, 407 1.1 riastrad .clear_pages = pd_vma_clear_pages, 408 1.1 riastrad .bind_vma = pd_vma_bind, 409 1.1 riastrad .unbind_vma = pd_vma_unbind, 410 1.1 riastrad }; 411 1.1 riastrad 412 1.1 riastrad static struct i915_vma *pd_vma_create(struct gen6_ppgtt *ppgtt, int size) 413 1.1 riastrad { 414 1.1 riastrad struct i915_ggtt *ggtt = ppgtt->base.vm.gt->ggtt; 415 1.1 riastrad struct i915_vma *vma; 416 1.1 riastrad 417 1.1 riastrad GEM_BUG_ON(!IS_ALIGNED(size, I915_GTT_PAGE_SIZE)); 418 1.1 riastrad GEM_BUG_ON(size > ggtt->vm.total); 419 1.1 riastrad 420 1.1 riastrad vma = i915_vma_alloc(); 421 1.1 riastrad if (!vma) 422 1.1 riastrad return ERR_PTR(-ENOMEM); 423 1.1 riastrad 424 1.1 riastrad i915_active_init(&vma->active, NULL, NULL); 425 1.1 riastrad 426 1.1 riastrad kref_init(&vma->ref); 427 1.1 riastrad mutex_init(&vma->pages_mutex); 428 1.1 riastrad vma->vm = i915_vm_get(&ggtt->vm); 429 1.1 riastrad vma->ops = &pd_vma_ops; 430 1.1 riastrad vma->private = ppgtt; 431 1.1 riastrad 432 1.1 riastrad vma->size = size; 433 1.1 riastrad vma->fence_size = size; 434 1.1 riastrad atomic_set(&vma->flags, I915_VMA_GGTT); 435 1.1 riastrad vma->ggtt_view.type = I915_GGTT_VIEW_ROTATED; /* prevent fencing */ 436 1.1 riastrad 437 1.1 riastrad INIT_LIST_HEAD(&vma->obj_link); 438 1.1 riastrad INIT_LIST_HEAD(&vma->closed_link); 439 1.1 riastrad 440 1.1 riastrad return vma; 441 1.1 riastrad } 442 1.1 riastrad 443 1.1 riastrad int gen6_ppgtt_pin(struct i915_ppgtt *base) 444 1.1 riastrad { 445 1.1 riastrad struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(base); 446 1.1 riastrad int err; 447 1.1 riastrad 448 1.1 riastrad GEM_BUG_ON(!atomic_read(&ppgtt->base.vm.open)); 449 1.1 riastrad 450 1.1 riastrad /* 451 1.1 riastrad * Workaround the limited maximum vma->pin_count and the aliasing_ppgtt 452 1.1 riastrad * which will be pinned into every active context. 453 1.1 riastrad * (When vma->pin_count becomes atomic, I expect we will naturally 454 1.1 riastrad * need a larger, unpacked, type and kill this redundancy.) 455 1.1 riastrad */ 456 1.1 riastrad if (atomic_add_unless(&ppgtt->pin_count, 1, 0)) 457 1.1 riastrad return 0; 458 1.1 riastrad 459 1.1 riastrad if (mutex_lock_interruptible(&ppgtt->pin_mutex)) 460 1.1 riastrad return -EINTR; 461 1.1 riastrad 462 1.1 riastrad /* 463 1.1 riastrad * PPGTT PDEs reside in the GGTT and consists of 512 entries. The 464 1.1 riastrad * allocator works in address space sizes, so it's multiplied by page 465 1.1 riastrad * size. We allocate at the top of the GTT to avoid fragmentation. 466 1.1 riastrad */ 467 1.1 riastrad err = 0; 468 1.1 riastrad if (!atomic_read(&ppgtt->pin_count)) 469 1.1 riastrad err = i915_ggtt_pin(ppgtt->vma, GEN6_PD_ALIGN, PIN_HIGH); 470 1.1 riastrad if (!err) 471 1.1 riastrad atomic_inc(&ppgtt->pin_count); 472 1.1 riastrad mutex_unlock(&ppgtt->pin_mutex); 473 1.1 riastrad 474 1.1 riastrad return err; 475 1.1 riastrad } 476 1.1 riastrad 477 1.1 riastrad void gen6_ppgtt_unpin(struct i915_ppgtt *base) 478 1.1 riastrad { 479 1.1 riastrad struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(base); 480 1.1 riastrad 481 1.1 riastrad GEM_BUG_ON(!atomic_read(&ppgtt->pin_count)); 482 1.1 riastrad if (atomic_dec_and_test(&ppgtt->pin_count)) 483 1.1 riastrad i915_vma_unpin(ppgtt->vma); 484 1.1 riastrad } 485 1.1 riastrad 486 1.1 riastrad void gen6_ppgtt_unpin_all(struct i915_ppgtt *base) 487 1.1 riastrad { 488 1.1 riastrad struct gen6_ppgtt *ppgtt = to_gen6_ppgtt(base); 489 1.1 riastrad 490 1.1 riastrad if (!atomic_read(&ppgtt->pin_count)) 491 1.1 riastrad return; 492 1.1 riastrad 493 1.1 riastrad i915_vma_unpin(ppgtt->vma); 494 1.1 riastrad atomic_set(&ppgtt->pin_count, 0); 495 1.1 riastrad } 496 1.1 riastrad 497 1.1 riastrad struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt) 498 1.1 riastrad { 499 1.1 riastrad struct i915_ggtt * const ggtt = gt->ggtt; 500 1.1 riastrad struct gen6_ppgtt *ppgtt; 501 1.1 riastrad int err; 502 1.1 riastrad 503 1.1 riastrad ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL); 504 1.1 riastrad if (!ppgtt) 505 1.1 riastrad return ERR_PTR(-ENOMEM); 506 1.1 riastrad 507 1.1 riastrad mutex_init(&ppgtt->flush); 508 1.1 riastrad mutex_init(&ppgtt->pin_mutex); 509 1.1 riastrad 510 1.1 riastrad ppgtt_init(&ppgtt->base, gt); 511 1.1 riastrad ppgtt->base.vm.top = 1; 512 1.1 riastrad 513 1.1 riastrad ppgtt->base.vm.bind_async_flags = I915_VMA_LOCAL_BIND; 514 1.1 riastrad ppgtt->base.vm.allocate_va_range = gen6_alloc_va_range; 515 1.1 riastrad ppgtt->base.vm.clear_range = gen6_ppgtt_clear_range; 516 1.1 riastrad ppgtt->base.vm.insert_entries = gen6_ppgtt_insert_entries; 517 1.1 riastrad ppgtt->base.vm.cleanup = gen6_ppgtt_cleanup; 518 1.1 riastrad 519 1.1 riastrad ppgtt->base.vm.pte_encode = ggtt->vm.pte_encode; 520 1.1 riastrad 521 1.1 riastrad ppgtt->base.pd = __alloc_pd(sizeof(*ppgtt->base.pd)); 522 1.1 riastrad if (!ppgtt->base.pd) { 523 1.1 riastrad err = -ENOMEM; 524 1.1 riastrad goto err_free; 525 1.1 riastrad } 526 1.1 riastrad 527 1.1 riastrad err = gen6_ppgtt_init_scratch(ppgtt); 528 1.1 riastrad if (err) 529 1.1 riastrad goto err_pd; 530 1.1 riastrad 531 1.1 riastrad ppgtt->vma = pd_vma_create(ppgtt, GEN6_PD_SIZE); 532 1.1 riastrad if (IS_ERR(ppgtt->vma)) { 533 1.1 riastrad err = PTR_ERR(ppgtt->vma); 534 1.1 riastrad goto err_scratch; 535 1.1 riastrad } 536 1.1 riastrad 537 1.1 riastrad return &ppgtt->base; 538 1.1 riastrad 539 1.1 riastrad err_scratch: 540 1.1 riastrad free_scratch(&ppgtt->base.vm); 541 1.1 riastrad err_pd: 542 1.6 riastrad spin_lock_destroy(&ppgtt->base.pd->lock); 543 1.1 riastrad kfree(ppgtt->base.pd); 544 1.1 riastrad err_free: 545 1.1 riastrad mutex_destroy(&ppgtt->pin_mutex); 546 1.1 riastrad kfree(ppgtt); 547 1.1 riastrad return ERR_PTR(err); 548 1.1 riastrad } 549