Branch data Line data Source code
1 : : // SPDX-License-Identifier: MIT
2 : : /*
3 : : * Copyright © 2020 Intel Corporation
4 : : */
5 : :
6 : : #include <linux/slab.h> /* fault-inject.h is not standalone! */
7 : :
8 : : #include <linux/fault-inject.h>
9 : :
10 : : #include "i915_trace.h"
11 : : #include "intel_gt.h"
12 : : #include "intel_gtt.h"
13 : :
14 : 0 : void stash_init(struct pagestash *stash)
15 : : {
16 : 0 : pagevec_init(&stash->pvec);
17 : 0 : spin_lock_init(&stash->lock);
18 : 0 : }
19 : :
20 : 0 : static struct page *stash_pop_page(struct pagestash *stash)
21 : : {
22 : 0 : struct page *page = NULL;
23 : :
24 : 0 : spin_lock(&stash->lock);
25 [ # # # # ]: 0 : if (likely(stash->pvec.nr))
26 : 0 : page = stash->pvec.pages[--stash->pvec.nr];
27 : 0 : spin_unlock(&stash->lock);
28 : :
29 : 0 : return page;
30 : : }
31 : :
32 : 0 : static void stash_push_pagevec(struct pagestash *stash, struct pagevec *pvec)
33 : : {
34 : 0 : unsigned int nr;
35 : :
36 : 0 : spin_lock_nested(&stash->lock, SINGLE_DEPTH_NESTING);
37 : :
38 : 0 : nr = min_t(typeof(nr), pvec->nr, pagevec_space(&stash->pvec));
39 : 0 : memcpy(stash->pvec.pages + stash->pvec.nr,
40 : 0 : pvec->pages + pvec->nr - nr,
41 : : sizeof(pvec->pages[0]) * nr);
42 : 0 : stash->pvec.nr += nr;
43 : :
44 : 0 : spin_unlock(&stash->lock);
45 : :
46 : 0 : pvec->nr -= nr;
47 : 0 : }
48 : :
49 : 0 : static struct page *vm_alloc_page(struct i915_address_space *vm, gfp_t gfp)
50 : : {
51 : 0 : struct pagevec stack;
52 : 0 : struct page *page;
53 : :
54 : 0 : if (I915_SELFTEST_ONLY(should_fail(&vm->fault_attr, 1)))
55 : : i915_gem_shrink_all(vm->i915);
56 : :
57 : 0 : page = stash_pop_page(&vm->free_pages);
58 [ # # ]: 0 : if (page)
59 : : return page;
60 : :
61 [ # # ]: 0 : if (!vm->pt_kmap_wc)
62 : 0 : return alloc_page(gfp);
63 : :
64 : : /* Look in our global stash of WC pages... */
65 : 0 : page = stash_pop_page(&vm->i915->mm.wc_stash);
66 [ # # ]: 0 : if (page)
67 : : return page;
68 : :
69 : : /*
70 : : * Otherwise batch allocate pages to amortize cost of set_pages_wc.
71 : : *
72 : : * We have to be careful as page allocation may trigger the shrinker
73 : : * (via direct reclaim) which will fill up the WC stash underneath us.
74 : : * So we add our WB pages into a temporary pvec on the stack and merge
75 : : * them into the WC stash after all the allocations are complete.
76 : : */
77 : 0 : pagevec_init(&stack);
78 : 0 : do {
79 : 0 : struct page *page;
80 : :
81 : 0 : page = alloc_page(gfp);
82 [ # # ]: 0 : if (unlikely(!page))
83 : : break;
84 : :
85 : 0 : stack.pages[stack.nr++] = page;
86 [ # # ]: 0 : } while (pagevec_space(&stack));
87 : :
88 [ # # # # ]: 0 : if (stack.nr && !set_pages_array_wc(stack.pages, stack.nr)) {
89 : 0 : page = stack.pages[--stack.nr];
90 : :
91 : : /* Merge spare WC pages to the global stash */
92 [ # # ]: 0 : if (stack.nr)
93 : 0 : stash_push_pagevec(&vm->i915->mm.wc_stash, &stack);
94 : :
95 : : /* Push any surplus WC pages onto the local VM stash */
96 [ # # ]: 0 : if (stack.nr)
97 : 0 : stash_push_pagevec(&vm->free_pages, &stack);
98 : : }
99 : :
100 : : /* Return unwanted leftovers */
101 [ # # ]: 0 : if (unlikely(stack.nr)) {
102 [ # # # # ]: 0 : WARN_ON_ONCE(set_pages_array_wb(stack.pages, stack.nr));
103 : 0 : __pagevec_release(&stack);
104 : : }
105 : :
106 : : return page;
107 : : }
108 : :
109 : 0 : static void vm_free_pages_release(struct i915_address_space *vm,
110 : : bool immediate)
111 : : {
112 : 0 : struct pagevec *pvec = &vm->free_pages.pvec;
113 : 0 : struct pagevec stack;
114 : :
115 : 0 : lockdep_assert_held(&vm->free_pages.lock);
116 : 0 : GEM_BUG_ON(!pagevec_count(pvec));
117 : :
118 [ # # ]: 0 : if (vm->pt_kmap_wc) {
119 : : /*
120 : : * When we use WC, first fill up the global stash and then
121 : : * only if full immediately free the overflow.
122 : : */
123 : 0 : stash_push_pagevec(&vm->i915->mm.wc_stash, pvec);
124 : :
125 : : /*
126 : : * As we have made some room in the VM's free_pages,
127 : : * we can wait for it to fill again. Unless we are
128 : : * inside i915_address_space_fini() and must
129 : : * immediately release the pages!
130 : : */
131 [ # # # # ]: 0 : if (pvec->nr <= (immediate ? 0 : PAGEVEC_SIZE - 1))
132 : 0 : return;
133 : :
134 : : /*
135 : : * We have to drop the lock to allow ourselves to sleep,
136 : : * so take a copy of the pvec and clear the stash for
137 : : * others to use it as we sleep.
138 : : */
139 : 0 : stack = *pvec;
140 : 0 : pagevec_reinit(pvec);
141 : 0 : spin_unlock(&vm->free_pages.lock);
142 : :
143 : 0 : pvec = &stack;
144 : 0 : set_pages_array_wb(pvec->pages, pvec->nr);
145 : :
146 : 0 : spin_lock(&vm->free_pages.lock);
147 : : }
148 : :
149 : 0 : __pagevec_release(pvec);
150 : : }
151 : :
152 : 0 : static void vm_free_page(struct i915_address_space *vm, struct page *page)
153 : : {
154 : : /*
155 : : * On !llc, we need to change the pages back to WB. We only do so
156 : : * in bulk, so we rarely need to change the page attributes here,
157 : : * but doing so requires a stop_machine() from deep inside arch/x86/mm.
158 : : * To make detection of the possible sleep more likely, use an
159 : : * unconditional might_sleep() for everybody.
160 : : */
161 : 0 : might_sleep();
162 : 0 : spin_lock(&vm->free_pages.lock);
163 [ # # ]: 0 : while (!pagevec_space(&vm->free_pages.pvec))
164 : 0 : vm_free_pages_release(vm, false);
165 : 0 : GEM_BUG_ON(pagevec_count(&vm->free_pages.pvec) >= PAGEVEC_SIZE);
166 : 0 : pagevec_add(&vm->free_pages.pvec, page);
167 : 0 : spin_unlock(&vm->free_pages.lock);
168 : 0 : }
169 : :
170 : 0 : void __i915_vm_close(struct i915_address_space *vm)
171 : : {
172 : 0 : struct i915_vma *vma, *vn;
173 : :
174 : 0 : mutex_lock(&vm->mutex);
175 [ # # ]: 0 : list_for_each_entry_safe(vma, vn, &vm->bound_list, vm_link) {
176 : 0 : struct drm_i915_gem_object *obj = vma->obj;
177 : :
178 : : /* Keep the obj (and hence the vma) alive as _we_ destroy it */
179 [ # # ]: 0 : if (!kref_get_unless_zero(&obj->base.refcount))
180 : 0 : continue;
181 : :
182 : 0 : atomic_and(~I915_VMA_PIN_MASK, &vma->flags);
183 [ # # ]: 0 : WARN_ON(__i915_vma_unbind(vma));
184 : 0 : __i915_vma_put(vma);
185 : :
186 : 0 : i915_gem_object_put(obj);
187 : : }
188 : 0 : GEM_BUG_ON(!list_empty(&vm->bound_list));
189 : 0 : mutex_unlock(&vm->mutex);
190 : 0 : }
191 : :
192 : 0 : void i915_address_space_fini(struct i915_address_space *vm)
193 : : {
194 : 0 : spin_lock(&vm->free_pages.lock);
195 [ # # ]: 0 : if (pagevec_count(&vm->free_pages.pvec))
196 : 0 : vm_free_pages_release(vm, true);
197 : 0 : GEM_BUG_ON(pagevec_count(&vm->free_pages.pvec));
198 : 0 : spin_unlock(&vm->free_pages.lock);
199 : :
200 : 0 : drm_mm_takedown(&vm->mm);
201 : :
202 : 0 : mutex_destroy(&vm->mutex);
203 : 0 : }
204 : :
205 : 0 : static void __i915_vm_release(struct work_struct *work)
206 : : {
207 : 0 : struct i915_address_space *vm =
208 : 0 : container_of(work, struct i915_address_space, rcu.work);
209 : :
210 : 0 : vm->cleanup(vm);
211 : 0 : i915_address_space_fini(vm);
212 : :
213 : 0 : kfree(vm);
214 : 0 : }
215 : :
216 : 0 : void i915_vm_release(struct kref *kref)
217 : : {
218 : 0 : struct i915_address_space *vm =
219 : 0 : container_of(kref, struct i915_address_space, ref);
220 : :
221 : 0 : GEM_BUG_ON(i915_is_ggtt(vm));
222 : 0 : trace_i915_ppgtt_release(vm);
223 : :
224 : 0 : queue_rcu_work(vm->i915->wq, &vm->rcu);
225 : 0 : }
226 : :
227 : 0 : void i915_address_space_init(struct i915_address_space *vm, int subclass)
228 : : {
229 : 0 : kref_init(&vm->ref);
230 : 0 : INIT_RCU_WORK(&vm->rcu, __i915_vm_release);
231 : 0 : atomic_set(&vm->open, 1);
232 : :
233 : : /*
234 : : * The vm->mutex must be reclaim safe (for use in the shrinker).
235 : : * Do a dummy acquire now under fs_reclaim so that any allocation
236 : : * attempt holding the lock is immediately reported by lockdep.
237 : : */
238 : 0 : mutex_init(&vm->mutex);
239 : 0 : lockdep_set_subclass(&vm->mutex, subclass);
240 : 0 : i915_gem_shrinker_taints_mutex(vm->i915, &vm->mutex);
241 : :
242 : 0 : GEM_BUG_ON(!vm->total);
243 : 0 : drm_mm_init(&vm->mm, 0, vm->total);
244 : 0 : vm->mm.head_node.color = I915_COLOR_UNEVICTABLE;
245 : :
246 : 0 : stash_init(&vm->free_pages);
247 : :
248 : 0 : INIT_LIST_HEAD(&vm->bound_list);
249 : 0 : }
250 : :
251 : 0 : void clear_pages(struct i915_vma *vma)
252 : : {
253 : 0 : GEM_BUG_ON(!vma->pages);
254 : :
255 [ # # ]: 0 : if (vma->pages != vma->obj->mm.pages) {
256 : 0 : sg_free_table(vma->pages);
257 : 0 : kfree(vma->pages);
258 : : }
259 : 0 : vma->pages = NULL;
260 : :
261 : 0 : memset(&vma->page_sizes, 0, sizeof(vma->page_sizes));
262 : 0 : }
263 : :
264 : : static int __setup_page_dma(struct i915_address_space *vm,
265 : : struct i915_page_dma *p,
266 : : gfp_t gfp)
267 : : {
268 : : p->page = vm_alloc_page(vm, gfp | I915_GFP_ALLOW_FAIL);
269 : : if (unlikely(!p->page))
270 : : return -ENOMEM;
271 : :
272 : : p->daddr = dma_map_page_attrs(vm->dma,
273 : : p->page, 0, PAGE_SIZE,
274 : : PCI_DMA_BIDIRECTIONAL,
275 : : DMA_ATTR_SKIP_CPU_SYNC |
276 : : DMA_ATTR_NO_WARN);
277 : : if (unlikely(dma_mapping_error(vm->dma, p->daddr))) {
278 : : vm_free_page(vm, p->page);
279 : : return -ENOMEM;
280 : : }
281 : :
282 : : return 0;
283 : : }
284 : :
285 : 0 : int setup_page_dma(struct i915_address_space *vm, struct i915_page_dma *p)
286 : : {
287 : 0 : return __setup_page_dma(vm, p, __GFP_HIGHMEM);
288 : : }
289 : :
290 : 0 : void cleanup_page_dma(struct i915_address_space *vm, struct i915_page_dma *p)
291 : : {
292 : 0 : dma_unmap_page(vm->dma, p->daddr, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
293 : 0 : vm_free_page(vm, p->page);
294 : 0 : }
295 : :
296 : : void
297 : 0 : fill_page_dma(const struct i915_page_dma *p, const u64 val, unsigned int count)
298 : : {
299 : 0 : kunmap_atomic(memset64(kmap_atomic(p->page), val, count));
300 : 0 : }
301 : :
302 : 0 : int setup_scratch_page(struct i915_address_space *vm, gfp_t gfp)
303 : : {
304 : 0 : unsigned long size;
305 : :
306 : : /*
307 : : * In order to utilize 64K pages for an object with a size < 2M, we will
308 : : * need to support a 64K scratch page, given that every 16th entry for a
309 : : * page-table operating in 64K mode must point to a properly aligned 64K
310 : : * region, including any PTEs which happen to point to scratch.
311 : : *
312 : : * This is only relevant for the 48b PPGTT where we support
313 : : * huge-gtt-pages, see also i915_vma_insert(). However, as we share the
314 : : * scratch (read-only) between all vm, we create one 64k scratch page
315 : : * for all.
316 : : */
317 : 0 : size = I915_GTT_PAGE_SIZE_4K;
318 [ # # ]: 0 : if (i915_vm_is_4lvl(vm) &&
319 [ # # ]: 0 : HAS_PAGE_SIZES(vm->i915, I915_GTT_PAGE_SIZE_64K)) {
320 : 0 : size = I915_GTT_PAGE_SIZE_64K;
321 : 0 : gfp |= __GFP_NOWARN;
322 : : }
323 : 0 : gfp |= __GFP_ZERO | __GFP_RETRY_MAYFAIL;
324 : :
325 : 0 : do {
326 : 0 : unsigned int order = get_order(size);
327 : 0 : struct page *page;
328 : 0 : dma_addr_t addr;
329 : :
330 : 0 : page = alloc_pages(gfp, order);
331 [ # # ]: 0 : if (unlikely(!page))
332 : 0 : goto skip;
333 : :
334 : 0 : addr = dma_map_page_attrs(vm->dma,
335 : : page, 0, size,
336 : : PCI_DMA_BIDIRECTIONAL,
337 : : DMA_ATTR_SKIP_CPU_SYNC |
338 : : DMA_ATTR_NO_WARN);
339 [ # # ]: 0 : if (unlikely(dma_mapping_error(vm->dma, addr)))
340 : 0 : goto free_page;
341 : :
342 [ # # ]: 0 : if (unlikely(!IS_ALIGNED(addr, size)))
343 : 0 : goto unmap_page;
344 : :
345 : 0 : vm->scratch[0].base.page = page;
346 : 0 : vm->scratch[0].base.daddr = addr;
347 : 0 : vm->scratch_order = order;
348 : 0 : return 0;
349 : :
350 : : unmap_page:
351 : 0 : dma_unmap_page(vm->dma, addr, size, PCI_DMA_BIDIRECTIONAL);
352 : 0 : free_page:
353 : 0 : __free_pages(page, order);
354 : 0 : skip:
355 [ # # ]: 0 : if (size == I915_GTT_PAGE_SIZE_4K)
356 : : return -ENOMEM;
357 : :
358 : 0 : size = I915_GTT_PAGE_SIZE_4K;
359 : 0 : gfp &= ~__GFP_NOWARN;
360 : 0 : } while (1);
361 : : }
362 : :
363 : 0 : void cleanup_scratch_page(struct i915_address_space *vm)
364 : : {
365 : 0 : struct i915_page_dma *p = px_base(&vm->scratch[0]);
366 : 0 : unsigned int order = vm->scratch_order;
367 : :
368 : 0 : dma_unmap_page(vm->dma, p->daddr, BIT(order) << PAGE_SHIFT,
369 : : PCI_DMA_BIDIRECTIONAL);
370 : 0 : __free_pages(p->page, order);
371 : 0 : }
372 : :
373 : 0 : void free_scratch(struct i915_address_space *vm)
374 : : {
375 : 0 : int i;
376 : :
377 [ # # ]: 0 : if (!px_dma(&vm->scratch[0])) /* set to 0 on clones */
378 : : return;
379 : :
380 [ # # ]: 0 : for (i = 1; i <= vm->top; i++) {
381 [ # # ]: 0 : if (!px_dma(&vm->scratch[i]))
382 : : break;
383 : 0 : cleanup_page_dma(vm, px_base(&vm->scratch[i]));
384 : : }
385 : :
386 : 0 : cleanup_scratch_page(vm);
387 : : }
388 : :
389 : 0 : void gtt_write_workarounds(struct intel_gt *gt)
390 : : {
391 : 0 : struct drm_i915_private *i915 = gt->i915;
392 : 0 : struct intel_uncore *uncore = gt->uncore;
393 : :
394 : : /*
395 : : * This function is for gtt related workarounds. This function is
396 : : * called on driver load and after a GPU reset, so you can place
397 : : * workarounds here even if they get overwritten by GPU reset.
398 : : */
399 : : /* WaIncreaseDefaultTLBEntries:chv,bdw,skl,bxt,kbl,glk,cfl,cnl,icl */
400 [ # # ]: 0 : if (IS_BROADWELL(i915))
401 : 0 : intel_uncore_write(uncore,
402 : : GEN8_L3_LRA_1_GPGPU,
403 : : GEN8_L3_LRA_1_GPGPU_DEFAULT_VALUE_BDW);
404 [ # # ]: 0 : else if (IS_CHERRYVIEW(i915))
405 : 0 : intel_uncore_write(uncore,
406 : : GEN8_L3_LRA_1_GPGPU,
407 : : GEN8_L3_LRA_1_GPGPU_DEFAULT_VALUE_CHV);
408 [ # # # # ]: 0 : else if (IS_GEN9_LP(i915))
409 : 0 : intel_uncore_write(uncore,
410 : : GEN8_L3_LRA_1_GPGPU,
411 : : GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_BXT);
412 [ # # ]: 0 : else if (INTEL_GEN(i915) >= 9 && INTEL_GEN(i915) <= 11)
413 : 0 : intel_uncore_write(uncore,
414 : : GEN8_L3_LRA_1_GPGPU,
415 : : GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_SKL);
416 : :
417 : : /*
418 : : * To support 64K PTEs we need to first enable the use of the
419 : : * Intermediate-Page-Size(IPS) bit of the PDE field via some magical
420 : : * mmio, otherwise the page-walker will simply ignore the IPS bit. This
421 : : * shouldn't be needed after GEN10.
422 : : *
423 : : * 64K pages were first introduced from BDW+, although technically they
424 : : * only *work* from gen9+. For pre-BDW we instead have the option for
425 : : * 32K pages, but we don't currently have any support for it in our
426 : : * driver.
427 : : */
428 [ # # ]: 0 : if (HAS_PAGE_SIZES(i915, I915_GTT_PAGE_SIZE_64K) &&
429 [ # # ]: 0 : INTEL_GEN(i915) <= 10)
430 : 0 : intel_uncore_rmw(uncore,
431 : 0 : GEN8_GAMW_ECO_DEV_RW_IA,
432 : : 0,
433 : : GAMW_ECO_ENABLE_64K_IPS_FIELD);
434 : :
435 [ # # ]: 0 : if (IS_GEN_RANGE(i915, 8, 11)) {
436 : 0 : bool can_use_gtt_cache = true;
437 : :
438 : : /*
439 : : * According to the BSpec if we use 2M/1G pages then we also
440 : : * need to disable the GTT cache. At least on BDW we can see
441 : : * visual corruption when using 2M pages, and not disabling the
442 : : * GTT cache.
443 : : */
444 [ # # ]: 0 : if (HAS_PAGE_SIZES(i915, I915_GTT_PAGE_SIZE_2M))
445 : 0 : can_use_gtt_cache = false;
446 : :
447 : : /* WaGttCachingOffByDefault */
448 : 0 : intel_uncore_write(uncore,
449 : : HSW_GTT_CACHE_EN,
450 : : can_use_gtt_cache ? GTT_CACHE_EN_ALL : 0);
451 [ # # # # : 0 : WARN_ON_ONCE(can_use_gtt_cache &&
# # # # ]
452 : : intel_uncore_read(uncore,
453 : : HSW_GTT_CACHE_EN) == 0);
454 : : }
455 : 0 : }
456 : :
457 : 0 : u64 gen8_pte_encode(dma_addr_t addr,
458 : : enum i915_cache_level level,
459 : : u32 flags)
460 : : {
461 : 0 : gen8_pte_t pte = addr | _PAGE_PRESENT | _PAGE_RW;
462 : :
463 [ # # ]: 0 : if (unlikely(flags & PTE_READ_ONLY))
464 : 0 : pte &= ~_PAGE_RW;
465 : :
466 [ # # # ]: 0 : switch (level) {
467 : 0 : case I915_CACHE_NONE:
468 : 0 : pte |= PPAT_UNCACHED;
469 : 0 : break;
470 : 0 : case I915_CACHE_WT:
471 : 0 : pte |= PPAT_DISPLAY_ELLC;
472 : 0 : break;
473 : 0 : default:
474 : 0 : pte |= PPAT_CACHED;
475 : 0 : break;
476 : : }
477 : :
478 : 0 : return pte;
479 : : }
480 : :
481 : 0 : static void tgl_setup_private_ppat(struct intel_uncore *uncore)
482 : : {
483 : : /* TGL doesn't support LLC or AGE settings */
484 : 0 : intel_uncore_write(uncore, GEN12_PAT_INDEX(0), GEN8_PPAT_WB);
485 : 0 : intel_uncore_write(uncore, GEN12_PAT_INDEX(1), GEN8_PPAT_WC);
486 : 0 : intel_uncore_write(uncore, GEN12_PAT_INDEX(2), GEN8_PPAT_WT);
487 : 0 : intel_uncore_write(uncore, GEN12_PAT_INDEX(3), GEN8_PPAT_UC);
488 : 0 : intel_uncore_write(uncore, GEN12_PAT_INDEX(4), GEN8_PPAT_WB);
489 : 0 : intel_uncore_write(uncore, GEN12_PAT_INDEX(5), GEN8_PPAT_WB);
490 : 0 : intel_uncore_write(uncore, GEN12_PAT_INDEX(6), GEN8_PPAT_WB);
491 : 0 : intel_uncore_write(uncore, GEN12_PAT_INDEX(7), GEN8_PPAT_WB);
492 : 0 : }
493 : :
494 : 0 : static void cnl_setup_private_ppat(struct intel_uncore *uncore)
495 : : {
496 : 0 : intel_uncore_write(uncore,
497 : : GEN10_PAT_INDEX(0),
498 : : GEN8_PPAT_WB | GEN8_PPAT_LLC);
499 : 0 : intel_uncore_write(uncore,
500 : : GEN10_PAT_INDEX(1),
501 : : GEN8_PPAT_WC | GEN8_PPAT_LLCELLC);
502 : 0 : intel_uncore_write(uncore,
503 : : GEN10_PAT_INDEX(2),
504 : : GEN8_PPAT_WT | GEN8_PPAT_LLCELLC);
505 : 0 : intel_uncore_write(uncore,
506 : : GEN10_PAT_INDEX(3),
507 : : GEN8_PPAT_UC);
508 : 0 : intel_uncore_write(uncore,
509 : : GEN10_PAT_INDEX(4),
510 : : GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0));
511 : 0 : intel_uncore_write(uncore,
512 : : GEN10_PAT_INDEX(5),
513 : : GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(1));
514 : 0 : intel_uncore_write(uncore,
515 : : GEN10_PAT_INDEX(6),
516 : : GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(2));
517 : 0 : intel_uncore_write(uncore,
518 : : GEN10_PAT_INDEX(7),
519 : : GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3));
520 : 0 : }
521 : :
522 : : /*
523 : : * The GGTT and PPGTT need a private PPAT setup in order to handle cacheability
524 : : * bits. When using advanced contexts each context stores its own PAT, but
525 : : * writing this data shouldn't be harmful even in those cases.
526 : : */
527 : 0 : static void bdw_setup_private_ppat(struct intel_uncore *uncore)
528 : : {
529 : 0 : u64 pat;
530 : :
531 : 0 : pat = GEN8_PPAT(0, GEN8_PPAT_WB | GEN8_PPAT_LLC) | /* for normal objects, no eLLC */
532 : : GEN8_PPAT(1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC) | /* for something pointing to ptes? */
533 : : GEN8_PPAT(2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC) | /* for scanout with eLLC */
534 : : GEN8_PPAT(3, GEN8_PPAT_UC) | /* Uncached objects, mostly for scanout */
535 : : GEN8_PPAT(4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0)) |
536 : : GEN8_PPAT(5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(1)) |
537 : : GEN8_PPAT(6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(2)) |
538 : : GEN8_PPAT(7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3));
539 : :
540 : 0 : intel_uncore_write(uncore, GEN8_PRIVATE_PAT_LO, lower_32_bits(pat));
541 : 0 : intel_uncore_write(uncore, GEN8_PRIVATE_PAT_HI, upper_32_bits(pat));
542 : 0 : }
543 : :
544 : 0 : static void chv_setup_private_ppat(struct intel_uncore *uncore)
545 : : {
546 : 0 : u64 pat;
547 : :
548 : : /*
549 : : * Map WB on BDW to snooped on CHV.
550 : : *
551 : : * Only the snoop bit has meaning for CHV, the rest is
552 : : * ignored.
553 : : *
554 : : * The hardware will never snoop for certain types of accesses:
555 : : * - CPU GTT (GMADR->GGTT->no snoop->memory)
556 : : * - PPGTT page tables
557 : : * - some other special cycles
558 : : *
559 : : * As with BDW, we also need to consider the following for GT accesses:
560 : : * "For GGTT, there is NO pat_sel[2:0] from the entry,
561 : : * so RTL will always use the value corresponding to
562 : : * pat_sel = 000".
563 : : * Which means we must set the snoop bit in PAT entry 0
564 : : * in order to keep the global status page working.
565 : : */
566 : :
567 : 0 : pat = GEN8_PPAT(0, CHV_PPAT_SNOOP) |
568 : : GEN8_PPAT(1, 0) |
569 : : GEN8_PPAT(2, 0) |
570 : : GEN8_PPAT(3, 0) |
571 : : GEN8_PPAT(4, CHV_PPAT_SNOOP) |
572 : : GEN8_PPAT(5, CHV_PPAT_SNOOP) |
573 : : GEN8_PPAT(6, CHV_PPAT_SNOOP) |
574 : : GEN8_PPAT(7, CHV_PPAT_SNOOP);
575 : :
576 : 0 : intel_uncore_write(uncore, GEN8_PRIVATE_PAT_LO, lower_32_bits(pat));
577 : 0 : intel_uncore_write(uncore, GEN8_PRIVATE_PAT_HI, upper_32_bits(pat));
578 : 0 : }
579 : :
580 : 0 : void setup_private_pat(struct intel_uncore *uncore)
581 : : {
582 : 0 : struct drm_i915_private *i915 = uncore->i915;
583 : :
584 : 0 : GEM_BUG_ON(INTEL_GEN(i915) < 8);
585 : :
586 [ # # ]: 0 : if (INTEL_GEN(i915) >= 12)
587 : 0 : tgl_setup_private_ppat(uncore);
588 [ # # ]: 0 : else if (INTEL_GEN(i915) >= 10)
589 : 0 : cnl_setup_private_ppat(uncore);
590 [ # # # # : 0 : else if (IS_CHERRYVIEW(i915) || IS_GEN9_LP(i915))
# # ]
591 : 0 : chv_setup_private_ppat(uncore);
592 : : else
593 : 0 : bdw_setup_private_ppat(uncore);
594 : 0 : }
595 : :
596 : : #if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
597 : : #include "selftests/mock_gtt.c"
598 : : #endif
|