blob: 4eb0e114a295acec59e8ad47a9488d83fba23a2b [file] [log] [blame]
Daniel Vetter76aaf222010-11-05 22:23:30 +01001/*
2 * Copyright © 2010 Daniel Vetter
Ben Widawskyc4ac5242014-02-19 22:05:47 -08003 * Copyright © 2011-2014 Intel Corporation
Daniel Vetter76aaf222010-11-05 22:23:30 +01004 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22 * IN THE SOFTWARE.
23 *
24 */
25
Chris Wilsonaae4a3d2017-02-13 17:15:44 +000026#include <linux/slab.h> /* fault-inject.h is not standalone! */
27
28#include <linux/fault-inject.h>
Chris Wilsone007b192017-01-11 11:23:10 +000029#include <linux/log2.h>
Chris Wilson606fec92017-01-11 11:23:12 +000030#include <linux/random.h>
Daniel Vetter0e46ce22014-01-08 16:10:27 +010031#include <linux/seq_file.h>
Chris Wilson5bab6f62015-10-23 18:43:32 +010032#include <linux/stop_machine.h>
Chris Wilsone007b192017-01-11 11:23:10 +000033
David Howells760285e2012-10-02 18:01:07 +010034#include <drm/drmP.h>
35#include <drm/i915_drm.h>
Chris Wilsone007b192017-01-11 11:23:10 +000036
Daniel Vetter76aaf222010-11-05 22:23:30 +010037#include "i915_drv.h"
Yu Zhang5dda8fa2015-02-10 19:05:48 +080038#include "i915_vgpu.h"
Daniel Vetter76aaf222010-11-05 22:23:30 +010039#include "i915_trace.h"
40#include "intel_drv.h"
Chris Wilsond07f0e52016-10-28 13:58:44 +010041#include "intel_frontbuffer.h"
Daniel Vetter76aaf222010-11-05 22:23:30 +010042
Chris Wilsonbb8f9cf2016-08-22 08:44:31 +010043#define I915_GFP_DMA (GFP_KERNEL | __GFP_HIGHMEM)
44
Tvrtko Ursulin45f8f692014-12-10 17:27:59 +000045/**
46 * DOC: Global GTT views
47 *
48 * Background and previous state
49 *
50 * Historically objects could exists (be bound) in global GTT space only as
51 * singular instances with a view representing all of the object's backing pages
52 * in a linear fashion. This view will be called a normal view.
53 *
54 * To support multiple views of the same object, where the number of mapped
55 * pages is not equal to the backing store, or where the layout of the pages
56 * is not linear, concept of a GGTT view was added.
57 *
58 * One example of an alternative view is a stereo display driven by a single
59 * image. In this case we would have a framebuffer looking like this
60 * (2x2 pages):
61 *
62 * 12
63 * 34
64 *
65 * Above would represent a normal GGTT view as normally mapped for GPU or CPU
66 * rendering. In contrast, fed to the display engine would be an alternative
67 * view which could look something like this:
68 *
69 * 1212
70 * 3434
71 *
72 * In this example both the size and layout of pages in the alternative view is
73 * different from the normal view.
74 *
75 * Implementation and usage
76 *
77 * GGTT views are implemented using VMAs and are distinguished via enum
78 * i915_ggtt_view_type and struct i915_ggtt_view.
79 *
80 * A new flavour of core GEM functions which work with GGTT bound objects were
Joonas Lahtinenec7adb62015-03-16 14:11:13 +020081 * added with the _ggtt_ infix, and sometimes with _view postfix to avoid
82 * renaming in large amounts of code. They take the struct i915_ggtt_view
83 * parameter encapsulating all metadata required to implement a view.
Tvrtko Ursulin45f8f692014-12-10 17:27:59 +000084 *
85 * As a helper for callers which are only interested in the normal view,
86 * globally const i915_ggtt_view_normal singleton instance exists. All old core
87 * GEM API functions, the ones not taking the view parameter, are operating on,
88 * or with the normal GGTT view.
89 *
90 * Code wanting to add or use a new GGTT view needs to:
91 *
92 * 1. Add a new enum with a suitable name.
93 * 2. Extend the metadata in the i915_ggtt_view structure if required.
94 * 3. Add support to i915_get_vma_pages().
95 *
96 * New views are required to build a scatter-gather table from within the
97 * i915_get_vma_pages function. This table is stored in the vma.ggtt_view and
98 * exists for the lifetime of an VMA.
99 *
100 * Core API is designed to have copy semantics which means that passed in
101 * struct i915_ggtt_view does not need to be persistent (left around after
102 * calling the core API functions).
103 *
104 */
105
Daniel Vetter70b9f6f2015-04-14 17:35:27 +0200106static int
107i915_get_ggtt_vma_pages(struct i915_vma *vma);
108
Chris Wilson7c3f86b2017-01-12 11:00:49 +0000109static void gen6_ggtt_invalidate(struct drm_i915_private *dev_priv)
110{
111 /* Note that as an uncached mmio write, this should flush the
112 * WCB of the writes into the GGTT before it triggers the invalidate.
113 */
114 I915_WRITE(GFX_FLSH_CNTL_GEN6, GFX_FLSH_CNTL_EN);
115}
116
117static void guc_ggtt_invalidate(struct drm_i915_private *dev_priv)
118{
119 gen6_ggtt_invalidate(dev_priv);
120 I915_WRITE(GEN8_GTCR, GEN8_GTCR_INVALIDATE);
121}
122
123static void gmch_ggtt_invalidate(struct drm_i915_private *dev_priv)
124{
125 intel_gtt_chipset_flush();
126}
127
128static inline void i915_ggtt_invalidate(struct drm_i915_private *i915)
129{
130 i915->ggtt.invalidate(i915);
131}
132
Chris Wilsonc0336662016-05-06 15:40:21 +0100133int intel_sanitize_enable_ppgtt(struct drm_i915_private *dev_priv,
134 int enable_ppgtt)
Daniel Vettercfa7c862014-04-29 11:53:58 +0200135{
Chris Wilson1893a712014-09-19 11:56:27 +0100136 bool has_aliasing_ppgtt;
137 bool has_full_ppgtt;
Michel Thierry1f9a99e2015-09-30 15:36:19 +0100138 bool has_full_48bit_ppgtt;
Chris Wilson1893a712014-09-19 11:56:27 +0100139
Michel Thierry9e1d0e62016-12-05 17:57:03 -0800140 has_aliasing_ppgtt = dev_priv->info.has_aliasing_ppgtt;
141 has_full_ppgtt = dev_priv->info.has_full_ppgtt;
142 has_full_48bit_ppgtt = dev_priv->info.has_full_48bit_ppgtt;
Chris Wilson1893a712014-09-19 11:56:27 +0100143
Zhi Wange320d402016-09-06 12:04:12 +0800144 if (intel_vgpu_active(dev_priv)) {
145 /* emulation is too hard */
146 has_full_ppgtt = false;
147 has_full_48bit_ppgtt = false;
148 }
Yu Zhang71ba2d62015-02-10 19:05:54 +0800149
Chris Wilson0e4ca102016-04-29 13:18:22 +0100150 if (!has_aliasing_ppgtt)
151 return 0;
152
Damien Lespiau70ee45e2014-11-14 15:05:59 +0000153 /*
154 * We don't allow disabling PPGTT for gen9+ as it's a requirement for
155 * execlists, the sole mechanism available to submit work.
156 */
Chris Wilsonc0336662016-05-06 15:40:21 +0100157 if (enable_ppgtt == 0 && INTEL_GEN(dev_priv) < 9)
Daniel Vettercfa7c862014-04-29 11:53:58 +0200158 return 0;
159
160 if (enable_ppgtt == 1)
161 return 1;
162
Chris Wilson1893a712014-09-19 11:56:27 +0100163 if (enable_ppgtt == 2 && has_full_ppgtt)
Daniel Vettercfa7c862014-04-29 11:53:58 +0200164 return 2;
165
Michel Thierry1f9a99e2015-09-30 15:36:19 +0100166 if (enable_ppgtt == 3 && has_full_48bit_ppgtt)
167 return 3;
168
Daniel Vetter93a25a92014-03-06 09:40:43 +0100169#ifdef CONFIG_INTEL_IOMMU
170 /* Disable ppgtt on SNB if VT-d is on. */
Chris Wilsonc0336662016-05-06 15:40:21 +0100171 if (IS_GEN6(dev_priv) && intel_iommu_gfx_mapped) {
Daniel Vetter93a25a92014-03-06 09:40:43 +0100172 DRM_INFO("Disabling PPGTT because VT-d is on\n");
Daniel Vettercfa7c862014-04-29 11:53:58 +0200173 return 0;
Daniel Vetter93a25a92014-03-06 09:40:43 +0100174 }
175#endif
176
Jesse Barnes62942ed2014-06-13 09:28:33 -0700177 /* Early VLV doesn't have this */
Chris Wilson91c8a322016-07-05 10:40:23 +0100178 if (IS_VALLEYVIEW(dev_priv) && dev_priv->drm.pdev->revision < 0xb) {
Jesse Barnes62942ed2014-06-13 09:28:33 -0700179 DRM_DEBUG_DRIVER("disabling PPGTT on pre-B3 step VLV\n");
180 return 0;
181 }
182
Zhi Wange320d402016-09-06 12:04:12 +0800183 if (INTEL_GEN(dev_priv) >= 8 && i915.enable_execlists && has_full_ppgtt)
Michel Thierry1f9a99e2015-09-30 15:36:19 +0100184 return has_full_48bit_ppgtt ? 3 : 2;
Michel Thierry2f82bbd2014-12-15 14:58:00 +0000185 else
186 return has_aliasing_ppgtt ? 1 : 0;
Daniel Vetter93a25a92014-03-06 09:40:43 +0100187}
188
Daniel Vetter70b9f6f2015-04-14 17:35:27 +0200189static int ppgtt_bind_vma(struct i915_vma *vma,
190 enum i915_cache_level cache_level,
191 u32 unused)
Daniel Vetter47552652015-04-14 17:35:24 +0200192{
193 u32 pte_flags = 0;
194
Chris Wilsona4f5ea62016-10-28 13:58:35 +0100195 vma->pages = vma->obj->mm.pages;
Chris Wilson247177d2016-08-15 10:48:47 +0100196
Daniel Vetter47552652015-04-14 17:35:24 +0200197 /* Currently applicable only to VLV */
198 if (vma->obj->gt_ro)
199 pte_flags |= PTE_READ_ONLY;
200
Chris Wilson247177d2016-08-15 10:48:47 +0100201 vma->vm->insert_entries(vma->vm, vma->pages, vma->node.start,
Daniel Vetter47552652015-04-14 17:35:24 +0200202 cache_level, pte_flags);
Daniel Vetter70b9f6f2015-04-14 17:35:27 +0200203
204 return 0;
Daniel Vetter47552652015-04-14 17:35:24 +0200205}
206
207static void ppgtt_unbind_vma(struct i915_vma *vma)
208{
209 vma->vm->clear_range(vma->vm,
210 vma->node.start,
Michał Winiarski4fb84d92016-10-13 14:02:40 +0200211 vma->size);
Daniel Vetter47552652015-04-14 17:35:24 +0200212}
Ben Widawsky6f65e292013-12-06 14:10:56 -0800213
Daniel Vetter2c642b02015-04-14 17:35:26 +0200214static gen8_pte_t gen8_pte_encode(dma_addr_t addr,
Michał Winiarski4fb84d92016-10-13 14:02:40 +0200215 enum i915_cache_level level)
Ben Widawsky94ec8f62013-11-02 21:07:18 -0700216{
Michał Winiarski4fb84d92016-10-13 14:02:40 +0200217 gen8_pte_t pte = _PAGE_PRESENT | _PAGE_RW;
Ben Widawsky94ec8f62013-11-02 21:07:18 -0700218 pte |= addr;
Ben Widawsky63c42e52014-04-18 18:04:27 -0300219
220 switch (level) {
221 case I915_CACHE_NONE:
Ben Widawskyfbe5d362013-11-04 19:56:49 -0800222 pte |= PPAT_UNCACHED_INDEX;
Ben Widawsky63c42e52014-04-18 18:04:27 -0300223 break;
224 case I915_CACHE_WT:
225 pte |= PPAT_DISPLAY_ELLC_INDEX;
226 break;
227 default:
228 pte |= PPAT_CACHED_INDEX;
229 break;
230 }
231
Ben Widawsky94ec8f62013-11-02 21:07:18 -0700232 return pte;
233}
234
Mika Kuoppalafe36f552015-06-25 18:35:16 +0300235static gen8_pde_t gen8_pde_encode(const dma_addr_t addr,
236 const enum i915_cache_level level)
Ben Widawskyb1fe6672013-11-04 21:20:14 -0800237{
Michel Thierry07749ef2015-03-16 16:00:54 +0000238 gen8_pde_t pde = _PAGE_PRESENT | _PAGE_RW;
Ben Widawskyb1fe6672013-11-04 21:20:14 -0800239 pde |= addr;
240 if (level != I915_CACHE_NONE)
241 pde |= PPAT_CACHED_PDE_INDEX;
242 else
243 pde |= PPAT_UNCACHED_INDEX;
244 return pde;
245}
246
Michel Thierry762d9932015-07-30 11:05:29 +0100247#define gen8_pdpe_encode gen8_pde_encode
248#define gen8_pml4e_encode gen8_pde_encode
249
Michel Thierry07749ef2015-03-16 16:00:54 +0000250static gen6_pte_t snb_pte_encode(dma_addr_t addr,
251 enum i915_cache_level level,
Michał Winiarski4fb84d92016-10-13 14:02:40 +0200252 u32 unused)
Ben Widawsky54d12522012-09-24 16:44:32 -0700253{
Michał Winiarski4fb84d92016-10-13 14:02:40 +0200254 gen6_pte_t pte = GEN6_PTE_VALID;
Ben Widawsky54d12522012-09-24 16:44:32 -0700255 pte |= GEN6_PTE_ADDR_ENCODE(addr);
Ben Widawskye7210c32012-10-19 09:33:22 -0700256
257 switch (level) {
Chris Wilson350ec882013-08-06 13:17:02 +0100258 case I915_CACHE_L3_LLC:
259 case I915_CACHE_LLC:
260 pte |= GEN6_PTE_CACHE_LLC;
261 break;
262 case I915_CACHE_NONE:
263 pte |= GEN6_PTE_UNCACHED;
264 break;
265 default:
Daniel Vetter5f77eeb2014-12-08 16:40:10 +0100266 MISSING_CASE(level);
Chris Wilson350ec882013-08-06 13:17:02 +0100267 }
268
269 return pte;
270}
271
Michel Thierry07749ef2015-03-16 16:00:54 +0000272static gen6_pte_t ivb_pte_encode(dma_addr_t addr,
273 enum i915_cache_level level,
Michał Winiarski4fb84d92016-10-13 14:02:40 +0200274 u32 unused)
Chris Wilson350ec882013-08-06 13:17:02 +0100275{
Michał Winiarski4fb84d92016-10-13 14:02:40 +0200276 gen6_pte_t pte = GEN6_PTE_VALID;
Chris Wilson350ec882013-08-06 13:17:02 +0100277 pte |= GEN6_PTE_ADDR_ENCODE(addr);
278
279 switch (level) {
280 case I915_CACHE_L3_LLC:
281 pte |= GEN7_PTE_CACHE_L3_LLC;
Ben Widawskye7210c32012-10-19 09:33:22 -0700282 break;
283 case I915_CACHE_LLC:
284 pte |= GEN6_PTE_CACHE_LLC;
285 break;
286 case I915_CACHE_NONE:
Kenneth Graunke91197082013-04-22 00:53:51 -0700287 pte |= GEN6_PTE_UNCACHED;
Ben Widawskye7210c32012-10-19 09:33:22 -0700288 break;
289 default:
Daniel Vetter5f77eeb2014-12-08 16:40:10 +0100290 MISSING_CASE(level);
Ben Widawskye7210c32012-10-19 09:33:22 -0700291 }
292
Ben Widawsky54d12522012-09-24 16:44:32 -0700293 return pte;
294}
295
Michel Thierry07749ef2015-03-16 16:00:54 +0000296static gen6_pte_t byt_pte_encode(dma_addr_t addr,
297 enum i915_cache_level level,
Michał Winiarski4fb84d92016-10-13 14:02:40 +0200298 u32 flags)
Kenneth Graunke93c34e72013-04-22 00:53:50 -0700299{
Michał Winiarski4fb84d92016-10-13 14:02:40 +0200300 gen6_pte_t pte = GEN6_PTE_VALID;
Kenneth Graunke93c34e72013-04-22 00:53:50 -0700301 pte |= GEN6_PTE_ADDR_ENCODE(addr);
302
Akash Goel24f3a8c2014-06-17 10:59:42 +0530303 if (!(flags & PTE_READ_ONLY))
304 pte |= BYT_PTE_WRITEABLE;
Kenneth Graunke93c34e72013-04-22 00:53:50 -0700305
306 if (level != I915_CACHE_NONE)
307 pte |= BYT_PTE_SNOOPED_BY_CPU_CACHES;
308
309 return pte;
310}
311
Michel Thierry07749ef2015-03-16 16:00:54 +0000312static gen6_pte_t hsw_pte_encode(dma_addr_t addr,
313 enum i915_cache_level level,
Michał Winiarski4fb84d92016-10-13 14:02:40 +0200314 u32 unused)
Kenneth Graunke91197082013-04-22 00:53:51 -0700315{
Michał Winiarski4fb84d92016-10-13 14:02:40 +0200316 gen6_pte_t pte = GEN6_PTE_VALID;
Ben Widawsky0d8ff152013-07-04 11:02:03 -0700317 pte |= HSW_PTE_ADDR_ENCODE(addr);
Kenneth Graunke91197082013-04-22 00:53:51 -0700318
319 if (level != I915_CACHE_NONE)
Ben Widawsky87a6b682013-08-04 23:47:29 -0700320 pte |= HSW_WB_LLC_AGE3;
Kenneth Graunke91197082013-04-22 00:53:51 -0700321
322 return pte;
323}
324
Michel Thierry07749ef2015-03-16 16:00:54 +0000325static gen6_pte_t iris_pte_encode(dma_addr_t addr,
326 enum i915_cache_level level,
Michał Winiarski4fb84d92016-10-13 14:02:40 +0200327 u32 unused)
Ben Widawsky4d15c142013-07-04 11:02:06 -0700328{
Michał Winiarski4fb84d92016-10-13 14:02:40 +0200329 gen6_pte_t pte = GEN6_PTE_VALID;
Ben Widawsky4d15c142013-07-04 11:02:06 -0700330 pte |= HSW_PTE_ADDR_ENCODE(addr);
331
Chris Wilson651d7942013-08-08 14:41:10 +0100332 switch (level) {
333 case I915_CACHE_NONE:
334 break;
335 case I915_CACHE_WT:
Chris Wilsonc51e9702013-11-22 10:37:53 +0000336 pte |= HSW_WT_ELLC_LLC_AGE3;
Chris Wilson651d7942013-08-08 14:41:10 +0100337 break;
338 default:
Chris Wilsonc51e9702013-11-22 10:37:53 +0000339 pte |= HSW_WB_ELLC_LLC_AGE3;
Chris Wilson651d7942013-08-08 14:41:10 +0100340 break;
341 }
Ben Widawsky4d15c142013-07-04 11:02:06 -0700342
343 return pte;
344}
345
Chris Wilson84486612017-02-15 08:43:40 +0000346static struct page *vm_alloc_page(struct i915_address_space *vm, gfp_t gfp)
Ben Widawsky678d96f2015-03-16 16:00:56 +0000347{
Chris Wilson84486612017-02-15 08:43:40 +0000348 struct page *page;
Ben Widawsky678d96f2015-03-16 16:00:56 +0000349
Chris Wilson84486612017-02-15 08:43:40 +0000350 if (I915_SELFTEST_ONLY(should_fail(&vm->fault_attr, 1)))
351 i915_gem_shrink_all(vm->i915);
Chris Wilsonaae4a3d2017-02-13 17:15:44 +0000352
Chris Wilson84486612017-02-15 08:43:40 +0000353 if (vm->free_pages.nr)
354 return vm->free_pages.pages[--vm->free_pages.nr];
355
356 page = alloc_page(gfp);
357 if (!page)
358 return NULL;
359
360 if (vm->pt_kmap_wc)
361 set_pages_array_wc(&page, 1);
362
363 return page;
364}
365
366static void vm_free_pages_release(struct i915_address_space *vm)
367{
368 GEM_BUG_ON(!pagevec_count(&vm->free_pages));
369
370 if (vm->pt_kmap_wc)
371 set_pages_array_wb(vm->free_pages.pages,
372 pagevec_count(&vm->free_pages));
373
374 __pagevec_release(&vm->free_pages);
375}
376
377static void vm_free_page(struct i915_address_space *vm, struct page *page)
378{
379 if (!pagevec_add(&vm->free_pages, page))
380 vm_free_pages_release(vm);
381}
382
383static int __setup_page_dma(struct i915_address_space *vm,
384 struct i915_page_dma *p,
385 gfp_t gfp)
386{
387 p->page = vm_alloc_page(vm, gfp | __GFP_NOWARN | __GFP_NORETRY);
388 if (unlikely(!p->page))
Michel Thierry1266cdb2015-03-24 17:06:33 +0000389 return -ENOMEM;
390
Chris Wilson84486612017-02-15 08:43:40 +0000391 p->daddr = dma_map_page(vm->dma, p->page, 0, PAGE_SIZE,
392 PCI_DMA_BIDIRECTIONAL);
393 if (unlikely(dma_mapping_error(vm->dma, p->daddr))) {
394 vm_free_page(vm, p->page);
395 return -ENOMEM;
Mika Kuoppala44159dd2015-06-25 18:35:07 +0300396 }
397
Michel Thierry1266cdb2015-03-24 17:06:33 +0000398 return 0;
Ben Widawsky678d96f2015-03-16 16:00:56 +0000399}
400
Chris Wilson84486612017-02-15 08:43:40 +0000401static int setup_page_dma(struct i915_address_space *vm,
Tvrtko Ursulin275a9912016-11-16 08:55:34 +0000402 struct i915_page_dma *p)
Mika Kuoppalac114f762015-06-25 18:35:13 +0300403{
Chris Wilson84486612017-02-15 08:43:40 +0000404 return __setup_page_dma(vm, p, I915_GFP_DMA);
Mika Kuoppalac114f762015-06-25 18:35:13 +0300405}
406
Chris Wilson84486612017-02-15 08:43:40 +0000407static void cleanup_page_dma(struct i915_address_space *vm,
Tvrtko Ursulin275a9912016-11-16 08:55:34 +0000408 struct i915_page_dma *p)
Mika Kuoppala44159dd2015-06-25 18:35:07 +0300409{
Chris Wilson84486612017-02-15 08:43:40 +0000410 dma_unmap_page(vm->dma, p->daddr, PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
411 vm_free_page(vm, p->page);
Mika Kuoppala44159dd2015-06-25 18:35:07 +0300412}
413
Mika Kuoppalad1c54ac2015-06-25 18:35:11 +0300414static void *kmap_page_dma(struct i915_page_dma *p)
Mika Kuoppala73eeea52015-06-25 18:35:10 +0300415{
Mika Kuoppalad1c54ac2015-06-25 18:35:11 +0300416 return kmap_atomic(p->page);
417}
Mika Kuoppala73eeea52015-06-25 18:35:10 +0300418
Mika Kuoppalad1c54ac2015-06-25 18:35:11 +0300419/* We use the flushing unmap only with ppgtt structures:
420 * page directories, page tables and scratch pages.
421 */
Chris Wilson84486612017-02-15 08:43:40 +0000422static void kunmap_page_dma(void *vaddr)
Mika Kuoppalad1c54ac2015-06-25 18:35:11 +0300423{
Mika Kuoppala73eeea52015-06-25 18:35:10 +0300424 kunmap_atomic(vaddr);
425}
426
Mika Kuoppala567047b2015-06-25 18:35:12 +0300427#define kmap_px(px) kmap_page_dma(px_base(px))
Chris Wilson84486612017-02-15 08:43:40 +0000428#define kunmap_px(vaddr) kunmap_page_dma((vaddr))
Mika Kuoppalad1c54ac2015-06-25 18:35:11 +0300429
Chris Wilson84486612017-02-15 08:43:40 +0000430#define setup_px(vm, px) setup_page_dma((vm), px_base(px))
431#define cleanup_px(vm, px) cleanup_page_dma((vm), px_base(px))
432#define fill_px(ppgtt, px, v) fill_page_dma((vm), px_base(px), (v))
433#define fill32_px(ppgtt, px, v) fill_page_dma_32((vm), px_base(px), (v))
Mika Kuoppala567047b2015-06-25 18:35:12 +0300434
Chris Wilson84486612017-02-15 08:43:40 +0000435static void fill_page_dma(struct i915_address_space *vm,
436 struct i915_page_dma *p,
437 const u64 val)
Mika Kuoppalad1c54ac2015-06-25 18:35:11 +0300438{
Chris Wilson84486612017-02-15 08:43:40 +0000439 u64 * const vaddr = kmap_page_dma(p);
Mika Kuoppalad1c54ac2015-06-25 18:35:11 +0300440 int i;
Mika Kuoppalad1c54ac2015-06-25 18:35:11 +0300441
442 for (i = 0; i < 512; i++)
443 vaddr[i] = val;
444
Chris Wilson84486612017-02-15 08:43:40 +0000445 kunmap_page_dma(vaddr);
Mika Kuoppalad1c54ac2015-06-25 18:35:11 +0300446}
447
Chris Wilson84486612017-02-15 08:43:40 +0000448static void fill_page_dma_32(struct i915_address_space *vm,
449 struct i915_page_dma *p,
450 const u32 v)
Mika Kuoppala73eeea52015-06-25 18:35:10 +0300451{
Chris Wilson84486612017-02-15 08:43:40 +0000452 fill_page_dma(vm, p, (u64)v << 32 | v);
Mika Kuoppala73eeea52015-06-25 18:35:10 +0300453}
454
Chris Wilson8bcdd0f72016-08-22 08:44:30 +0100455static int
Chris Wilson84486612017-02-15 08:43:40 +0000456setup_scratch_page(struct i915_address_space *vm, gfp_t gfp)
Mika Kuoppala4ad2af12015-06-30 18:16:39 +0300457{
Chris Wilson84486612017-02-15 08:43:40 +0000458 return __setup_page_dma(vm, &vm->scratch_page, gfp | __GFP_ZERO);
Mika Kuoppala4ad2af12015-06-30 18:16:39 +0300459}
460
Chris Wilson84486612017-02-15 08:43:40 +0000461static void cleanup_scratch_page(struct i915_address_space *vm)
Mika Kuoppala4ad2af12015-06-30 18:16:39 +0300462{
Chris Wilson84486612017-02-15 08:43:40 +0000463 cleanup_page_dma(vm, &vm->scratch_page);
Mika Kuoppala4ad2af12015-06-30 18:16:39 +0300464}
465
Chris Wilson84486612017-02-15 08:43:40 +0000466static struct i915_page_table *alloc_pt(struct i915_address_space *vm)
Ben Widawsky06fda602015-02-24 16:22:36 +0000467{
Michel Thierryec565b32015-04-08 12:13:23 +0100468 struct i915_page_table *pt;
Chris Wilson84486612017-02-15 08:43:40 +0000469 const size_t count = INTEL_GEN(vm->i915) >= 8 ? GEN8_PTES : GEN6_PTES;
Ben Widawsky678d96f2015-03-16 16:00:56 +0000470 int ret = -ENOMEM;
Ben Widawsky06fda602015-02-24 16:22:36 +0000471
472 pt = kzalloc(sizeof(*pt), GFP_KERNEL);
473 if (!pt)
474 return ERR_PTR(-ENOMEM);
475
Ben Widawsky678d96f2015-03-16 16:00:56 +0000476 pt->used_ptes = kcalloc(BITS_TO_LONGS(count), sizeof(*pt->used_ptes),
477 GFP_KERNEL);
478
479 if (!pt->used_ptes)
480 goto fail_bitmap;
481
Chris Wilson84486612017-02-15 08:43:40 +0000482 ret = setup_px(vm, pt);
Ben Widawsky678d96f2015-03-16 16:00:56 +0000483 if (ret)
Mika Kuoppala44159dd2015-06-25 18:35:07 +0300484 goto fail_page_m;
Ben Widawsky06fda602015-02-24 16:22:36 +0000485
486 return pt;
Ben Widawsky678d96f2015-03-16 16:00:56 +0000487
Mika Kuoppala44159dd2015-06-25 18:35:07 +0300488fail_page_m:
Ben Widawsky678d96f2015-03-16 16:00:56 +0000489 kfree(pt->used_ptes);
490fail_bitmap:
491 kfree(pt);
492
493 return ERR_PTR(ret);
Ben Widawsky06fda602015-02-24 16:22:36 +0000494}
495
Chris Wilson84486612017-02-15 08:43:40 +0000496static void free_pt(struct i915_address_space *vm, struct i915_page_table *pt)
Ben Widawsky06fda602015-02-24 16:22:36 +0000497{
Chris Wilson84486612017-02-15 08:43:40 +0000498 cleanup_px(vm, pt);
Mika Kuoppala2e906be2015-06-30 18:16:37 +0300499 kfree(pt->used_ptes);
500 kfree(pt);
501}
502
503static void gen8_initialize_pt(struct i915_address_space *vm,
504 struct i915_page_table *pt)
505{
506 gen8_pte_t scratch_pte;
507
Chris Wilson8bcdd0f72016-08-22 08:44:30 +0100508 scratch_pte = gen8_pte_encode(vm->scratch_page.daddr,
Michał Winiarski4fb84d92016-10-13 14:02:40 +0200509 I915_CACHE_LLC);
Mika Kuoppala2e906be2015-06-30 18:16:37 +0300510
Chris Wilson84486612017-02-15 08:43:40 +0000511 fill_px(vm, pt, scratch_pte);
Mika Kuoppala2e906be2015-06-30 18:16:37 +0300512}
513
514static void gen6_initialize_pt(struct i915_address_space *vm,
515 struct i915_page_table *pt)
516{
517 gen6_pte_t scratch_pte;
518
Chris Wilson8bcdd0f72016-08-22 08:44:30 +0100519 WARN_ON(vm->scratch_page.daddr == 0);
Mika Kuoppala2e906be2015-06-30 18:16:37 +0300520
Chris Wilson8bcdd0f72016-08-22 08:44:30 +0100521 scratch_pte = vm->pte_encode(vm->scratch_page.daddr,
Michał Winiarski4fb84d92016-10-13 14:02:40 +0200522 I915_CACHE_LLC, 0);
Mika Kuoppala2e906be2015-06-30 18:16:37 +0300523
Chris Wilson84486612017-02-15 08:43:40 +0000524 fill32_px(vm, pt, scratch_pte);
Ben Widawsky06fda602015-02-24 16:22:36 +0000525}
526
Chris Wilson84486612017-02-15 08:43:40 +0000527static struct i915_page_directory *alloc_pd(struct i915_address_space *vm)
Ben Widawsky06fda602015-02-24 16:22:36 +0000528{
Michel Thierryec565b32015-04-08 12:13:23 +0100529 struct i915_page_directory *pd;
Michel Thierry33c88192015-04-08 12:13:33 +0100530 int ret = -ENOMEM;
Ben Widawsky06fda602015-02-24 16:22:36 +0000531
532 pd = kzalloc(sizeof(*pd), GFP_KERNEL);
533 if (!pd)
534 return ERR_PTR(-ENOMEM);
535
Michel Thierry33c88192015-04-08 12:13:33 +0100536 pd->used_pdes = kcalloc(BITS_TO_LONGS(I915_PDES),
537 sizeof(*pd->used_pdes), GFP_KERNEL);
538 if (!pd->used_pdes)
Mika Kuoppalaa08e1112015-06-25 18:35:08 +0300539 goto fail_bitmap;
Michel Thierry33c88192015-04-08 12:13:33 +0100540
Chris Wilson84486612017-02-15 08:43:40 +0000541 ret = setup_px(vm, pd);
Michel Thierry33c88192015-04-08 12:13:33 +0100542 if (ret)
Mika Kuoppalaa08e1112015-06-25 18:35:08 +0300543 goto fail_page_m;
Michel Thierrye5815a22015-04-08 12:13:32 +0100544
Ben Widawsky06fda602015-02-24 16:22:36 +0000545 return pd;
Michel Thierry33c88192015-04-08 12:13:33 +0100546
Mika Kuoppalaa08e1112015-06-25 18:35:08 +0300547fail_page_m:
Michel Thierry33c88192015-04-08 12:13:33 +0100548 kfree(pd->used_pdes);
Mika Kuoppalaa08e1112015-06-25 18:35:08 +0300549fail_bitmap:
Michel Thierry33c88192015-04-08 12:13:33 +0100550 kfree(pd);
551
552 return ERR_PTR(ret);
Ben Widawsky06fda602015-02-24 16:22:36 +0000553}
554
Chris Wilson84486612017-02-15 08:43:40 +0000555static void free_pd(struct i915_address_space *vm,
Tvrtko Ursulin275a9912016-11-16 08:55:34 +0000556 struct i915_page_directory *pd)
Mika Kuoppala2e906be2015-06-30 18:16:37 +0300557{
558 if (px_page(pd)) {
Chris Wilson84486612017-02-15 08:43:40 +0000559 cleanup_px(vm, pd);
Mika Kuoppala2e906be2015-06-30 18:16:37 +0300560 kfree(pd->used_pdes);
561 kfree(pd);
562 }
563}
564
565static void gen8_initialize_pd(struct i915_address_space *vm,
566 struct i915_page_directory *pd)
567{
568 gen8_pde_t scratch_pde;
569
570 scratch_pde = gen8_pde_encode(px_dma(vm->scratch_pt), I915_CACHE_LLC);
571
Chris Wilson84486612017-02-15 08:43:40 +0000572 fill_px(vm, pd, scratch_pde);
Mika Kuoppala2e906be2015-06-30 18:16:37 +0300573}
574
Tvrtko Ursulin275a9912016-11-16 08:55:34 +0000575static int __pdp_init(struct drm_i915_private *dev_priv,
Michel Thierry6ac18502015-07-29 17:23:46 +0100576 struct i915_page_directory_pointer *pdp)
577{
Tvrtko Ursulin275a9912016-11-16 08:55:34 +0000578 size_t pdpes = I915_PDPES_PER_PDP(dev_priv);
Michel Thierry6ac18502015-07-29 17:23:46 +0100579
580 pdp->used_pdpes = kcalloc(BITS_TO_LONGS(pdpes),
581 sizeof(unsigned long),
582 GFP_KERNEL);
583 if (!pdp->used_pdpes)
584 return -ENOMEM;
585
586 pdp->page_directory = kcalloc(pdpes, sizeof(*pdp->page_directory),
587 GFP_KERNEL);
588 if (!pdp->page_directory) {
589 kfree(pdp->used_pdpes);
590 /* the PDP might be the statically allocated top level. Keep it
591 * as clean as possible */
592 pdp->used_pdpes = NULL;
593 return -ENOMEM;
594 }
595
596 return 0;
597}
598
599static void __pdp_fini(struct i915_page_directory_pointer *pdp)
600{
601 kfree(pdp->used_pdpes);
602 kfree(pdp->page_directory);
603 pdp->page_directory = NULL;
604}
605
Chris Wilson84486612017-02-15 08:43:40 +0000606static struct i915_page_directory_pointer *
607alloc_pdp(struct i915_address_space *vm)
Michel Thierry762d9932015-07-30 11:05:29 +0100608{
609 struct i915_page_directory_pointer *pdp;
610 int ret = -ENOMEM;
611
Chris Wilson84486612017-02-15 08:43:40 +0000612 WARN_ON(!USES_FULL_48BIT_PPGTT(vm->i915));
Michel Thierry762d9932015-07-30 11:05:29 +0100613
614 pdp = kzalloc(sizeof(*pdp), GFP_KERNEL);
615 if (!pdp)
616 return ERR_PTR(-ENOMEM);
617
Chris Wilson84486612017-02-15 08:43:40 +0000618 ret = __pdp_init(vm->i915, pdp);
Michel Thierry762d9932015-07-30 11:05:29 +0100619 if (ret)
620 goto fail_bitmap;
621
Chris Wilson84486612017-02-15 08:43:40 +0000622 ret = setup_px(vm, pdp);
Michel Thierry762d9932015-07-30 11:05:29 +0100623 if (ret)
624 goto fail_page_m;
625
626 return pdp;
627
628fail_page_m:
629 __pdp_fini(pdp);
630fail_bitmap:
631 kfree(pdp);
632
633 return ERR_PTR(ret);
634}
635
Chris Wilson84486612017-02-15 08:43:40 +0000636static void free_pdp(struct i915_address_space *vm,
Michel Thierry6ac18502015-07-29 17:23:46 +0100637 struct i915_page_directory_pointer *pdp)
638{
639 __pdp_fini(pdp);
Chris Wilson84486612017-02-15 08:43:40 +0000640 if (USES_FULL_48BIT_PPGTT(vm->i915)) {
641 cleanup_px(vm, pdp);
Michel Thierry762d9932015-07-30 11:05:29 +0100642 kfree(pdp);
643 }
644}
645
Michel Thierry69ab76f2015-07-29 17:23:55 +0100646static void gen8_initialize_pdp(struct i915_address_space *vm,
647 struct i915_page_directory_pointer *pdp)
648{
649 gen8_ppgtt_pdpe_t scratch_pdpe;
650
651 scratch_pdpe = gen8_pdpe_encode(px_dma(vm->scratch_pd), I915_CACHE_LLC);
652
Chris Wilson84486612017-02-15 08:43:40 +0000653 fill_px(vm, pdp, scratch_pdpe);
Michel Thierry69ab76f2015-07-29 17:23:55 +0100654}
655
656static void gen8_initialize_pml4(struct i915_address_space *vm,
657 struct i915_pml4 *pml4)
658{
659 gen8_ppgtt_pml4e_t scratch_pml4e;
660
661 scratch_pml4e = gen8_pml4e_encode(px_dma(vm->scratch_pdp),
662 I915_CACHE_LLC);
663
Chris Wilson84486612017-02-15 08:43:40 +0000664 fill_px(vm, pml4, scratch_pml4e);
Michel Thierry69ab76f2015-07-29 17:23:55 +0100665}
666
Michel Thierry762d9932015-07-30 11:05:29 +0100667static void
Matthew Auld5c693b22016-12-13 16:05:10 +0000668gen8_setup_pdpe(struct i915_hw_ppgtt *ppgtt,
669 struct i915_page_directory_pointer *pdp,
670 struct i915_page_directory *pd,
671 int index)
Michel Thierry762d9932015-07-30 11:05:29 +0100672{
673 gen8_ppgtt_pdpe_t *page_directorypo;
674
Tvrtko Ursulin275a9912016-11-16 08:55:34 +0000675 if (!USES_FULL_48BIT_PPGTT(to_i915(ppgtt->base.dev)))
Michel Thierry762d9932015-07-30 11:05:29 +0100676 return;
677
678 page_directorypo = kmap_px(pdp);
679 page_directorypo[index] = gen8_pdpe_encode(px_dma(pd), I915_CACHE_LLC);
Chris Wilson84486612017-02-15 08:43:40 +0000680 kunmap_px(page_directorypo);
Michel Thierry762d9932015-07-30 11:05:29 +0100681}
682
683static void
Chris Wilson84486612017-02-15 08:43:40 +0000684gen8_setup_pml4e(struct i915_pml4 *pml4,
Matthew Auld56843102016-12-13 16:05:11 +0000685 struct i915_page_directory_pointer *pdp,
686 int index)
Michel Thierry762d9932015-07-30 11:05:29 +0100687{
688 gen8_ppgtt_pml4e_t *pagemap = kmap_px(pml4);
689
Michel Thierry762d9932015-07-30 11:05:29 +0100690 pagemap[index] = gen8_pml4e_encode(px_dma(pdp), I915_CACHE_LLC);
Chris Wilson84486612017-02-15 08:43:40 +0000691 kunmap_px(pagemap);
Michel Thierry6ac18502015-07-29 17:23:46 +0100692}
693
Ben Widawsky94e409c2013-11-04 22:29:36 -0800694/* Broadwell Page Directory Pointer Descriptors */
John Harrisone85b26d2015-05-29 17:43:56 +0100695static int gen8_write_pdp(struct drm_i915_gem_request *req,
Michel Thierry7cb6d7a2015-04-08 12:13:29 +0100696 unsigned entry,
697 dma_addr_t addr)
Ben Widawsky94e409c2013-11-04 22:29:36 -0800698{
Tvrtko Ursulin4a570db2016-03-16 11:00:38 +0000699 struct intel_engine_cs *engine = req->engine;
Tvrtko Ursulin73dec952017-02-14 11:32:42 +0000700 u32 *cs;
Ben Widawsky94e409c2013-11-04 22:29:36 -0800701
702 BUG_ON(entry >= 4);
703
Tvrtko Ursulin73dec952017-02-14 11:32:42 +0000704 cs = intel_ring_begin(req, 6);
705 if (IS_ERR(cs))
706 return PTR_ERR(cs);
Ben Widawsky94e409c2013-11-04 22:29:36 -0800707
Tvrtko Ursulin73dec952017-02-14 11:32:42 +0000708 *cs++ = MI_LOAD_REGISTER_IMM(1);
709 *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_UDW(engine, entry));
710 *cs++ = upper_32_bits(addr);
711 *cs++ = MI_LOAD_REGISTER_IMM(1);
712 *cs++ = i915_mmio_reg_offset(GEN8_RING_PDP_LDW(engine, entry));
713 *cs++ = lower_32_bits(addr);
714 intel_ring_advance(req, cs);
Ben Widawsky94e409c2013-11-04 22:29:36 -0800715
716 return 0;
717}
718
Michel Thierry2dba3232015-07-30 11:06:23 +0100719static int gen8_legacy_mm_switch(struct i915_hw_ppgtt *ppgtt,
720 struct drm_i915_gem_request *req)
Ben Widawsky94e409c2013-11-04 22:29:36 -0800721{
Ben Widawskyeeb94882013-12-06 14:11:10 -0800722 int i, ret;
Ben Widawsky94e409c2013-11-04 22:29:36 -0800723
Michel Thierry7cb6d7a2015-04-08 12:13:29 +0100724 for (i = GEN8_LEGACY_PDPES - 1; i >= 0; i--) {
Mika Kuoppalad852c7b2015-06-25 18:35:06 +0300725 const dma_addr_t pd_daddr = i915_page_dir_dma_addr(ppgtt, i);
726
John Harrisone85b26d2015-05-29 17:43:56 +0100727 ret = gen8_write_pdp(req, i, pd_daddr);
Ben Widawskyeeb94882013-12-06 14:11:10 -0800728 if (ret)
729 return ret;
Ben Widawsky94e409c2013-11-04 22:29:36 -0800730 }
Ben Widawskyd595bd42013-11-25 09:54:32 -0800731
Ben Widawskyeeb94882013-12-06 14:11:10 -0800732 return 0;
Ben Widawsky94e409c2013-11-04 22:29:36 -0800733}
734
Michel Thierry2dba3232015-07-30 11:06:23 +0100735static int gen8_48b_mm_switch(struct i915_hw_ppgtt *ppgtt,
736 struct drm_i915_gem_request *req)
737{
738 return gen8_write_pdp(req, 0, px_dma(&ppgtt->pml4));
739}
740
Mika Kuoppalafce93752016-10-31 17:24:46 +0200741/* PDE TLBs are a pain to invalidate on GEN8+. When we modify
742 * the page table structures, we mark them dirty so that
743 * context switching/execlist queuing code takes extra steps
744 * to ensure that tlbs are flushed.
745 */
746static void mark_tlbs_dirty(struct i915_hw_ppgtt *ppgtt)
747{
Chris Wilson49d73912016-11-29 09:50:08 +0000748 ppgtt->pd_dirty_rings = INTEL_INFO(ppgtt->base.i915)->ring_mask;
Mika Kuoppalafce93752016-10-31 17:24:46 +0200749}
750
Michał Winiarski2ce51792016-10-13 14:02:42 +0200751/* Removes entries from a single page table, releasing it if it's empty.
752 * Caller can use the return value to update higher-level entries.
753 */
754static bool gen8_ppgtt_clear_pt(struct i915_address_space *vm,
Michał Winiarskid209b9c2016-10-13 14:02:41 +0200755 struct i915_page_table *pt,
756 uint64_t start,
757 uint64_t length)
Ben Widawsky459108b2013-11-02 21:07:23 -0700758{
Michał Winiarskid209b9c2016-10-13 14:02:41 +0200759 unsigned int num_entries = gen8_pte_count(start, length);
Mika Kuoppala37c63932016-11-01 15:27:36 +0200760 unsigned int pte = gen8_pte_index(start);
761 unsigned int pte_end = pte + num_entries;
Chris Wilson894cceb2017-02-15 08:43:37 +0000762 const gen8_pte_t scratch_pte =
763 gen8_pte_encode(vm->scratch_page.daddr, I915_CACHE_LLC);
764 gen8_pte_t *vaddr;
Michał Winiarskid209b9c2016-10-13 14:02:41 +0200765
766 if (WARN_ON(!px_page(pt)))
Michał Winiarski2ce51792016-10-13 14:02:42 +0200767 return false;
Ben Widawsky459108b2013-11-02 21:07:23 -0700768
Mika Kuoppala37c63932016-11-01 15:27:36 +0200769 GEM_BUG_ON(pte_end > GEN8_PTES);
770
771 bitmap_clear(pt->used_ptes, pte, num_entries);
Zhi Wange81ecb52017-02-08 21:03:33 +0800772 if (USES_FULL_PPGTT(vm->i915)) {
773 if (bitmap_empty(pt->used_ptes, GEN8_PTES))
774 return true;
775 }
Michał Winiarski2ce51792016-10-13 14:02:42 +0200776
Chris Wilson894cceb2017-02-15 08:43:37 +0000777 vaddr = kmap_px(pt);
Mika Kuoppala37c63932016-11-01 15:27:36 +0200778 while (pte < pte_end)
Chris Wilson894cceb2017-02-15 08:43:37 +0000779 vaddr[pte++] = scratch_pte;
Chris Wilson84486612017-02-15 08:43:40 +0000780 kunmap_px(vaddr);
Michał Winiarski2ce51792016-10-13 14:02:42 +0200781
782 return false;
Michał Winiarskid209b9c2016-10-13 14:02:41 +0200783}
784
Michał Winiarski2ce51792016-10-13 14:02:42 +0200785/* Removes entries from a single page dir, releasing it if it's empty.
786 * Caller can use the return value to update higher-level entries
787 */
788static bool gen8_ppgtt_clear_pd(struct i915_address_space *vm,
Michał Winiarskid209b9c2016-10-13 14:02:41 +0200789 struct i915_page_directory *pd,
790 uint64_t start,
791 uint64_t length)
792{
793 struct i915_page_table *pt;
794 uint64_t pde;
Michał Winiarski2ce51792016-10-13 14:02:42 +0200795 gen8_pde_t *pde_vaddr;
796 gen8_pde_t scratch_pde = gen8_pde_encode(px_dma(vm->scratch_pt),
797 I915_CACHE_LLC);
Michał Winiarskid209b9c2016-10-13 14:02:41 +0200798
799 gen8_for_each_pde(pt, pd, start, length, pde) {
Ben Widawsky06fda602015-02-24 16:22:36 +0000800 if (WARN_ON(!pd->page_table[pde]))
Michel Thierry00245262015-06-25 12:59:38 +0100801 break;
Ben Widawsky06fda602015-02-24 16:22:36 +0000802
Michał Winiarski2ce51792016-10-13 14:02:42 +0200803 if (gen8_ppgtt_clear_pt(vm, pt, start, length)) {
804 __clear_bit(pde, pd->used_pdes);
805 pde_vaddr = kmap_px(pd);
806 pde_vaddr[pde] = scratch_pde;
Chris Wilson84486612017-02-15 08:43:40 +0000807 kunmap_px(pde_vaddr);
808 free_pt(vm, pt);
Michał Winiarski2ce51792016-10-13 14:02:42 +0200809 }
Michał Winiarskid209b9c2016-10-13 14:02:41 +0200810 }
Michał Winiarski2ce51792016-10-13 14:02:42 +0200811
Zhi Wanga18dbba2016-11-29 14:55:16 +0800812 if (bitmap_empty(pd->used_pdes, I915_PDES))
Michał Winiarski2ce51792016-10-13 14:02:42 +0200813 return true;
Michał Winiarski2ce51792016-10-13 14:02:42 +0200814
815 return false;
Michał Winiarskid209b9c2016-10-13 14:02:41 +0200816}
Ben Widawsky06fda602015-02-24 16:22:36 +0000817
Michał Winiarski2ce51792016-10-13 14:02:42 +0200818/* Removes entries from a single page dir pointer, releasing it if it's empty.
819 * Caller can use the return value to update higher-level entries
820 */
821static bool gen8_ppgtt_clear_pdp(struct i915_address_space *vm,
Michał Winiarskid209b9c2016-10-13 14:02:41 +0200822 struct i915_page_directory_pointer *pdp,
823 uint64_t start,
824 uint64_t length)
825{
Michał Winiarski2ce51792016-10-13 14:02:42 +0200826 struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
Michał Winiarskid209b9c2016-10-13 14:02:41 +0200827 struct i915_page_directory *pd;
828 uint64_t pdpe;
829
830 gen8_for_each_pdpe(pd, pdp, start, length, pdpe) {
831 if (WARN_ON(!pdp->page_directory[pdpe]))
Michel Thierry00245262015-06-25 12:59:38 +0100832 break;
Ben Widawsky06fda602015-02-24 16:22:36 +0000833
Michał Winiarski2ce51792016-10-13 14:02:42 +0200834 if (gen8_ppgtt_clear_pd(vm, pd, start, length)) {
835 __clear_bit(pdpe, pdp->used_pdpes);
Matthew Auld9e65a372016-12-13 16:05:12 +0000836 gen8_setup_pdpe(ppgtt, pdp, vm->scratch_pd, pdpe);
Chris Wilson84486612017-02-15 08:43:40 +0000837 free_pd(vm, pd);
Michał Winiarski2ce51792016-10-13 14:02:42 +0200838 }
Michał Winiarskid209b9c2016-10-13 14:02:41 +0200839 }
Michał Winiarski2ce51792016-10-13 14:02:42 +0200840
Mika Kuoppalafce93752016-10-31 17:24:46 +0200841 mark_tlbs_dirty(ppgtt);
842
Zhi Wanga18dbba2016-11-29 14:55:16 +0800843 if (bitmap_empty(pdp->used_pdpes, I915_PDPES_PER_PDP(dev_priv)))
Michał Winiarski2ce51792016-10-13 14:02:42 +0200844 return true;
Michał Winiarski2ce51792016-10-13 14:02:42 +0200845
846 return false;
Michał Winiarskid209b9c2016-10-13 14:02:41 +0200847}
Ben Widawsky459108b2013-11-02 21:07:23 -0700848
Michał Winiarski2ce51792016-10-13 14:02:42 +0200849/* Removes entries from a single pml4.
850 * This is the top-level structure in 4-level page tables used on gen8+.
851 * Empty entries are always scratch pml4e.
852 */
Michał Winiarskid209b9c2016-10-13 14:02:41 +0200853static void gen8_ppgtt_clear_pml4(struct i915_address_space *vm,
854 struct i915_pml4 *pml4,
855 uint64_t start,
856 uint64_t length)
857{
858 struct i915_page_directory_pointer *pdp;
859 uint64_t pml4e;
Michał Winiarski2ce51792016-10-13 14:02:42 +0200860
Chris Wilson49d73912016-11-29 09:50:08 +0000861 GEM_BUG_ON(!USES_FULL_48BIT_PPGTT(vm->i915));
Ben Widawsky459108b2013-11-02 21:07:23 -0700862
Michał Winiarskid209b9c2016-10-13 14:02:41 +0200863 gen8_for_each_pml4e(pdp, pml4, start, length, pml4e) {
864 if (WARN_ON(!pml4->pdps[pml4e]))
865 break;
Ben Widawsky459108b2013-11-02 21:07:23 -0700866
Michał Winiarski2ce51792016-10-13 14:02:42 +0200867 if (gen8_ppgtt_clear_pdp(vm, pdp, start, length)) {
868 __clear_bit(pml4e, pml4->used_pml4es);
Chris Wilson84486612017-02-15 08:43:40 +0000869 gen8_setup_pml4e(pml4, vm->scratch_pdp, pml4e);
870 free_pdp(vm, pdp);
Michał Winiarski2ce51792016-10-13 14:02:42 +0200871 }
Ben Widawsky459108b2013-11-02 21:07:23 -0700872 }
873}
874
Michel Thierryf9b5b782015-07-30 11:02:49 +0100875static void gen8_ppgtt_clear_range(struct i915_address_space *vm,
Michał Winiarski4fb84d92016-10-13 14:02:40 +0200876 uint64_t start, uint64_t length)
Ben Widawsky9df15b42013-11-02 21:07:24 -0700877{
Joonas Lahtinene5716f52016-04-07 11:08:03 +0300878 struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
Michel Thierryf9b5b782015-07-30 11:02:49 +0100879
Chris Wilsonc6385c92016-11-29 12:42:05 +0000880 if (USES_FULL_48BIT_PPGTT(vm->i915))
Michał Winiarskid209b9c2016-10-13 14:02:41 +0200881 gen8_ppgtt_clear_pml4(vm, &ppgtt->pml4, start, length);
882 else
883 gen8_ppgtt_clear_pdp(vm, &ppgtt->pdp, start, length);
Michel Thierryf9b5b782015-07-30 11:02:49 +0100884}
885
Chris Wilson894cceb2017-02-15 08:43:37 +0000886struct sgt_dma {
887 struct scatterlist *sg;
888 dma_addr_t dma, max;
889};
890
891static __always_inline bool
892gen8_ppgtt_insert_pte_entries(struct i915_hw_ppgtt *ppgtt,
Michel Thierryf9b5b782015-07-30 11:02:49 +0100893 struct i915_page_directory_pointer *pdp,
Chris Wilson894cceb2017-02-15 08:43:37 +0000894 struct sgt_dma *iter,
895 u64 start,
Michel Thierryf9b5b782015-07-30 11:02:49 +0100896 enum i915_cache_level cache_level)
897{
Chris Wilson894cceb2017-02-15 08:43:37 +0000898 unsigned int pdpe = gen8_pdpe_index(start);
899 unsigned int pde = gen8_pde_index(start);
900 unsigned int pte = gen8_pte_index(start);
901 struct i915_page_directory *pd;
902 const gen8_pte_t pte_encode = gen8_pte_encode(0, cache_level);
903 gen8_pte_t *vaddr;
904 bool ret;
Ben Widawsky9df15b42013-11-02 21:07:24 -0700905
Chris Wilson894cceb2017-02-15 08:43:37 +0000906 pd = pdp->page_directory[pdpe];
907 vaddr = kmap_px(pd->page_table[pde]);
908 do {
909 vaddr[pte] = pte_encode | iter->dma;
910 iter->dma += PAGE_SIZE;
911 if (iter->dma >= iter->max) {
912 iter->sg = __sg_next(iter->sg);
913 if (!iter->sg) {
914 ret = false;
915 break;
916 }
Ben Widawsky9df15b42013-11-02 21:07:24 -0700917
Chris Wilson894cceb2017-02-15 08:43:37 +0000918 iter->dma = sg_dma_address(iter->sg);
919 iter->max = iter->dma + iter->sg->length;
Ben Widawskyd7b3de92015-02-24 16:22:34 +0000920 }
Ben Widawsky7ad47cf2014-02-20 11:51:21 -0800921
Michel Thierry07749ef2015-03-16 16:00:54 +0000922 if (++pte == GEN8_PTES) {
Michel Thierry07749ef2015-03-16 16:00:54 +0000923 if (++pde == I915_PDES) {
Chris Wilson894cceb2017-02-15 08:43:37 +0000924 /* Limited by sg length for 3lvl */
925 if (++pdpe == GEN8_PML4ES_PER_PML4) {
926 ret = true;
Michel Thierryde5ba8e2015-08-03 09:53:27 +0100927 break;
Chris Wilson894cceb2017-02-15 08:43:37 +0000928 }
929
930 GEM_BUG_ON(pdpe > GEN8_LEGACY_PDPES);
931 pd = pdp->page_directory[pdpe];
Ben Widawsky7ad47cf2014-02-20 11:51:21 -0800932 pde = 0;
933 }
Chris Wilson894cceb2017-02-15 08:43:37 +0000934
Chris Wilson84486612017-02-15 08:43:40 +0000935 kunmap_px(vaddr);
Chris Wilson894cceb2017-02-15 08:43:37 +0000936 vaddr = kmap_px(pd->page_table[pde]);
Ben Widawsky7ad47cf2014-02-20 11:51:21 -0800937 pte = 0;
Ben Widawsky9df15b42013-11-02 21:07:24 -0700938 }
Chris Wilson894cceb2017-02-15 08:43:37 +0000939 } while (1);
Chris Wilson84486612017-02-15 08:43:40 +0000940 kunmap_px(vaddr);
Mika Kuoppalad1c54ac2015-06-25 18:35:11 +0300941
Chris Wilson894cceb2017-02-15 08:43:37 +0000942 return ret;
Ben Widawsky9df15b42013-11-02 21:07:24 -0700943}
944
Chris Wilson894cceb2017-02-15 08:43:37 +0000945static void gen8_ppgtt_insert_3lvl(struct i915_address_space *vm,
946 struct sg_table *pages,
947 u64 start,
948 enum i915_cache_level cache_level,
949 u32 unused)
Michel Thierryf9b5b782015-07-30 11:02:49 +0100950{
Joonas Lahtinene5716f52016-04-07 11:08:03 +0300951 struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
Chris Wilson894cceb2017-02-15 08:43:37 +0000952 struct sgt_dma iter = {
953 .sg = pages->sgl,
954 .dma = sg_dma_address(iter.sg),
955 .max = iter.dma + iter.sg->length,
956 };
Michel Thierryf9b5b782015-07-30 11:02:49 +0100957
Chris Wilson894cceb2017-02-15 08:43:37 +0000958 gen8_ppgtt_insert_pte_entries(ppgtt, &ppgtt->pdp, &iter,
959 start, cache_level);
960}
Michel Thierryde5ba8e2015-08-03 09:53:27 +0100961
Chris Wilson894cceb2017-02-15 08:43:37 +0000962static void gen8_ppgtt_insert_4lvl(struct i915_address_space *vm,
963 struct sg_table *pages,
964 uint64_t start,
965 enum i915_cache_level cache_level,
966 u32 unused)
967{
968 struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
969 struct sgt_dma iter = {
970 .sg = pages->sgl,
971 .dma = sg_dma_address(iter.sg),
972 .max = iter.dma + iter.sg->length,
973 };
974 struct i915_page_directory_pointer **pdps = ppgtt->pml4.pdps;
975 unsigned int pml4e = gen8_pml4e_index(start);
Michel Thierryde5ba8e2015-08-03 09:53:27 +0100976
Chris Wilson894cceb2017-02-15 08:43:37 +0000977 while (gen8_ppgtt_insert_pte_entries(ppgtt, pdps[pml4e++], &iter,
978 start, cache_level))
979 ;
Michel Thierryf9b5b782015-07-30 11:02:49 +0100980}
981
Chris Wilson84486612017-02-15 08:43:40 +0000982static void gen8_free_page_tables(struct i915_address_space *vm,
Michel Thierryf37c0502015-06-10 17:46:39 +0100983 struct i915_page_directory *pd)
Ben Widawskyb45a6712014-02-12 14:28:44 -0800984{
985 int i;
986
Mika Kuoppala567047b2015-06-25 18:35:12 +0300987 if (!px_page(pd))
Ben Widawsky7ad47cf2014-02-20 11:51:21 -0800988 return;
Ben Widawskyb45a6712014-02-12 14:28:44 -0800989
Michel Thierry33c88192015-04-08 12:13:33 +0100990 for_each_set_bit(i, pd->used_pdes, I915_PDES) {
Ben Widawsky06fda602015-02-24 16:22:36 +0000991 if (WARN_ON(!pd->page_table[i]))
992 continue;
Ben Widawsky7ad47cf2014-02-20 11:51:21 -0800993
Chris Wilson84486612017-02-15 08:43:40 +0000994 free_pt(vm, pd->page_table[i]);
Ben Widawsky06fda602015-02-24 16:22:36 +0000995 pd->page_table[i] = NULL;
996 }
Ben Widawskyd7b3de92015-02-24 16:22:34 +0000997}
998
Mika Kuoppala8776f022015-06-30 18:16:40 +0300999static int gen8_init_scratch(struct i915_address_space *vm)
1000{
Matthew Auld64c050d2016-04-27 13:19:25 +01001001 int ret;
Mika Kuoppala8776f022015-06-30 18:16:40 +03001002
Chris Wilson84486612017-02-15 08:43:40 +00001003 ret = setup_scratch_page(vm, I915_GFP_DMA);
Chris Wilson8bcdd0f72016-08-22 08:44:30 +01001004 if (ret)
1005 return ret;
Mika Kuoppala8776f022015-06-30 18:16:40 +03001006
Chris Wilson84486612017-02-15 08:43:40 +00001007 vm->scratch_pt = alloc_pt(vm);
Mika Kuoppala8776f022015-06-30 18:16:40 +03001008 if (IS_ERR(vm->scratch_pt)) {
Matthew Auld64c050d2016-04-27 13:19:25 +01001009 ret = PTR_ERR(vm->scratch_pt);
1010 goto free_scratch_page;
Mika Kuoppala8776f022015-06-30 18:16:40 +03001011 }
1012
Chris Wilson84486612017-02-15 08:43:40 +00001013 vm->scratch_pd = alloc_pd(vm);
Mika Kuoppala8776f022015-06-30 18:16:40 +03001014 if (IS_ERR(vm->scratch_pd)) {
Matthew Auld64c050d2016-04-27 13:19:25 +01001015 ret = PTR_ERR(vm->scratch_pd);
1016 goto free_pt;
Mika Kuoppala8776f022015-06-30 18:16:40 +03001017 }
1018
Chris Wilson84486612017-02-15 08:43:40 +00001019 if (USES_FULL_48BIT_PPGTT(dev)) {
1020 vm->scratch_pdp = alloc_pdp(vm);
Michel Thierry69ab76f2015-07-29 17:23:55 +01001021 if (IS_ERR(vm->scratch_pdp)) {
Matthew Auld64c050d2016-04-27 13:19:25 +01001022 ret = PTR_ERR(vm->scratch_pdp);
1023 goto free_pd;
Michel Thierry69ab76f2015-07-29 17:23:55 +01001024 }
1025 }
1026
Mika Kuoppala8776f022015-06-30 18:16:40 +03001027 gen8_initialize_pt(vm, vm->scratch_pt);
1028 gen8_initialize_pd(vm, vm->scratch_pd);
Tvrtko Ursulin275a9912016-11-16 08:55:34 +00001029 if (USES_FULL_48BIT_PPGTT(dev_priv))
Michel Thierry69ab76f2015-07-29 17:23:55 +01001030 gen8_initialize_pdp(vm, vm->scratch_pdp);
Mika Kuoppala8776f022015-06-30 18:16:40 +03001031
1032 return 0;
Matthew Auld64c050d2016-04-27 13:19:25 +01001033
1034free_pd:
Chris Wilson84486612017-02-15 08:43:40 +00001035 free_pd(vm, vm->scratch_pd);
Matthew Auld64c050d2016-04-27 13:19:25 +01001036free_pt:
Chris Wilson84486612017-02-15 08:43:40 +00001037 free_pt(vm, vm->scratch_pt);
Matthew Auld64c050d2016-04-27 13:19:25 +01001038free_scratch_page:
Chris Wilson84486612017-02-15 08:43:40 +00001039 cleanup_scratch_page(vm);
Matthew Auld64c050d2016-04-27 13:19:25 +01001040
1041 return ret;
Mika Kuoppala8776f022015-06-30 18:16:40 +03001042}
1043
Zhiyuan Lv650da342015-08-28 15:41:18 +08001044static int gen8_ppgtt_notify_vgt(struct i915_hw_ppgtt *ppgtt, bool create)
1045{
1046 enum vgt_g2v_type msg;
Chris Wilson49d73912016-11-29 09:50:08 +00001047 struct drm_i915_private *dev_priv = ppgtt->base.i915;
Zhiyuan Lv650da342015-08-28 15:41:18 +08001048 int i;
1049
Matthew Aulddf285642016-04-22 12:09:25 +01001050 if (USES_FULL_48BIT_PPGTT(dev_priv)) {
Zhiyuan Lv650da342015-08-28 15:41:18 +08001051 u64 daddr = px_dma(&ppgtt->pml4);
1052
Ville Syrjäläab75bb52015-11-04 23:20:12 +02001053 I915_WRITE(vgtif_reg(pdp[0].lo), lower_32_bits(daddr));
1054 I915_WRITE(vgtif_reg(pdp[0].hi), upper_32_bits(daddr));
Zhiyuan Lv650da342015-08-28 15:41:18 +08001055
1056 msg = (create ? VGT_G2V_PPGTT_L4_PAGE_TABLE_CREATE :
1057 VGT_G2V_PPGTT_L4_PAGE_TABLE_DESTROY);
1058 } else {
1059 for (i = 0; i < GEN8_LEGACY_PDPES; i++) {
1060 u64 daddr = i915_page_dir_dma_addr(ppgtt, i);
1061
Ville Syrjäläab75bb52015-11-04 23:20:12 +02001062 I915_WRITE(vgtif_reg(pdp[i].lo), lower_32_bits(daddr));
1063 I915_WRITE(vgtif_reg(pdp[i].hi), upper_32_bits(daddr));
Zhiyuan Lv650da342015-08-28 15:41:18 +08001064 }
1065
1066 msg = (create ? VGT_G2V_PPGTT_L3_PAGE_TABLE_CREATE :
1067 VGT_G2V_PPGTT_L3_PAGE_TABLE_DESTROY);
1068 }
1069
1070 I915_WRITE(vgtif_reg(g2v_notify), msg);
1071
1072 return 0;
1073}
1074
Mika Kuoppala8776f022015-06-30 18:16:40 +03001075static void gen8_free_scratch(struct i915_address_space *vm)
1076{
Chris Wilson84486612017-02-15 08:43:40 +00001077 if (USES_FULL_48BIT_PPGTT(vm->i915))
1078 free_pdp(vm, vm->scratch_pdp);
1079 free_pd(vm, vm->scratch_pd);
1080 free_pt(vm, vm->scratch_pt);
1081 cleanup_scratch_page(vm);
Mika Kuoppala8776f022015-06-30 18:16:40 +03001082}
1083
Chris Wilson84486612017-02-15 08:43:40 +00001084static void gen8_ppgtt_cleanup_3lvl(struct i915_address_space *vm,
Michel Thierry762d9932015-07-30 11:05:29 +01001085 struct i915_page_directory_pointer *pdp)
Ben Widawsky7ad47cf2014-02-20 11:51:21 -08001086{
1087 int i;
1088
Chris Wilson84486612017-02-15 08:43:40 +00001089 for_each_set_bit(i, pdp->used_pdpes, I915_PDPES_PER_PDP(vm->i915)) {
Michel Thierryd4ec9da2015-07-30 11:02:03 +01001090 if (WARN_ON(!pdp->page_directory[i]))
Ben Widawsky06fda602015-02-24 16:22:36 +00001091 continue;
1092
Chris Wilson84486612017-02-15 08:43:40 +00001093 gen8_free_page_tables(vm, pdp->page_directory[i]);
1094 free_pd(vm, pdp->page_directory[i]);
Ben Widawsky7ad47cf2014-02-20 11:51:21 -08001095 }
Michel Thierry69876be2015-04-08 12:13:27 +01001096
Chris Wilson84486612017-02-15 08:43:40 +00001097 free_pdp(vm, pdp);
Michel Thierry762d9932015-07-30 11:05:29 +01001098}
1099
1100static void gen8_ppgtt_cleanup_4lvl(struct i915_hw_ppgtt *ppgtt)
1101{
1102 int i;
1103
1104 for_each_set_bit(i, ppgtt->pml4.used_pml4es, GEN8_PML4ES_PER_PML4) {
1105 if (WARN_ON(!ppgtt->pml4.pdps[i]))
1106 continue;
1107
Chris Wilson84486612017-02-15 08:43:40 +00001108 gen8_ppgtt_cleanup_3lvl(&ppgtt->base, ppgtt->pml4.pdps[i]);
Michel Thierry762d9932015-07-30 11:05:29 +01001109 }
1110
Chris Wilson84486612017-02-15 08:43:40 +00001111 cleanup_px(&ppgtt->base, &ppgtt->pml4);
Michel Thierry762d9932015-07-30 11:05:29 +01001112}
1113
1114static void gen8_ppgtt_cleanup(struct i915_address_space *vm)
1115{
Chris Wilson49d73912016-11-29 09:50:08 +00001116 struct drm_i915_private *dev_priv = vm->i915;
Joonas Lahtinene5716f52016-04-07 11:08:03 +03001117 struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
Michel Thierry762d9932015-07-30 11:05:29 +01001118
Tvrtko Ursulin275a9912016-11-16 08:55:34 +00001119 if (intel_vgpu_active(dev_priv))
Zhiyuan Lv650da342015-08-28 15:41:18 +08001120 gen8_ppgtt_notify_vgt(ppgtt, false);
1121
Chris Wilson84486612017-02-15 08:43:40 +00001122 if (!USES_FULL_48BIT_PPGTT(vm->i915))
1123 gen8_ppgtt_cleanup_3lvl(&ppgtt->base, &ppgtt->pdp);
Michel Thierry762d9932015-07-30 11:05:29 +01001124 else
1125 gen8_ppgtt_cleanup_4lvl(ppgtt);
Michel Thierryd4ec9da2015-07-30 11:02:03 +01001126
Mika Kuoppala8776f022015-06-30 18:16:40 +03001127 gen8_free_scratch(vm);
Ben Widawskyb45a6712014-02-12 14:28:44 -08001128}
1129
Michel Thierryd7b26332015-04-08 12:13:34 +01001130/**
1131 * gen8_ppgtt_alloc_pagetabs() - Allocate page tables for VA range.
Michel Thierryd4ec9da2015-07-30 11:02:03 +01001132 * @vm: Master vm structure.
1133 * @pd: Page directory for this address range.
Michel Thierryd7b26332015-04-08 12:13:34 +01001134 * @start: Starting virtual address to begin allocations.
Michel Thierryd4ec9da2015-07-30 11:02:03 +01001135 * @length: Size of the allocations.
Michel Thierryd7b26332015-04-08 12:13:34 +01001136 * @new_pts: Bitmap set by function with new allocations. Likely used by the
1137 * caller to free on error.
1138 *
1139 * Allocate the required number of page tables. Extremely similar to
1140 * gen8_ppgtt_alloc_page_directories(). The main difference is here we are limited by
1141 * the page directory boundary (instead of the page directory pointer). That
1142 * boundary is 1GB virtual. Therefore, unlike gen8_ppgtt_alloc_page_directories(), it is
1143 * possible, and likely that the caller will need to use multiple calls of this
1144 * function to achieve the appropriate allocation.
1145 *
1146 * Return: 0 if success; negative error code otherwise.
1147 */
Michel Thierryd4ec9da2015-07-30 11:02:03 +01001148static int gen8_ppgtt_alloc_pagetabs(struct i915_address_space *vm,
Michel Thierrye5815a22015-04-08 12:13:32 +01001149 struct i915_page_directory *pd,
Michel Thierry5441f0c2015-04-08 12:13:28 +01001150 uint64_t start,
Michel Thierryd7b26332015-04-08 12:13:34 +01001151 uint64_t length,
1152 unsigned long *new_pts)
Ben Widawskyd7b3de92015-02-24 16:22:34 +00001153{
Michel Thierryd7b26332015-04-08 12:13:34 +01001154 struct i915_page_table *pt;
Michel Thierry5441f0c2015-04-08 12:13:28 +01001155 uint32_t pde;
Ben Widawskyd7b3de92015-02-24 16:22:34 +00001156
Dave Gordone8ebd8e2015-12-08 13:30:51 +00001157 gen8_for_each_pde(pt, pd, start, length, pde) {
Michel Thierryd7b26332015-04-08 12:13:34 +01001158 /* Don't reallocate page tables */
Michel Thierry6ac18502015-07-29 17:23:46 +01001159 if (test_bit(pde, pd->used_pdes)) {
Michel Thierryd7b26332015-04-08 12:13:34 +01001160 /* Scratch is never allocated this way */
Michel Thierryd4ec9da2015-07-30 11:02:03 +01001161 WARN_ON(pt == vm->scratch_pt);
Michel Thierryd7b26332015-04-08 12:13:34 +01001162 continue;
1163 }
1164
Chris Wilson84486612017-02-15 08:43:40 +00001165 pt = alloc_pt(vm);
Michel Thierryd7b26332015-04-08 12:13:34 +01001166 if (IS_ERR(pt))
Ben Widawsky06fda602015-02-24 16:22:36 +00001167 goto unwind_out;
Michel Thierry5441f0c2015-04-08 12:13:28 +01001168
Michel Thierryd4ec9da2015-07-30 11:02:03 +01001169 gen8_initialize_pt(vm, pt);
Michel Thierryd7b26332015-04-08 12:13:34 +01001170 pd->page_table[pde] = pt;
Mika Kuoppala966082c2015-06-25 18:35:19 +03001171 __set_bit(pde, new_pts);
Michel Thierry4c06ec82015-07-29 17:23:49 +01001172 trace_i915_page_table_entry_alloc(vm, pde, start, GEN8_PDE_SHIFT);
Ben Widawskyd7b3de92015-02-24 16:22:34 +00001173 }
1174
1175 return 0;
1176
1177unwind_out:
Michel Thierryd7b26332015-04-08 12:13:34 +01001178 for_each_set_bit(pde, new_pts, I915_PDES)
Chris Wilson84486612017-02-15 08:43:40 +00001179 free_pt(vm, pd->page_table[pde]);
Ben Widawskyd7b3de92015-02-24 16:22:34 +00001180
1181 return -ENOMEM;
1182}
1183
Michel Thierryd7b26332015-04-08 12:13:34 +01001184/**
1185 * gen8_ppgtt_alloc_page_directories() - Allocate page directories for VA range.
Michel Thierryd4ec9da2015-07-30 11:02:03 +01001186 * @vm: Master vm structure.
Michel Thierryd7b26332015-04-08 12:13:34 +01001187 * @pdp: Page directory pointer for this address range.
1188 * @start: Starting virtual address to begin allocations.
Michel Thierryd4ec9da2015-07-30 11:02:03 +01001189 * @length: Size of the allocations.
1190 * @new_pds: Bitmap set by function with new allocations. Likely used by the
Michel Thierryd7b26332015-04-08 12:13:34 +01001191 * caller to free on error.
1192 *
1193 * Allocate the required number of page directories starting at the pde index of
1194 * @start, and ending at the pde index @start + @length. This function will skip
1195 * over already allocated page directories within the range, and only allocate
1196 * new ones, setting the appropriate pointer within the pdp as well as the
1197 * correct position in the bitmap @new_pds.
1198 *
1199 * The function will only allocate the pages within the range for a give page
1200 * directory pointer. In other words, if @start + @length straddles a virtually
1201 * addressed PDP boundary (512GB for 4k pages), there will be more allocations
1202 * required by the caller, This is not currently possible, and the BUG in the
1203 * code will prevent it.
1204 *
1205 * Return: 0 if success; negative error code otherwise.
1206 */
Michel Thierryd4ec9da2015-07-30 11:02:03 +01001207static int
1208gen8_ppgtt_alloc_page_directories(struct i915_address_space *vm,
1209 struct i915_page_directory_pointer *pdp,
1210 uint64_t start,
1211 uint64_t length,
1212 unsigned long *new_pds)
Ben Widawskybf2b4ed2014-02-19 22:05:43 -08001213{
Michel Thierryd7b26332015-04-08 12:13:34 +01001214 struct i915_page_directory *pd;
Michel Thierry69876be2015-04-08 12:13:27 +01001215 uint32_t pdpe;
Tvrtko Ursulin275a9912016-11-16 08:55:34 +00001216 uint32_t pdpes = I915_PDPES_PER_PDP(dev_priv);
Ben Widawskybf2b4ed2014-02-19 22:05:43 -08001217
Michel Thierry6ac18502015-07-29 17:23:46 +01001218 WARN_ON(!bitmap_empty(new_pds, pdpes));
Michel Thierryd7b26332015-04-08 12:13:34 +01001219
Dave Gordone8ebd8e2015-12-08 13:30:51 +00001220 gen8_for_each_pdpe(pd, pdp, start, length, pdpe) {
Michel Thierry6ac18502015-07-29 17:23:46 +01001221 if (test_bit(pdpe, pdp->used_pdpes))
Michel Thierryd7b26332015-04-08 12:13:34 +01001222 continue;
Michel Thierry33c88192015-04-08 12:13:33 +01001223
Chris Wilson84486612017-02-15 08:43:40 +00001224 pd = alloc_pd(vm);
Michel Thierryd7b26332015-04-08 12:13:34 +01001225 if (IS_ERR(pd))
Ben Widawskyd7b3de92015-02-24 16:22:34 +00001226 goto unwind_out;
Michel Thierry69876be2015-04-08 12:13:27 +01001227
Michel Thierryd4ec9da2015-07-30 11:02:03 +01001228 gen8_initialize_pd(vm, pd);
Michel Thierryd7b26332015-04-08 12:13:34 +01001229 pdp->page_directory[pdpe] = pd;
Mika Kuoppala966082c2015-06-25 18:35:19 +03001230 __set_bit(pdpe, new_pds);
Michel Thierry4c06ec82015-07-29 17:23:49 +01001231 trace_i915_page_directory_entry_alloc(vm, pdpe, start, GEN8_PDPE_SHIFT);
Ben Widawskyd7b3de92015-02-24 16:22:34 +00001232 }
1233
Ben Widawskybf2b4ed2014-02-19 22:05:43 -08001234 return 0;
Ben Widawskyd7b3de92015-02-24 16:22:34 +00001235
1236unwind_out:
Michel Thierry6ac18502015-07-29 17:23:46 +01001237 for_each_set_bit(pdpe, new_pds, pdpes)
Chris Wilson84486612017-02-15 08:43:40 +00001238 free_pd(vm, pdp->page_directory[pdpe]);
Ben Widawskyd7b3de92015-02-24 16:22:34 +00001239
1240 return -ENOMEM;
Ben Widawskybf2b4ed2014-02-19 22:05:43 -08001241}
1242
Michel Thierry762d9932015-07-30 11:05:29 +01001243/**
1244 * gen8_ppgtt_alloc_page_dirpointers() - Allocate pdps for VA range.
1245 * @vm: Master vm structure.
1246 * @pml4: Page map level 4 for this address range.
1247 * @start: Starting virtual address to begin allocations.
1248 * @length: Size of the allocations.
1249 * @new_pdps: Bitmap set by function with new allocations. Likely used by the
1250 * caller to free on error.
1251 *
1252 * Allocate the required number of page directory pointers. Extremely similar to
1253 * gen8_ppgtt_alloc_page_directories() and gen8_ppgtt_alloc_pagetabs().
1254 * The main difference is here we are limited by the pml4 boundary (instead of
1255 * the page directory pointer).
1256 *
1257 * Return: 0 if success; negative error code otherwise.
1258 */
1259static int
1260gen8_ppgtt_alloc_page_dirpointers(struct i915_address_space *vm,
1261 struct i915_pml4 *pml4,
1262 uint64_t start,
1263 uint64_t length,
1264 unsigned long *new_pdps)
1265{
Michel Thierry762d9932015-07-30 11:05:29 +01001266 struct i915_page_directory_pointer *pdp;
Michel Thierry762d9932015-07-30 11:05:29 +01001267 uint32_t pml4e;
1268
1269 WARN_ON(!bitmap_empty(new_pdps, GEN8_PML4ES_PER_PML4));
1270
Dave Gordone8ebd8e2015-12-08 13:30:51 +00001271 gen8_for_each_pml4e(pdp, pml4, start, length, pml4e) {
Michel Thierry762d9932015-07-30 11:05:29 +01001272 if (!test_bit(pml4e, pml4->used_pml4es)) {
Chris Wilson84486612017-02-15 08:43:40 +00001273 pdp = alloc_pdp(vm);
Michel Thierry762d9932015-07-30 11:05:29 +01001274 if (IS_ERR(pdp))
1275 goto unwind_out;
1276
Michel Thierry69ab76f2015-07-29 17:23:55 +01001277 gen8_initialize_pdp(vm, pdp);
Michel Thierry762d9932015-07-30 11:05:29 +01001278 pml4->pdps[pml4e] = pdp;
1279 __set_bit(pml4e, new_pdps);
1280 trace_i915_page_directory_pointer_entry_alloc(vm,
1281 pml4e,
1282 start,
1283 GEN8_PML4E_SHIFT);
1284 }
1285 }
1286
1287 return 0;
1288
1289unwind_out:
1290 for_each_set_bit(pml4e, new_pdps, GEN8_PML4ES_PER_PML4)
Chris Wilson84486612017-02-15 08:43:40 +00001291 free_pdp(vm, pml4->pdps[pml4e]);
Michel Thierry762d9932015-07-30 11:05:29 +01001292
1293 return -ENOMEM;
1294}
1295
Michel Thierryd7b26332015-04-08 12:13:34 +01001296static void
Michał Winiarski3a41a052015-09-03 19:22:18 +02001297free_gen8_temp_bitmaps(unsigned long *new_pds, unsigned long *new_pts)
Michel Thierryd7b26332015-04-08 12:13:34 +01001298{
Michel Thierryd7b26332015-04-08 12:13:34 +01001299 kfree(new_pts);
1300 kfree(new_pds);
1301}
1302
1303/* Fills in the page directory bitmap, and the array of page tables bitmap. Both
1304 * of these are based on the number of PDPEs in the system.
1305 */
1306static
1307int __must_check alloc_gen8_temp_bitmaps(unsigned long **new_pds,
Michał Winiarski3a41a052015-09-03 19:22:18 +02001308 unsigned long **new_pts,
Michel Thierry6ac18502015-07-29 17:23:46 +01001309 uint32_t pdpes)
Michel Thierryd7b26332015-04-08 12:13:34 +01001310{
Michel Thierryd7b26332015-04-08 12:13:34 +01001311 unsigned long *pds;
Michał Winiarski3a41a052015-09-03 19:22:18 +02001312 unsigned long *pts;
Michel Thierryd7b26332015-04-08 12:13:34 +01001313
Michał Winiarski3a41a052015-09-03 19:22:18 +02001314 pds = kcalloc(BITS_TO_LONGS(pdpes), sizeof(unsigned long), GFP_TEMPORARY);
Michel Thierryd7b26332015-04-08 12:13:34 +01001315 if (!pds)
1316 return -ENOMEM;
1317
Michał Winiarski3a41a052015-09-03 19:22:18 +02001318 pts = kcalloc(pdpes, BITS_TO_LONGS(I915_PDES) * sizeof(unsigned long),
1319 GFP_TEMPORARY);
1320 if (!pts)
1321 goto err_out;
Michel Thierryd7b26332015-04-08 12:13:34 +01001322
1323 *new_pds = pds;
1324 *new_pts = pts;
1325
1326 return 0;
1327
1328err_out:
Michał Winiarski3a41a052015-09-03 19:22:18 +02001329 free_gen8_temp_bitmaps(pds, pts);
Michel Thierryd7b26332015-04-08 12:13:34 +01001330 return -ENOMEM;
1331}
1332
Michel Thierry762d9932015-07-30 11:05:29 +01001333static int gen8_alloc_va_range_3lvl(struct i915_address_space *vm,
1334 struct i915_page_directory_pointer *pdp,
1335 uint64_t start,
1336 uint64_t length)
Ben Widawskybf2b4ed2014-02-19 22:05:43 -08001337{
Joonas Lahtinene5716f52016-04-07 11:08:03 +03001338 struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
Michał Winiarski3a41a052015-09-03 19:22:18 +02001339 unsigned long *new_page_dirs, *new_page_tables;
Michel Thierry5441f0c2015-04-08 12:13:28 +01001340 struct i915_page_directory *pd;
Michel Thierry33c88192015-04-08 12:13:33 +01001341 const uint64_t orig_start = start;
1342 const uint64_t orig_length = length;
Michel Thierry5441f0c2015-04-08 12:13:28 +01001343 uint32_t pdpe;
Tvrtko Ursulin275a9912016-11-16 08:55:34 +00001344 uint32_t pdpes = I915_PDPES_PER_PDP(dev_priv);
Ben Widawskybf2b4ed2014-02-19 22:05:43 -08001345 int ret;
1346
Michel Thierry6ac18502015-07-29 17:23:46 +01001347 ret = alloc_gen8_temp_bitmaps(&new_page_dirs, &new_page_tables, pdpes);
Ben Widawskybf2b4ed2014-02-19 22:05:43 -08001348 if (ret)
1349 return ret;
1350
Michel Thierryd7b26332015-04-08 12:13:34 +01001351 /* Do the allocations first so we can easily bail out */
Michel Thierryd4ec9da2015-07-30 11:02:03 +01001352 ret = gen8_ppgtt_alloc_page_directories(vm, pdp, start, length,
1353 new_page_dirs);
Michel Thierryd7b26332015-04-08 12:13:34 +01001354 if (ret) {
Michał Winiarski3a41a052015-09-03 19:22:18 +02001355 free_gen8_temp_bitmaps(new_page_dirs, new_page_tables);
Michel Thierryd7b26332015-04-08 12:13:34 +01001356 return ret;
1357 }
1358
1359 /* For every page directory referenced, allocate page tables */
Dave Gordone8ebd8e2015-12-08 13:30:51 +00001360 gen8_for_each_pdpe(pd, pdp, start, length, pdpe) {
Michel Thierryd4ec9da2015-07-30 11:02:03 +01001361 ret = gen8_ppgtt_alloc_pagetabs(vm, pd, start, length,
Michał Winiarski3a41a052015-09-03 19:22:18 +02001362 new_page_tables + pdpe * BITS_TO_LONGS(I915_PDES));
Michel Thierry5441f0c2015-04-08 12:13:28 +01001363 if (ret)
1364 goto err_out;
Michel Thierry5441f0c2015-04-08 12:13:28 +01001365 }
1366
Michel Thierry33c88192015-04-08 12:13:33 +01001367 start = orig_start;
1368 length = orig_length;
1369
Michel Thierryd7b26332015-04-08 12:13:34 +01001370 /* Allocations have completed successfully, so set the bitmaps, and do
1371 * the mappings. */
Dave Gordone8ebd8e2015-12-08 13:30:51 +00001372 gen8_for_each_pdpe(pd, pdp, start, length, pdpe) {
Mika Kuoppalad1c54ac2015-06-25 18:35:11 +03001373 gen8_pde_t *const page_directory = kmap_px(pd);
Michel Thierry33c88192015-04-08 12:13:33 +01001374 struct i915_page_table *pt;
Michel Thierry09120d42015-07-29 17:23:45 +01001375 uint64_t pd_len = length;
Michel Thierry33c88192015-04-08 12:13:33 +01001376 uint64_t pd_start = start;
1377 uint32_t pde;
1378
Michel Thierryd7b26332015-04-08 12:13:34 +01001379 /* Every pd should be allocated, we just did that above. */
1380 WARN_ON(!pd);
1381
Dave Gordone8ebd8e2015-12-08 13:30:51 +00001382 gen8_for_each_pde(pt, pd, pd_start, pd_len, pde) {
Michel Thierryd7b26332015-04-08 12:13:34 +01001383 /* Same reasoning as pd */
1384 WARN_ON(!pt);
1385 WARN_ON(!pd_len);
1386 WARN_ON(!gen8_pte_count(pd_start, pd_len));
1387
1388 /* Set our used ptes within the page table */
1389 bitmap_set(pt->used_ptes,
1390 gen8_pte_index(pd_start),
1391 gen8_pte_count(pd_start, pd_len));
1392
1393 /* Our pde is now pointing to the pagetable, pt */
Mika Kuoppala966082c2015-06-25 18:35:19 +03001394 __set_bit(pde, pd->used_pdes);
Michel Thierryd7b26332015-04-08 12:13:34 +01001395
1396 /* Map the PDE to the page table */
Mika Kuoppalafe36f552015-06-25 18:35:16 +03001397 page_directory[pde] = gen8_pde_encode(px_dma(pt),
1398 I915_CACHE_LLC);
Michel Thierry4c06ec82015-07-29 17:23:49 +01001399 trace_i915_page_table_entry_map(&ppgtt->base, pde, pt,
1400 gen8_pte_index(start),
1401 gen8_pte_count(start, length),
1402 GEN8_PTES);
Michel Thierryd7b26332015-04-08 12:13:34 +01001403
1404 /* NB: We haven't yet mapped ptes to pages. At this
1405 * point we're still relying on insert_entries() */
Michel Thierry33c88192015-04-08 12:13:33 +01001406 }
Michel Thierryd7b26332015-04-08 12:13:34 +01001407
Chris Wilson84486612017-02-15 08:43:40 +00001408 kunmap_px(page_directory);
Michel Thierryd4ec9da2015-07-30 11:02:03 +01001409 __set_bit(pdpe, pdp->used_pdpes);
Matthew Auld5c693b22016-12-13 16:05:10 +00001410 gen8_setup_pdpe(ppgtt, pdp, pd, pdpe);
Michel Thierry33c88192015-04-08 12:13:33 +01001411 }
1412
Michał Winiarski3a41a052015-09-03 19:22:18 +02001413 free_gen8_temp_bitmaps(new_page_dirs, new_page_tables);
Mika Kuoppala5b7e4c9c2015-06-25 18:35:03 +03001414 mark_tlbs_dirty(ppgtt);
Ben Widawskyd7b3de92015-02-24 16:22:34 +00001415 return 0;
1416
1417err_out:
Michel Thierryd7b26332015-04-08 12:13:34 +01001418 while (pdpe--) {
Dave Gordone8ebd8e2015-12-08 13:30:51 +00001419 unsigned long temp;
1420
Michał Winiarski3a41a052015-09-03 19:22:18 +02001421 for_each_set_bit(temp, new_page_tables + pdpe *
1422 BITS_TO_LONGS(I915_PDES), I915_PDES)
Chris Wilson84486612017-02-15 08:43:40 +00001423 free_pt(vm, pdp->page_directory[pdpe]->page_table[temp]);
Michel Thierryd7b26332015-04-08 12:13:34 +01001424 }
1425
Michel Thierry6ac18502015-07-29 17:23:46 +01001426 for_each_set_bit(pdpe, new_page_dirs, pdpes)
Chris Wilson84486612017-02-15 08:43:40 +00001427 free_pd(vm, pdp->page_directory[pdpe]);
Michel Thierryd7b26332015-04-08 12:13:34 +01001428
Michał Winiarski3a41a052015-09-03 19:22:18 +02001429 free_gen8_temp_bitmaps(new_page_dirs, new_page_tables);
Mika Kuoppala5b7e4c9c2015-06-25 18:35:03 +03001430 mark_tlbs_dirty(ppgtt);
Ben Widawskybf2b4ed2014-02-19 22:05:43 -08001431 return ret;
1432}
1433
Michel Thierry762d9932015-07-30 11:05:29 +01001434static int gen8_alloc_va_range_4lvl(struct i915_address_space *vm,
1435 struct i915_pml4 *pml4,
1436 uint64_t start,
1437 uint64_t length)
1438{
1439 DECLARE_BITMAP(new_pdps, GEN8_PML4ES_PER_PML4);
Michel Thierry762d9932015-07-30 11:05:29 +01001440 struct i915_page_directory_pointer *pdp;
Dave Gordone8ebd8e2015-12-08 13:30:51 +00001441 uint64_t pml4e;
Michel Thierry762d9932015-07-30 11:05:29 +01001442 int ret = 0;
1443
1444 /* Do the pml4 allocations first, so we don't need to track the newly
1445 * allocated tables below the pdp */
1446 bitmap_zero(new_pdps, GEN8_PML4ES_PER_PML4);
1447
1448 /* The pagedirectory and pagetable allocations are done in the shared 3
1449 * and 4 level code. Just allocate the pdps.
1450 */
1451 ret = gen8_ppgtt_alloc_page_dirpointers(vm, pml4, start, length,
1452 new_pdps);
1453 if (ret)
1454 return ret;
1455
Dave Gordone8ebd8e2015-12-08 13:30:51 +00001456 gen8_for_each_pml4e(pdp, pml4, start, length, pml4e) {
Michel Thierry762d9932015-07-30 11:05:29 +01001457 WARN_ON(!pdp);
1458
1459 ret = gen8_alloc_va_range_3lvl(vm, pdp, start, length);
1460 if (ret)
1461 goto err_out;
1462
Chris Wilson84486612017-02-15 08:43:40 +00001463 gen8_setup_pml4e(pml4, pdp, pml4e);
Michel Thierry762d9932015-07-30 11:05:29 +01001464 }
1465
1466 bitmap_or(pml4->used_pml4es, new_pdps, pml4->used_pml4es,
1467 GEN8_PML4ES_PER_PML4);
1468
1469 return 0;
1470
1471err_out:
1472 for_each_set_bit(pml4e, new_pdps, GEN8_PML4ES_PER_PML4)
Chris Wilson84486612017-02-15 08:43:40 +00001473 gen8_ppgtt_cleanup_3lvl(vm, pml4->pdps[pml4e]);
Michel Thierry762d9932015-07-30 11:05:29 +01001474
1475 return ret;
1476}
1477
1478static int gen8_alloc_va_range(struct i915_address_space *vm,
1479 uint64_t start, uint64_t length)
1480{
Joonas Lahtinene5716f52016-04-07 11:08:03 +03001481 struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
Michel Thierry762d9932015-07-30 11:05:29 +01001482
Chris Wilsonc6385c92016-11-29 12:42:05 +00001483 if (USES_FULL_48BIT_PPGTT(vm->i915))
Michel Thierry762d9932015-07-30 11:05:29 +01001484 return gen8_alloc_va_range_4lvl(vm, &ppgtt->pml4, start, length);
1485 else
1486 return gen8_alloc_va_range_3lvl(vm, &ppgtt->pdp, start, length);
1487}
1488
Chris Wilson84486612017-02-15 08:43:40 +00001489static void gen8_dump_pdp(struct i915_hw_ppgtt *ppgtt,
1490 struct i915_page_directory_pointer *pdp,
Michel Thierryea91e402015-07-29 17:23:57 +01001491 uint64_t start, uint64_t length,
1492 gen8_pte_t scratch_pte,
1493 struct seq_file *m)
1494{
1495 struct i915_page_directory *pd;
Michel Thierryea91e402015-07-29 17:23:57 +01001496 uint32_t pdpe;
1497
Dave Gordone8ebd8e2015-12-08 13:30:51 +00001498 gen8_for_each_pdpe(pd, pdp, start, length, pdpe) {
Michel Thierryea91e402015-07-29 17:23:57 +01001499 struct i915_page_table *pt;
1500 uint64_t pd_len = length;
1501 uint64_t pd_start = start;
1502 uint32_t pde;
1503
1504 if (!test_bit(pdpe, pdp->used_pdpes))
1505 continue;
1506
1507 seq_printf(m, "\tPDPE #%d\n", pdpe);
Dave Gordone8ebd8e2015-12-08 13:30:51 +00001508 gen8_for_each_pde(pt, pd, pd_start, pd_len, pde) {
Michel Thierryea91e402015-07-29 17:23:57 +01001509 uint32_t pte;
1510 gen8_pte_t *pt_vaddr;
1511
1512 if (!test_bit(pde, pd->used_pdes))
1513 continue;
1514
1515 pt_vaddr = kmap_px(pt);
1516 for (pte = 0; pte < GEN8_PTES; pte += 4) {
1517 uint64_t va =
1518 (pdpe << GEN8_PDPE_SHIFT) |
1519 (pde << GEN8_PDE_SHIFT) |
1520 (pte << GEN8_PTE_SHIFT);
1521 int i;
1522 bool found = false;
1523
1524 for (i = 0; i < 4; i++)
1525 if (pt_vaddr[pte + i] != scratch_pte)
1526 found = true;
1527 if (!found)
1528 continue;
1529
1530 seq_printf(m, "\t\t0x%llx [%03d,%03d,%04d]: =", va, pdpe, pde, pte);
1531 for (i = 0; i < 4; i++) {
1532 if (pt_vaddr[pte + i] != scratch_pte)
1533 seq_printf(m, " %llx", pt_vaddr[pte + i]);
1534 else
1535 seq_puts(m, " SCRATCH ");
1536 }
1537 seq_puts(m, "\n");
1538 }
1539 /* don't use kunmap_px, it could trigger
1540 * an unnecessary flush.
1541 */
1542 kunmap_atomic(pt_vaddr);
1543 }
1544 }
1545}
1546
1547static void gen8_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m)
1548{
1549 struct i915_address_space *vm = &ppgtt->base;
1550 uint64_t start = ppgtt->base.start;
1551 uint64_t length = ppgtt->base.total;
Chris Wilson894cceb2017-02-15 08:43:37 +00001552 const gen8_pte_t scratch_pte =
1553 gen8_pte_encode(vm->scratch_page.daddr, I915_CACHE_LLC);
Michel Thierryea91e402015-07-29 17:23:57 +01001554
Chris Wilsonc6385c92016-11-29 12:42:05 +00001555 if (!USES_FULL_48BIT_PPGTT(vm->i915)) {
Chris Wilson84486612017-02-15 08:43:40 +00001556 gen8_dump_pdp(ppgtt, &ppgtt->pdp, start, length, scratch_pte, m);
Michel Thierryea91e402015-07-29 17:23:57 +01001557 } else {
Dave Gordone8ebd8e2015-12-08 13:30:51 +00001558 uint64_t pml4e;
Michel Thierryea91e402015-07-29 17:23:57 +01001559 struct i915_pml4 *pml4 = &ppgtt->pml4;
1560 struct i915_page_directory_pointer *pdp;
1561
Dave Gordone8ebd8e2015-12-08 13:30:51 +00001562 gen8_for_each_pml4e(pdp, pml4, start, length, pml4e) {
Michel Thierryea91e402015-07-29 17:23:57 +01001563 if (!test_bit(pml4e, pml4->used_pml4es))
1564 continue;
1565
1566 seq_printf(m, " PML4E #%llu\n", pml4e);
Chris Wilson84486612017-02-15 08:43:40 +00001567 gen8_dump_pdp(ppgtt, pdp, start, length, scratch_pte, m);
Michel Thierryea91e402015-07-29 17:23:57 +01001568 }
1569 }
1570}
1571
Zhiyuan Lv331f38e2015-08-28 15:41:14 +08001572static int gen8_preallocate_top_level_pdps(struct i915_hw_ppgtt *ppgtt)
1573{
Michał Winiarski3a41a052015-09-03 19:22:18 +02001574 unsigned long *new_page_dirs, *new_page_tables;
Tvrtko Ursulin275a9912016-11-16 08:55:34 +00001575 uint32_t pdpes = I915_PDPES_PER_PDP(to_i915(ppgtt->base.dev));
Zhiyuan Lv331f38e2015-08-28 15:41:14 +08001576 int ret;
1577
1578 /* We allocate temp bitmap for page tables for no gain
1579 * but as this is for init only, lets keep the things simple
1580 */
1581 ret = alloc_gen8_temp_bitmaps(&new_page_dirs, &new_page_tables, pdpes);
1582 if (ret)
1583 return ret;
1584
1585 /* Allocate for all pdps regardless of how the ppgtt
1586 * was defined.
1587 */
1588 ret = gen8_ppgtt_alloc_page_directories(&ppgtt->base, &ppgtt->pdp,
1589 0, 1ULL << 32,
1590 new_page_dirs);
1591 if (!ret)
1592 *ppgtt->pdp.used_pdpes = *new_page_dirs;
1593
Michał Winiarski3a41a052015-09-03 19:22:18 +02001594 free_gen8_temp_bitmaps(new_page_dirs, new_page_tables);
Zhiyuan Lv331f38e2015-08-28 15:41:14 +08001595
1596 return ret;
1597}
1598
Daniel Vettereb0b44a2015-03-18 14:47:59 +01001599/*
Ben Widawskyf3a964b2014-02-19 22:05:42 -08001600 * GEN8 legacy ppgtt programming is accomplished through a max 4 PDP registers
1601 * with a net effect resembling a 2-level page table in normal x86 terms. Each
1602 * PDP represents 1GB of memory 4 * 512 * 512 * 4096 = 4GB legacy 32b address
1603 * space.
Ben Widawsky37aca442013-11-04 20:47:32 -08001604 *
Ben Widawskyf3a964b2014-02-19 22:05:42 -08001605 */
Daniel Vetter5c5f6452015-04-14 17:35:14 +02001606static int gen8_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
Ben Widawsky37aca442013-11-04 20:47:32 -08001607{
Chris Wilson49d73912016-11-29 09:50:08 +00001608 struct drm_i915_private *dev_priv = ppgtt->base.i915;
Mika Kuoppala8776f022015-06-30 18:16:40 +03001609 int ret;
Michel Thierry69876be2015-04-08 12:13:27 +01001610
Mika Kuoppala8776f022015-06-30 18:16:40 +03001611 ret = gen8_init_scratch(&ppgtt->base);
1612 if (ret)
1613 return ret;
Michel Thierry69876be2015-04-08 12:13:27 +01001614
Michel Thierryd7b26332015-04-08 12:13:34 +01001615 ppgtt->base.start = 0;
Michel Thierryd7b26332015-04-08 12:13:34 +01001616 ppgtt->base.cleanup = gen8_ppgtt_cleanup;
Daniel Vetter5c5f6452015-04-14 17:35:14 +02001617 ppgtt->base.allocate_va_range = gen8_alloc_va_range;
Daniel Vetterc7e16f22015-04-14 17:35:11 +02001618 ppgtt->base.clear_range = gen8_ppgtt_clear_range;
Daniel Vetter777dc5b2015-04-14 17:35:12 +02001619 ppgtt->base.unbind_vma = ppgtt_unbind_vma;
1620 ppgtt->base.bind_vma = ppgtt_bind_vma;
Michel Thierryea91e402015-07-29 17:23:57 +01001621 ppgtt->debug_dump = gen8_dump_ppgtt;
Michel Thierryd7b26332015-04-08 12:13:34 +01001622
Chris Wilson84486612017-02-15 08:43:40 +00001623 /* There are only few exceptions for gen >=6. chv and bxt.
1624 * And we are not sure about the latter so play safe for now.
1625 */
1626 if (IS_CHERRYVIEW(dev_priv) || IS_BROXTON(dev_priv))
1627 ppgtt->base.pt_kmap_wc = true;
1628
Tvrtko Ursulin275a9912016-11-16 08:55:34 +00001629 if (USES_FULL_48BIT_PPGTT(dev_priv)) {
Chris Wilson84486612017-02-15 08:43:40 +00001630 ret = setup_px(&ppgtt->base, &ppgtt->pml4);
Michel Thierry762d9932015-07-30 11:05:29 +01001631 if (ret)
1632 goto free_scratch;
Michel Thierry6ac18502015-07-29 17:23:46 +01001633
Michel Thierry69ab76f2015-07-29 17:23:55 +01001634 gen8_initialize_pml4(&ppgtt->base, &ppgtt->pml4);
1635
Michel Thierry762d9932015-07-30 11:05:29 +01001636 ppgtt->base.total = 1ULL << 48;
Michel Thierry2dba3232015-07-30 11:06:23 +01001637 ppgtt->switch_mm = gen8_48b_mm_switch;
Chris Wilson894cceb2017-02-15 08:43:37 +00001638
1639 ppgtt->base.insert_entries = gen8_ppgtt_insert_4lvl;
Michel Thierry762d9932015-07-30 11:05:29 +01001640 } else {
Tvrtko Ursulin275a9912016-11-16 08:55:34 +00001641 ret = __pdp_init(dev_priv, &ppgtt->pdp);
Michel Thierry81ba8aef2015-08-03 09:52:01 +01001642 if (ret)
1643 goto free_scratch;
1644
1645 ppgtt->base.total = 1ULL << 32;
Michel Thierry2dba3232015-07-30 11:06:23 +01001646 ppgtt->switch_mm = gen8_legacy_mm_switch;
Michel Thierry762d9932015-07-30 11:05:29 +01001647 trace_i915_page_directory_pointer_entry_alloc(&ppgtt->base,
1648 0, 0,
1649 GEN8_PML4E_SHIFT);
Zhiyuan Lv331f38e2015-08-28 15:41:14 +08001650
Tvrtko Ursulin275a9912016-11-16 08:55:34 +00001651 if (intel_vgpu_active(dev_priv)) {
Zhiyuan Lv331f38e2015-08-28 15:41:14 +08001652 ret = gen8_preallocate_top_level_pdps(ppgtt);
1653 if (ret)
1654 goto free_scratch;
1655 }
Chris Wilson894cceb2017-02-15 08:43:37 +00001656
1657 ppgtt->base.insert_entries = gen8_ppgtt_insert_3lvl;
Michel Thierry81ba8aef2015-08-03 09:52:01 +01001658 }
Michel Thierry6ac18502015-07-29 17:23:46 +01001659
Tvrtko Ursulin275a9912016-11-16 08:55:34 +00001660 if (intel_vgpu_active(dev_priv))
Zhiyuan Lv650da342015-08-28 15:41:18 +08001661 gen8_ppgtt_notify_vgt(ppgtt, true);
1662
Michel Thierryd7b26332015-04-08 12:13:34 +01001663 return 0;
Michel Thierry6ac18502015-07-29 17:23:46 +01001664
1665free_scratch:
1666 gen8_free_scratch(&ppgtt->base);
1667 return ret;
Michel Thierryd7b26332015-04-08 12:13:34 +01001668}
1669
Ben Widawsky87d60b62013-12-06 14:11:29 -08001670static void gen6_dump_ppgtt(struct i915_hw_ppgtt *ppgtt, struct seq_file *m)
1671{
Ben Widawsky87d60b62013-12-06 14:11:29 -08001672 struct i915_address_space *vm = &ppgtt->base;
Michel Thierry09942c62015-04-08 12:13:30 +01001673 struct i915_page_table *unused;
Michel Thierry07749ef2015-03-16 16:00:54 +00001674 gen6_pte_t scratch_pte;
Ben Widawsky87d60b62013-12-06 14:11:29 -08001675 uint32_t pd_entry;
Dave Gordon731f74c2016-06-24 19:37:46 +01001676 uint32_t pte, pde;
Michel Thierry09942c62015-04-08 12:13:30 +01001677 uint32_t start = ppgtt->base.start, length = ppgtt->base.total;
Ben Widawsky87d60b62013-12-06 14:11:29 -08001678
Chris Wilson8bcdd0f72016-08-22 08:44:30 +01001679 scratch_pte = vm->pte_encode(vm->scratch_page.daddr,
Michał Winiarski4fb84d92016-10-13 14:02:40 +02001680 I915_CACHE_LLC, 0);
Ben Widawsky87d60b62013-12-06 14:11:29 -08001681
Dave Gordon731f74c2016-06-24 19:37:46 +01001682 gen6_for_each_pde(unused, &ppgtt->pd, start, length, pde) {
Ben Widawsky87d60b62013-12-06 14:11:29 -08001683 u32 expected;
Michel Thierry07749ef2015-03-16 16:00:54 +00001684 gen6_pte_t *pt_vaddr;
Mika Kuoppala567047b2015-06-25 18:35:12 +03001685 const dma_addr_t pt_addr = px_dma(ppgtt->pd.page_table[pde]);
Michel Thierry09942c62015-04-08 12:13:30 +01001686 pd_entry = readl(ppgtt->pd_addr + pde);
Ben Widawsky87d60b62013-12-06 14:11:29 -08001687 expected = (GEN6_PDE_ADDR_ENCODE(pt_addr) | GEN6_PDE_VALID);
1688
1689 if (pd_entry != expected)
1690 seq_printf(m, "\tPDE #%d mismatch: Actual PDE: %x Expected PDE: %x\n",
1691 pde,
1692 pd_entry,
1693 expected);
1694 seq_printf(m, "\tPDE: %x\n", pd_entry);
1695
Mika Kuoppalad1c54ac2015-06-25 18:35:11 +03001696 pt_vaddr = kmap_px(ppgtt->pd.page_table[pde]);
1697
Michel Thierry07749ef2015-03-16 16:00:54 +00001698 for (pte = 0; pte < GEN6_PTES; pte+=4) {
Ben Widawsky87d60b62013-12-06 14:11:29 -08001699 unsigned long va =
Michel Thierry07749ef2015-03-16 16:00:54 +00001700 (pde * PAGE_SIZE * GEN6_PTES) +
Ben Widawsky87d60b62013-12-06 14:11:29 -08001701 (pte * PAGE_SIZE);
1702 int i;
1703 bool found = false;
1704 for (i = 0; i < 4; i++)
1705 if (pt_vaddr[pte + i] != scratch_pte)
1706 found = true;
1707 if (!found)
1708 continue;
1709
1710 seq_printf(m, "\t\t0x%lx [%03d,%04d]: =", va, pde, pte);
1711 for (i = 0; i < 4; i++) {
1712 if (pt_vaddr[pte + i] != scratch_pte)
1713 seq_printf(m, " %08x", pt_vaddr[pte + i]);
1714 else
1715 seq_puts(m, " SCRATCH ");
1716 }
1717 seq_puts(m, "\n");
1718 }
Chris Wilson84486612017-02-15 08:43:40 +00001719 kunmap_px(pt_vaddr);
Ben Widawsky87d60b62013-12-06 14:11:29 -08001720 }
1721}
1722
Ben Widawsky678d96f2015-03-16 16:00:56 +00001723/* Write pde (index) from the page directory @pd to the page table @pt */
Michel Thierryec565b32015-04-08 12:13:23 +01001724static void gen6_write_pde(struct i915_page_directory *pd,
1725 const int pde, struct i915_page_table *pt)
Ben Widawsky61973492013-04-08 18:43:54 -07001726{
Ben Widawsky678d96f2015-03-16 16:00:56 +00001727 /* Caller needs to make sure the write completes if necessary */
1728 struct i915_hw_ppgtt *ppgtt =
1729 container_of(pd, struct i915_hw_ppgtt, pd);
1730 u32 pd_entry;
Ben Widawsky61973492013-04-08 18:43:54 -07001731
Mika Kuoppala567047b2015-06-25 18:35:12 +03001732 pd_entry = GEN6_PDE_ADDR_ENCODE(px_dma(pt));
Ben Widawsky678d96f2015-03-16 16:00:56 +00001733 pd_entry |= GEN6_PDE_VALID;
Ben Widawsky61973492013-04-08 18:43:54 -07001734
Ben Widawsky678d96f2015-03-16 16:00:56 +00001735 writel(pd_entry, ppgtt->pd_addr + pde);
1736}
Ben Widawsky61973492013-04-08 18:43:54 -07001737
Ben Widawsky678d96f2015-03-16 16:00:56 +00001738/* Write all the page tables found in the ppgtt structure to incrementing page
1739 * directories. */
1740static void gen6_write_page_range(struct drm_i915_private *dev_priv,
Michel Thierryec565b32015-04-08 12:13:23 +01001741 struct i915_page_directory *pd,
Ben Widawsky678d96f2015-03-16 16:00:56 +00001742 uint32_t start, uint32_t length)
1743{
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03001744 struct i915_ggtt *ggtt = &dev_priv->ggtt;
Michel Thierryec565b32015-04-08 12:13:23 +01001745 struct i915_page_table *pt;
Dave Gordon731f74c2016-06-24 19:37:46 +01001746 uint32_t pde;
Ben Widawsky678d96f2015-03-16 16:00:56 +00001747
Dave Gordon731f74c2016-06-24 19:37:46 +01001748 gen6_for_each_pde(pt, pd, start, length, pde)
Ben Widawsky678d96f2015-03-16 16:00:56 +00001749 gen6_write_pde(pd, pde, pt);
1750
1751 /* Make sure write is complete before other code can use this page
1752 * table. Also require for WC mapped PTEs */
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03001753 readl(ggtt->gsm);
Ben Widawsky3e302542013-04-23 23:15:32 -07001754}
1755
Ben Widawskyb4a74e32013-12-06 14:11:09 -08001756static uint32_t get_pd_offset(struct i915_hw_ppgtt *ppgtt)
Ben Widawsky3e302542013-04-23 23:15:32 -07001757{
Mika Kuoppala44159dd2015-06-25 18:35:07 +03001758 BUG_ON(ppgtt->pd.base.ggtt_offset & 0x3f);
Ben Widawsky3e302542013-04-23 23:15:32 -07001759
Mika Kuoppala44159dd2015-06-25 18:35:07 +03001760 return (ppgtt->pd.base.ggtt_offset / 64) << 16;
Ben Widawskyb4a74e32013-12-06 14:11:09 -08001761}
Ben Widawsky61973492013-04-08 18:43:54 -07001762
Ben Widawsky90252e52013-12-06 14:11:12 -08001763static int hsw_mm_switch(struct i915_hw_ppgtt *ppgtt,
John Harrisone85b26d2015-05-29 17:43:56 +01001764 struct drm_i915_gem_request *req)
Ben Widawsky90252e52013-12-06 14:11:12 -08001765{
Tvrtko Ursulin4a570db2016-03-16 11:00:38 +00001766 struct intel_engine_cs *engine = req->engine;
Tvrtko Ursulin73dec952017-02-14 11:32:42 +00001767 u32 *cs;
Ben Widawsky90252e52013-12-06 14:11:12 -08001768 int ret;
Ben Widawsky61973492013-04-08 18:43:54 -07001769
Ben Widawsky90252e52013-12-06 14:11:12 -08001770 /* NB: TLBs must be flushed and invalidated before a switch */
Chris Wilson7c9cf4e2016-08-02 22:50:25 +01001771 ret = engine->emit_flush(req, EMIT_INVALIDATE | EMIT_FLUSH);
Ben Widawsky90252e52013-12-06 14:11:12 -08001772 if (ret)
1773 return ret;
1774
Tvrtko Ursulin73dec952017-02-14 11:32:42 +00001775 cs = intel_ring_begin(req, 6);
1776 if (IS_ERR(cs))
1777 return PTR_ERR(cs);
Ben Widawsky90252e52013-12-06 14:11:12 -08001778
Tvrtko Ursulin73dec952017-02-14 11:32:42 +00001779 *cs++ = MI_LOAD_REGISTER_IMM(2);
1780 *cs++ = i915_mmio_reg_offset(RING_PP_DIR_DCLV(engine));
1781 *cs++ = PP_DIR_DCLV_2G;
1782 *cs++ = i915_mmio_reg_offset(RING_PP_DIR_BASE(engine));
1783 *cs++ = get_pd_offset(ppgtt);
1784 *cs++ = MI_NOOP;
1785 intel_ring_advance(req, cs);
Ben Widawsky90252e52013-12-06 14:11:12 -08001786
1787 return 0;
1788}
1789
Ben Widawsky48a10382013-12-06 14:11:11 -08001790static int gen7_mm_switch(struct i915_hw_ppgtt *ppgtt,
John Harrisone85b26d2015-05-29 17:43:56 +01001791 struct drm_i915_gem_request *req)
Ben Widawsky48a10382013-12-06 14:11:11 -08001792{
Tvrtko Ursulin4a570db2016-03-16 11:00:38 +00001793 struct intel_engine_cs *engine = req->engine;
Tvrtko Ursulin73dec952017-02-14 11:32:42 +00001794 u32 *cs;
Ben Widawsky48a10382013-12-06 14:11:11 -08001795 int ret;
1796
Ben Widawsky48a10382013-12-06 14:11:11 -08001797 /* NB: TLBs must be flushed and invalidated before a switch */
Chris Wilson7c9cf4e2016-08-02 22:50:25 +01001798 ret = engine->emit_flush(req, EMIT_INVALIDATE | EMIT_FLUSH);
Ben Widawsky48a10382013-12-06 14:11:11 -08001799 if (ret)
1800 return ret;
1801
Tvrtko Ursulin73dec952017-02-14 11:32:42 +00001802 cs = intel_ring_begin(req, 6);
1803 if (IS_ERR(cs))
1804 return PTR_ERR(cs);
Ben Widawsky48a10382013-12-06 14:11:11 -08001805
Tvrtko Ursulin73dec952017-02-14 11:32:42 +00001806 *cs++ = MI_LOAD_REGISTER_IMM(2);
1807 *cs++ = i915_mmio_reg_offset(RING_PP_DIR_DCLV(engine));
1808 *cs++ = PP_DIR_DCLV_2G;
1809 *cs++ = i915_mmio_reg_offset(RING_PP_DIR_BASE(engine));
1810 *cs++ = get_pd_offset(ppgtt);
1811 *cs++ = MI_NOOP;
1812 intel_ring_advance(req, cs);
Ben Widawsky48a10382013-12-06 14:11:11 -08001813
Ben Widawsky90252e52013-12-06 14:11:12 -08001814 /* XXX: RCS is the only one to auto invalidate the TLBs? */
Tvrtko Ursuline2f80392016-03-16 11:00:36 +00001815 if (engine->id != RCS) {
Chris Wilson7c9cf4e2016-08-02 22:50:25 +01001816 ret = engine->emit_flush(req, EMIT_INVALIDATE | EMIT_FLUSH);
Ben Widawsky90252e52013-12-06 14:11:12 -08001817 if (ret)
1818 return ret;
1819 }
1820
Ben Widawsky48a10382013-12-06 14:11:11 -08001821 return 0;
1822}
1823
Ben Widawskyeeb94882013-12-06 14:11:10 -08001824static int gen6_mm_switch(struct i915_hw_ppgtt *ppgtt,
John Harrisone85b26d2015-05-29 17:43:56 +01001825 struct drm_i915_gem_request *req)
Ben Widawskyeeb94882013-12-06 14:11:10 -08001826{
Tvrtko Ursulin4a570db2016-03-16 11:00:38 +00001827 struct intel_engine_cs *engine = req->engine;
Chris Wilson8eb95202016-07-04 08:48:31 +01001828 struct drm_i915_private *dev_priv = req->i915;
Ben Widawsky48a10382013-12-06 14:11:11 -08001829
Tvrtko Ursuline2f80392016-03-16 11:00:36 +00001830 I915_WRITE(RING_PP_DIR_DCLV(engine), PP_DIR_DCLV_2G);
1831 I915_WRITE(RING_PP_DIR_BASE(engine), get_pd_offset(ppgtt));
Ben Widawskyeeb94882013-12-06 14:11:10 -08001832 return 0;
1833}
1834
Tvrtko Ursulinc6be6072016-11-16 08:55:31 +00001835static void gen8_ppgtt_enable(struct drm_i915_private *dev_priv)
Ben Widawskyeeb94882013-12-06 14:11:10 -08001836{
Tvrtko Ursuline2f80392016-03-16 11:00:36 +00001837 struct intel_engine_cs *engine;
Akash Goel3b3f1652016-10-13 22:44:48 +05301838 enum intel_engine_id id;
Ben Widawskyeeb94882013-12-06 14:11:10 -08001839
Akash Goel3b3f1652016-10-13 22:44:48 +05301840 for_each_engine(engine, dev_priv, id) {
Tvrtko Ursulinc6be6072016-11-16 08:55:31 +00001841 u32 four_level = USES_FULL_48BIT_PPGTT(dev_priv) ?
1842 GEN8_GFX_PPGTT_48B : 0;
Tvrtko Ursuline2f80392016-03-16 11:00:36 +00001843 I915_WRITE(RING_MODE_GEN7(engine),
Michel Thierry2dba3232015-07-30 11:06:23 +01001844 _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE | four_level));
Ben Widawskyeeb94882013-12-06 14:11:10 -08001845 }
Ben Widawskyeeb94882013-12-06 14:11:10 -08001846}
1847
Tvrtko Ursulinc6be6072016-11-16 08:55:31 +00001848static void gen7_ppgtt_enable(struct drm_i915_private *dev_priv)
Ben Widawskyb4a74e32013-12-06 14:11:09 -08001849{
Tvrtko Ursuline2f80392016-03-16 11:00:36 +00001850 struct intel_engine_cs *engine;
Ben Widawskyb4a74e32013-12-06 14:11:09 -08001851 uint32_t ecochk, ecobits;
Akash Goel3b3f1652016-10-13 22:44:48 +05301852 enum intel_engine_id id;
Ben Widawskyb4a74e32013-12-06 14:11:09 -08001853
Ben Widawskyb4a74e32013-12-06 14:11:09 -08001854 ecobits = I915_READ(GAC_ECO_BITS);
1855 I915_WRITE(GAC_ECO_BITS, ecobits | ECOBITS_PPGTT_CACHE64B);
1856
1857 ecochk = I915_READ(GAM_ECOCHK);
Tvrtko Ursulin772c2a52016-10-13 11:03:01 +01001858 if (IS_HASWELL(dev_priv)) {
Ben Widawskyb4a74e32013-12-06 14:11:09 -08001859 ecochk |= ECOCHK_PPGTT_WB_HSW;
1860 } else {
1861 ecochk |= ECOCHK_PPGTT_LLC_IVB;
1862 ecochk &= ~ECOCHK_PPGTT_GFDT_IVB;
1863 }
1864 I915_WRITE(GAM_ECOCHK, ecochk);
Ben Widawskyb4a74e32013-12-06 14:11:09 -08001865
Akash Goel3b3f1652016-10-13 22:44:48 +05301866 for_each_engine(engine, dev_priv, id) {
Ben Widawskyeeb94882013-12-06 14:11:10 -08001867 /* GFX_MODE is per-ring on gen7+ */
Tvrtko Ursuline2f80392016-03-16 11:00:36 +00001868 I915_WRITE(RING_MODE_GEN7(engine),
Ben Widawskyb4a74e32013-12-06 14:11:09 -08001869 _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
Ben Widawsky61973492013-04-08 18:43:54 -07001870 }
Ben Widawskyb4a74e32013-12-06 14:11:09 -08001871}
1872
Tvrtko Ursulinc6be6072016-11-16 08:55:31 +00001873static void gen6_ppgtt_enable(struct drm_i915_private *dev_priv)
Ben Widawsky61973492013-04-08 18:43:54 -07001874{
Ben Widawskyb4a74e32013-12-06 14:11:09 -08001875 uint32_t ecochk, gab_ctl, ecobits;
Ben Widawsky61973492013-04-08 18:43:54 -07001876
Ben Widawskyb4a74e32013-12-06 14:11:09 -08001877 ecobits = I915_READ(GAC_ECO_BITS);
1878 I915_WRITE(GAC_ECO_BITS, ecobits | ECOBITS_SNB_BIT |
1879 ECOBITS_PPGTT_CACHE64B);
Ben Widawsky61973492013-04-08 18:43:54 -07001880
Ben Widawskyb4a74e32013-12-06 14:11:09 -08001881 gab_ctl = I915_READ(GAB_CTL);
1882 I915_WRITE(GAB_CTL, gab_ctl | GAB_CTL_CONT_AFTER_PAGEFAULT);
Ben Widawsky61973492013-04-08 18:43:54 -07001883
Ben Widawskyb4a74e32013-12-06 14:11:09 -08001884 ecochk = I915_READ(GAM_ECOCHK);
1885 I915_WRITE(GAM_ECOCHK, ecochk | ECOCHK_SNB_BIT | ECOCHK_PPGTT_CACHE64B);
Ben Widawsky61973492013-04-08 18:43:54 -07001886
Ben Widawskyb4a74e32013-12-06 14:11:09 -08001887 I915_WRITE(GFX_MODE, _MASKED_BIT_ENABLE(GFX_PPGTT_ENABLE));
Ben Widawsky61973492013-04-08 18:43:54 -07001888}
1889
Daniel Vetter1d2a3142012-02-09 17:15:46 +01001890/* PPGTT support for Sandybdrige/Gen6 and later */
Ben Widawsky853ba5d2013-07-16 16:50:05 -07001891static void gen6_ppgtt_clear_range(struct i915_address_space *vm,
Ben Widawsky782f1492014-02-20 11:50:33 -08001892 uint64_t start,
Michał Winiarski4fb84d92016-10-13 14:02:40 +02001893 uint64_t length)
Daniel Vetter1d2a3142012-02-09 17:15:46 +01001894{
Joonas Lahtinene5716f52016-04-07 11:08:03 +03001895 struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
Michel Thierry07749ef2015-03-16 16:00:54 +00001896 gen6_pte_t *pt_vaddr, scratch_pte;
Ben Widawsky782f1492014-02-20 11:50:33 -08001897 unsigned first_entry = start >> PAGE_SHIFT;
1898 unsigned num_entries = length >> PAGE_SHIFT;
Michel Thierry07749ef2015-03-16 16:00:54 +00001899 unsigned act_pt = first_entry / GEN6_PTES;
1900 unsigned first_pte = first_entry % GEN6_PTES;
Daniel Vetter7bddb012012-02-09 17:15:47 +01001901 unsigned last_pte, i;
Daniel Vetter1d2a3142012-02-09 17:15:46 +01001902
Chris Wilson8bcdd0f72016-08-22 08:44:30 +01001903 scratch_pte = vm->pte_encode(vm->scratch_page.daddr,
Michał Winiarski4fb84d92016-10-13 14:02:40 +02001904 I915_CACHE_LLC, 0);
Daniel Vetter1d2a3142012-02-09 17:15:46 +01001905
Daniel Vetter7bddb012012-02-09 17:15:47 +01001906 while (num_entries) {
1907 last_pte = first_pte + num_entries;
Michel Thierry07749ef2015-03-16 16:00:54 +00001908 if (last_pte > GEN6_PTES)
1909 last_pte = GEN6_PTES;
Daniel Vetter1d2a3142012-02-09 17:15:46 +01001910
Mika Kuoppalad1c54ac2015-06-25 18:35:11 +03001911 pt_vaddr = kmap_px(ppgtt->pd.page_table[act_pt]);
Daniel Vetter7bddb012012-02-09 17:15:47 +01001912
1913 for (i = first_pte; i < last_pte; i++)
1914 pt_vaddr[i] = scratch_pte;
Daniel Vetter1d2a3142012-02-09 17:15:46 +01001915
Chris Wilson84486612017-02-15 08:43:40 +00001916 kunmap_px(pt_vaddr);
Daniel Vetter1d2a3142012-02-09 17:15:46 +01001917
Daniel Vetter7bddb012012-02-09 17:15:47 +01001918 num_entries -= last_pte - first_pte;
1919 first_pte = 0;
Daniel Vettera15326a2013-03-19 23:48:39 +01001920 act_pt++;
Daniel Vetter7bddb012012-02-09 17:15:47 +01001921 }
Daniel Vetter1d2a3142012-02-09 17:15:46 +01001922}
1923
Ben Widawsky853ba5d2013-07-16 16:50:05 -07001924static void gen6_ppgtt_insert_entries(struct i915_address_space *vm,
Daniel Vetterdef886c2013-01-24 14:44:56 -08001925 struct sg_table *pages,
Ben Widawsky782f1492014-02-20 11:50:33 -08001926 uint64_t start,
Akash Goel24f3a8c2014-06-17 10:59:42 +05301927 enum i915_cache_level cache_level, u32 flags)
Daniel Vetterdef886c2013-01-24 14:44:56 -08001928{
Joonas Lahtinene5716f52016-04-07 11:08:03 +03001929 struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
Ben Widawsky782f1492014-02-20 11:50:33 -08001930 unsigned first_entry = start >> PAGE_SHIFT;
Michel Thierry07749ef2015-03-16 16:00:54 +00001931 unsigned act_pt = first_entry / GEN6_PTES;
1932 unsigned act_pte = first_entry % GEN6_PTES;
Chris Wilsonb31144c2017-02-15 08:43:36 +00001933 const u32 pte_encode = vm->pte_encode(0, cache_level, flags);
1934 struct sgt_dma iter;
1935 gen6_pte_t *vaddr;
Daniel Vetterdef886c2013-01-24 14:44:56 -08001936
Chris Wilsonb31144c2017-02-15 08:43:36 +00001937 vaddr = kmap_px(ppgtt->pd.page_table[act_pt]);
1938 iter.sg = pages->sgl;
1939 iter.dma = sg_dma_address(iter.sg);
1940 iter.max = iter.dma + iter.sg->length;
1941 do {
1942 vaddr[act_pte] = pte_encode | GEN6_PTE_ADDR_ENCODE(iter.dma);
Daniel Vetterdef886c2013-01-24 14:44:56 -08001943
Chris Wilsonb31144c2017-02-15 08:43:36 +00001944 iter.dma += PAGE_SIZE;
1945 if (iter.dma == iter.max) {
1946 iter.sg = __sg_next(iter.sg);
1947 if (!iter.sg)
1948 break;
1949
1950 iter.dma = sg_dma_address(iter.sg);
1951 iter.max = iter.dma + iter.sg->length;
1952 }
Akash Goel24f3a8c2014-06-17 10:59:42 +05301953
Michel Thierry07749ef2015-03-16 16:00:54 +00001954 if (++act_pte == GEN6_PTES) {
Chris Wilson84486612017-02-15 08:43:40 +00001955 kunmap_px(vaddr);
Chris Wilsonb31144c2017-02-15 08:43:36 +00001956 vaddr = kmap_px(ppgtt->pd.page_table[++act_pt]);
Imre Deak6e995e22013-02-18 19:28:04 +02001957 act_pte = 0;
Daniel Vetterdef886c2013-01-24 14:44:56 -08001958 }
Chris Wilsonb31144c2017-02-15 08:43:36 +00001959 } while (1);
Chris Wilson84486612017-02-15 08:43:40 +00001960 kunmap_px(vaddr);
Daniel Vetterdef886c2013-01-24 14:44:56 -08001961}
1962
Ben Widawsky678d96f2015-03-16 16:00:56 +00001963static int gen6_alloc_va_range(struct i915_address_space *vm,
Mika Kuoppalaa05d80e2015-06-25 18:35:04 +03001964 uint64_t start_in, uint64_t length_in)
Ben Widawsky678d96f2015-03-16 16:00:56 +00001965{
Michel Thierry4933d512015-03-24 15:46:22 +00001966 DECLARE_BITMAP(new_page_tables, I915_PDES);
Chris Wilson49d73912016-11-29 09:50:08 +00001967 struct drm_i915_private *dev_priv = vm->i915;
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03001968 struct i915_ggtt *ggtt = &dev_priv->ggtt;
Joonas Lahtinene5716f52016-04-07 11:08:03 +03001969 struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
Michel Thierryec565b32015-04-08 12:13:23 +01001970 struct i915_page_table *pt;
Mika Kuoppalaa05d80e2015-06-25 18:35:04 +03001971 uint32_t start, length, start_save, length_save;
Dave Gordon731f74c2016-06-24 19:37:46 +01001972 uint32_t pde;
Michel Thierry4933d512015-03-24 15:46:22 +00001973 int ret;
1974
Mika Kuoppalaa05d80e2015-06-25 18:35:04 +03001975 start = start_save = start_in;
1976 length = length_save = length_in;
Michel Thierry4933d512015-03-24 15:46:22 +00001977
1978 bitmap_zero(new_page_tables, I915_PDES);
1979
1980 /* The allocation is done in two stages so that we can bail out with
1981 * minimal amount of pain. The first stage finds new page tables that
1982 * need allocation. The second stage marks use ptes within the page
1983 * tables.
1984 */
Dave Gordon731f74c2016-06-24 19:37:46 +01001985 gen6_for_each_pde(pt, &ppgtt->pd, start, length, pde) {
Mika Kuoppala79ab9372015-06-25 18:35:17 +03001986 if (pt != vm->scratch_pt) {
Michel Thierry4933d512015-03-24 15:46:22 +00001987 WARN_ON(bitmap_empty(pt->used_ptes, GEN6_PTES));
1988 continue;
1989 }
1990
1991 /* We've already allocated a page table */
1992 WARN_ON(!bitmap_empty(pt->used_ptes, GEN6_PTES));
1993
Chris Wilson84486612017-02-15 08:43:40 +00001994 pt = alloc_pt(vm);
Michel Thierry4933d512015-03-24 15:46:22 +00001995 if (IS_ERR(pt)) {
1996 ret = PTR_ERR(pt);
1997 goto unwind_out;
1998 }
1999
2000 gen6_initialize_pt(vm, pt);
2001
2002 ppgtt->pd.page_table[pde] = pt;
Mika Kuoppala966082c2015-06-25 18:35:19 +03002003 __set_bit(pde, new_page_tables);
Michel Thierry72744cb2015-03-24 15:46:23 +00002004 trace_i915_page_table_entry_alloc(vm, pde, start, GEN6_PDE_SHIFT);
Michel Thierry4933d512015-03-24 15:46:22 +00002005 }
2006
2007 start = start_save;
2008 length = length_save;
Ben Widawsky678d96f2015-03-16 16:00:56 +00002009
Dave Gordon731f74c2016-06-24 19:37:46 +01002010 gen6_for_each_pde(pt, &ppgtt->pd, start, length, pde) {
Ben Widawsky678d96f2015-03-16 16:00:56 +00002011 DECLARE_BITMAP(tmp_bitmap, GEN6_PTES);
2012
2013 bitmap_zero(tmp_bitmap, GEN6_PTES);
2014 bitmap_set(tmp_bitmap, gen6_pte_index(start),
2015 gen6_pte_count(start, length));
2016
Mika Kuoppala966082c2015-06-25 18:35:19 +03002017 if (__test_and_clear_bit(pde, new_page_tables))
Michel Thierry4933d512015-03-24 15:46:22 +00002018 gen6_write_pde(&ppgtt->pd, pde, pt);
2019
Michel Thierry72744cb2015-03-24 15:46:23 +00002020 trace_i915_page_table_entry_map(vm, pde, pt,
2021 gen6_pte_index(start),
2022 gen6_pte_count(start, length),
2023 GEN6_PTES);
Michel Thierry4933d512015-03-24 15:46:22 +00002024 bitmap_or(pt->used_ptes, tmp_bitmap, pt->used_ptes,
Ben Widawsky678d96f2015-03-16 16:00:56 +00002025 GEN6_PTES);
2026 }
2027
Michel Thierry4933d512015-03-24 15:46:22 +00002028 WARN_ON(!bitmap_empty(new_page_tables, I915_PDES));
2029
2030 /* Make sure write is complete before other code can use this page
2031 * table. Also require for WC mapped PTEs */
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03002032 readl(ggtt->gsm);
Michel Thierry4933d512015-03-24 15:46:22 +00002033
Ben Widawsky563222a2015-03-19 12:53:28 +00002034 mark_tlbs_dirty(ppgtt);
Ben Widawsky678d96f2015-03-16 16:00:56 +00002035 return 0;
Michel Thierry4933d512015-03-24 15:46:22 +00002036
2037unwind_out:
2038 for_each_set_bit(pde, new_page_tables, I915_PDES) {
Michel Thierryec565b32015-04-08 12:13:23 +01002039 struct i915_page_table *pt = ppgtt->pd.page_table[pde];
Michel Thierry4933d512015-03-24 15:46:22 +00002040
Mika Kuoppala79ab9372015-06-25 18:35:17 +03002041 ppgtt->pd.page_table[pde] = vm->scratch_pt;
Chris Wilson84486612017-02-15 08:43:40 +00002042 free_pt(vm, pt);
Michel Thierry4933d512015-03-24 15:46:22 +00002043 }
2044
2045 mark_tlbs_dirty(ppgtt);
2046 return ret;
Ben Widawsky678d96f2015-03-16 16:00:56 +00002047}
2048
Mika Kuoppala8776f022015-06-30 18:16:40 +03002049static int gen6_init_scratch(struct i915_address_space *vm)
2050{
Chris Wilson8bcdd0f72016-08-22 08:44:30 +01002051 int ret;
Mika Kuoppala8776f022015-06-30 18:16:40 +03002052
Chris Wilson84486612017-02-15 08:43:40 +00002053 ret = setup_scratch_page(vm, I915_GFP_DMA);
Chris Wilson8bcdd0f72016-08-22 08:44:30 +01002054 if (ret)
2055 return ret;
Mika Kuoppala8776f022015-06-30 18:16:40 +03002056
Chris Wilson84486612017-02-15 08:43:40 +00002057 vm->scratch_pt = alloc_pt(vm);
Mika Kuoppala8776f022015-06-30 18:16:40 +03002058 if (IS_ERR(vm->scratch_pt)) {
Chris Wilson84486612017-02-15 08:43:40 +00002059 cleanup_scratch_page(vm);
Mika Kuoppala8776f022015-06-30 18:16:40 +03002060 return PTR_ERR(vm->scratch_pt);
2061 }
2062
2063 gen6_initialize_pt(vm, vm->scratch_pt);
2064
2065 return 0;
2066}
2067
2068static void gen6_free_scratch(struct i915_address_space *vm)
2069{
Chris Wilson84486612017-02-15 08:43:40 +00002070 free_pt(vm, vm->scratch_pt);
2071 cleanup_scratch_page(vm);
Mika Kuoppala8776f022015-06-30 18:16:40 +03002072}
2073
Daniel Vetter061dd492015-04-14 17:35:13 +02002074static void gen6_ppgtt_cleanup(struct i915_address_space *vm)
Ben Widawskya00d8252014-02-19 22:05:48 -08002075{
Joonas Lahtinene5716f52016-04-07 11:08:03 +03002076 struct i915_hw_ppgtt *ppgtt = i915_vm_to_ppgtt(vm);
Dave Gordon731f74c2016-06-24 19:37:46 +01002077 struct i915_page_directory *pd = &ppgtt->pd;
Michel Thierry09942c62015-04-08 12:13:30 +01002078 struct i915_page_table *pt;
2079 uint32_t pde;
Daniel Vetter3440d262013-01-24 13:49:56 -08002080
Daniel Vetter061dd492015-04-14 17:35:13 +02002081 drm_mm_remove_node(&ppgtt->node);
2082
Dave Gordon731f74c2016-06-24 19:37:46 +01002083 gen6_for_all_pdes(pt, pd, pde)
Mika Kuoppala79ab9372015-06-25 18:35:17 +03002084 if (pt != vm->scratch_pt)
Chris Wilson84486612017-02-15 08:43:40 +00002085 free_pt(vm, pt);
Michel Thierry4933d512015-03-24 15:46:22 +00002086
Mika Kuoppala8776f022015-06-30 18:16:40 +03002087 gen6_free_scratch(vm);
Daniel Vetter3440d262013-01-24 13:49:56 -08002088}
2089
Ben Widawskyb1465202014-02-19 22:05:49 -08002090static int gen6_ppgtt_allocate_page_directories(struct i915_hw_ppgtt *ppgtt)
Daniel Vetter3440d262013-01-24 13:49:56 -08002091{
Mika Kuoppala8776f022015-06-30 18:16:40 +03002092 struct i915_address_space *vm = &ppgtt->base;
Chris Wilson49d73912016-11-29 09:50:08 +00002093 struct drm_i915_private *dev_priv = ppgtt->base.i915;
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03002094 struct i915_ggtt *ggtt = &dev_priv->ggtt;
Ben Widawskyb1465202014-02-19 22:05:49 -08002095 int ret;
Daniel Vetter1d2a3142012-02-09 17:15:46 +01002096
Ben Widawskyc8d4c0d2013-12-06 14:11:07 -08002097 /* PPGTT PDEs reside in the GGTT and consists of 512 entries. The
2098 * allocator works in address space sizes, so it's multiplied by page
2099 * size. We allocate at the top of the GTT to avoid fragmentation.
2100 */
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03002101 BUG_ON(!drm_mm_initialized(&ggtt->base.mm));
Michel Thierry4933d512015-03-24 15:46:22 +00002102
Mika Kuoppala8776f022015-06-30 18:16:40 +03002103 ret = gen6_init_scratch(vm);
2104 if (ret)
2105 return ret;
Michel Thierry4933d512015-03-24 15:46:22 +00002106
Chris Wilsone007b192017-01-11 11:23:10 +00002107 ret = i915_gem_gtt_insert(&ggtt->base, &ppgtt->node,
2108 GEN6_PD_SIZE, GEN6_PD_ALIGN,
2109 I915_COLOR_UNEVICTABLE,
2110 0, ggtt->base.total,
2111 PIN_HIGH);
Ben Widawskyc8c26622015-01-22 17:01:25 +00002112 if (ret)
Ben Widawsky678d96f2015-03-16 16:00:56 +00002113 goto err_out;
2114
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03002115 if (ppgtt->node.start < ggtt->mappable_end)
Ben Widawskyc8d4c0d2013-12-06 14:11:07 -08002116 DRM_DEBUG("Forced to use aperture for PDEs\n");
Daniel Vetter1d2a3142012-02-09 17:15:46 +01002117
Ben Widawskyc8c26622015-01-22 17:01:25 +00002118 return 0;
Ben Widawsky678d96f2015-03-16 16:00:56 +00002119
2120err_out:
Mika Kuoppala8776f022015-06-30 18:16:40 +03002121 gen6_free_scratch(vm);
Ben Widawsky678d96f2015-03-16 16:00:56 +00002122 return ret;
Ben Widawskyb1465202014-02-19 22:05:49 -08002123}
2124
Ben Widawskyb1465202014-02-19 22:05:49 -08002125static int gen6_ppgtt_alloc(struct i915_hw_ppgtt *ppgtt)
2126{
kbuild test robot2f2cf682015-03-27 19:26:35 +08002127 return gen6_ppgtt_allocate_page_directories(ppgtt);
Ben Widawskyb1465202014-02-19 22:05:49 -08002128}
2129
Michel Thierry4933d512015-03-24 15:46:22 +00002130static void gen6_scratch_va_range(struct i915_hw_ppgtt *ppgtt,
2131 uint64_t start, uint64_t length)
2132{
Michel Thierryec565b32015-04-08 12:13:23 +01002133 struct i915_page_table *unused;
Dave Gordon731f74c2016-06-24 19:37:46 +01002134 uint32_t pde;
Michel Thierry4933d512015-03-24 15:46:22 +00002135
Dave Gordon731f74c2016-06-24 19:37:46 +01002136 gen6_for_each_pde(unused, &ppgtt->pd, start, length, pde)
Mika Kuoppala79ab9372015-06-25 18:35:17 +03002137 ppgtt->pd.page_table[pde] = ppgtt->base.scratch_pt;
Michel Thierry4933d512015-03-24 15:46:22 +00002138}
2139
Daniel Vetter5c5f6452015-04-14 17:35:14 +02002140static int gen6_ppgtt_init(struct i915_hw_ppgtt *ppgtt)
Ben Widawskyb1465202014-02-19 22:05:49 -08002141{
Chris Wilson49d73912016-11-29 09:50:08 +00002142 struct drm_i915_private *dev_priv = ppgtt->base.i915;
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03002143 struct i915_ggtt *ggtt = &dev_priv->ggtt;
Ben Widawskyb1465202014-02-19 22:05:49 -08002144 int ret;
2145
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03002146 ppgtt->base.pte_encode = ggtt->base.pte_encode;
Tvrtko Ursulin5db94012016-10-13 11:03:10 +01002147 if (intel_vgpu_active(dev_priv) || IS_GEN6(dev_priv))
Ben Widawsky48a10382013-12-06 14:11:11 -08002148 ppgtt->switch_mm = gen6_mm_switch;
Tvrtko Ursulin772c2a52016-10-13 11:03:01 +01002149 else if (IS_HASWELL(dev_priv))
Ben Widawsky90252e52013-12-06 14:11:12 -08002150 ppgtt->switch_mm = hsw_mm_switch;
Tvrtko Ursulin5db94012016-10-13 11:03:10 +01002151 else if (IS_GEN7(dev_priv))
Ben Widawsky48a10382013-12-06 14:11:11 -08002152 ppgtt->switch_mm = gen7_mm_switch;
Chris Wilson8eb95202016-07-04 08:48:31 +01002153 else
Ben Widawskyb4a74e32013-12-06 14:11:09 -08002154 BUG();
Ben Widawskyb1465202014-02-19 22:05:49 -08002155
2156 ret = gen6_ppgtt_alloc(ppgtt);
2157 if (ret)
2158 return ret;
2159
Daniel Vetter5c5f6452015-04-14 17:35:14 +02002160 ppgtt->base.allocate_va_range = gen6_alloc_va_range;
Ben Widawsky853ba5d2013-07-16 16:50:05 -07002161 ppgtt->base.clear_range = gen6_ppgtt_clear_range;
2162 ppgtt->base.insert_entries = gen6_ppgtt_insert_entries;
Daniel Vetter777dc5b2015-04-14 17:35:12 +02002163 ppgtt->base.unbind_vma = ppgtt_unbind_vma;
2164 ppgtt->base.bind_vma = ppgtt_bind_vma;
Ben Widawsky853ba5d2013-07-16 16:50:05 -07002165 ppgtt->base.cleanup = gen6_ppgtt_cleanup;
Ben Widawsky686e1f62013-11-25 09:54:34 -08002166 ppgtt->base.start = 0;
Michel Thierry09942c62015-04-08 12:13:30 +01002167 ppgtt->base.total = I915_PDES * GEN6_PTES * PAGE_SIZE;
Ben Widawskyb1465202014-02-19 22:05:49 -08002168 ppgtt->debug_dump = gen6_dump_ppgtt;
Daniel Vetter1d2a3142012-02-09 17:15:46 +01002169
Mika Kuoppala44159dd2015-06-25 18:35:07 +03002170 ppgtt->pd.base.ggtt_offset =
Michel Thierry07749ef2015-03-16 16:00:54 +00002171 ppgtt->node.start / PAGE_SIZE * sizeof(gen6_pte_t);
Daniel Vetter1d2a3142012-02-09 17:15:46 +01002172
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03002173 ppgtt->pd_addr = (gen6_pte_t __iomem *)ggtt->gsm +
Mika Kuoppala44159dd2015-06-25 18:35:07 +03002174 ppgtt->pd.base.ggtt_offset / sizeof(gen6_pte_t);
Ben Widawsky678d96f2015-03-16 16:00:56 +00002175
Daniel Vetter5c5f6452015-04-14 17:35:14 +02002176 gen6_scratch_va_range(ppgtt, 0, ppgtt->base.total);
Daniel Vetter1d2a3142012-02-09 17:15:46 +01002177
Ben Widawsky678d96f2015-03-16 16:00:56 +00002178 gen6_write_page_range(dev_priv, &ppgtt->pd, 0, ppgtt->base.total);
2179
Thierry Reding440fd522015-01-23 09:05:06 +01002180 DRM_DEBUG_DRIVER("Allocated pde space (%lldM) at GTT entry: %llx\n",
Ben Widawskyc8d4c0d2013-12-06 14:11:07 -08002181 ppgtt->node.size >> 20,
2182 ppgtt->node.start / PAGE_SIZE);
Daniel Vetter1d2a3142012-02-09 17:15:46 +01002183
Daniel Vetterfa76da32014-08-06 20:19:54 +02002184 DRM_DEBUG("Adding PPGTT at offset %x\n",
Mika Kuoppala44159dd2015-06-25 18:35:07 +03002185 ppgtt->pd.base.ggtt_offset << 10);
Daniel Vetterfa76da32014-08-06 20:19:54 +02002186
Daniel Vetter1d2a3142012-02-09 17:15:46 +01002187 return 0;
Daniel Vetter3440d262013-01-24 13:49:56 -08002188}
2189
Chris Wilson2bfa9962016-08-04 07:52:25 +01002190static int __hw_ppgtt_init(struct i915_hw_ppgtt *ppgtt,
2191 struct drm_i915_private *dev_priv)
Daniel Vetter3440d262013-01-24 13:49:56 -08002192{
Chris Wilson49d73912016-11-29 09:50:08 +00002193 ppgtt->base.i915 = dev_priv;
Chris Wilson84486612017-02-15 08:43:40 +00002194 ppgtt->base.dma = &dev_priv->drm.pdev->dev;
Daniel Vetter3440d262013-01-24 13:49:56 -08002195
Chris Wilson2bfa9962016-08-04 07:52:25 +01002196 if (INTEL_INFO(dev_priv)->gen < 8)
Daniel Vetter5c5f6452015-04-14 17:35:14 +02002197 return gen6_ppgtt_init(ppgtt);
Ben Widawsky3ed124b2013-04-08 18:43:53 -07002198 else
Michel Thierryd7b26332015-04-08 12:13:34 +01002199 return gen8_ppgtt_init(ppgtt);
Daniel Vetterfa76da32014-08-06 20:19:54 +02002200}
Mika Kuoppalac114f762015-06-25 18:35:13 +03002201
Michał Winiarskia2cad9d2015-09-16 11:49:00 +02002202static void i915_address_space_init(struct i915_address_space *vm,
Chris Wilson80b204b2016-10-28 13:58:58 +01002203 struct drm_i915_private *dev_priv,
2204 const char *name)
Michał Winiarskia2cad9d2015-09-16 11:49:00 +02002205{
Chris Wilson80b204b2016-10-28 13:58:58 +01002206 i915_gem_timeline_init(dev_priv, &vm->timeline, name);
Chris Wilson47db9222017-02-06 08:45:46 +00002207
Michał Winiarskia2cad9d2015-09-16 11:49:00 +02002208 drm_mm_init(&vm->mm, vm->start, vm->total);
Chris Wilson47db9222017-02-06 08:45:46 +00002209 vm->mm.head_node.color = I915_COLOR_UNEVICTABLE;
2210
Michał Winiarskia2cad9d2015-09-16 11:49:00 +02002211 INIT_LIST_HEAD(&vm->active_list);
2212 INIT_LIST_HEAD(&vm->inactive_list);
Chris Wilson50e046b2016-08-04 07:52:46 +01002213 INIT_LIST_HEAD(&vm->unbound_list);
Chris Wilson47db9222017-02-06 08:45:46 +00002214
Michał Winiarskia2cad9d2015-09-16 11:49:00 +02002215 list_add_tail(&vm->global_link, &dev_priv->vm_list);
Chris Wilson84486612017-02-15 08:43:40 +00002216 pagevec_init(&vm->free_pages, false);
Michał Winiarskia2cad9d2015-09-16 11:49:00 +02002217}
2218
Matthew Aulded9724d2016-11-17 21:04:10 +00002219static void i915_address_space_fini(struct i915_address_space *vm)
2220{
Chris Wilson84486612017-02-15 08:43:40 +00002221 if (pagevec_count(&vm->free_pages))
2222 vm_free_pages_release(vm);
2223
Matthew Aulded9724d2016-11-17 21:04:10 +00002224 i915_gem_timeline_fini(&vm->timeline);
2225 drm_mm_takedown(&vm->mm);
2226 list_del(&vm->global_link);
2227}
2228
Tvrtko Ursulinc6be6072016-11-16 08:55:31 +00002229static void gtt_write_workarounds(struct drm_i915_private *dev_priv)
Tim Gored5165eb2016-02-04 11:49:34 +00002230{
Tim Gored5165eb2016-02-04 11:49:34 +00002231 /* This function is for gtt related workarounds. This function is
2232 * called on driver load and after a GPU reset, so you can place
2233 * workarounds here even if they get overwritten by GPU reset.
2234 */
Ander Conselvan de Oliveira9fb50262017-01-26 11:16:58 +02002235 /* WaIncreaseDefaultTLBEntries:chv,bdw,skl,bxt,kbl,glk */
Tvrtko Ursulin86527442016-10-13 11:03:00 +01002236 if (IS_BROADWELL(dev_priv))
Tim Gored5165eb2016-02-04 11:49:34 +00002237 I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN8_L3_LRA_1_GPGPU_DEFAULT_VALUE_BDW);
Tvrtko Ursulin920a14b2016-10-14 10:13:44 +01002238 else if (IS_CHERRYVIEW(dev_priv))
Tim Gored5165eb2016-02-04 11:49:34 +00002239 I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN8_L3_LRA_1_GPGPU_DEFAULT_VALUE_CHV);
Rodrigo Vivib976dc52017-01-23 10:32:37 -08002240 else if (IS_GEN9_BC(dev_priv))
Tim Gored5165eb2016-02-04 11:49:34 +00002241 I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_SKL);
Ander Conselvan de Oliveira9fb50262017-01-26 11:16:58 +02002242 else if (IS_GEN9_LP(dev_priv))
Tim Gored5165eb2016-02-04 11:49:34 +00002243 I915_WRITE(GEN8_L3_LRA_1_GPGPU, GEN9_L3_LRA_1_GPGPU_DEFAULT_VALUE_BXT);
2244}
2245
Tvrtko Ursulinc6be6072016-11-16 08:55:31 +00002246int i915_ppgtt_init_hw(struct drm_i915_private *dev_priv)
Daniel Vetter82460d92014-08-06 20:19:53 +02002247{
Tvrtko Ursulinc6be6072016-11-16 08:55:31 +00002248 gtt_write_workarounds(dev_priv);
Tim Gored5165eb2016-02-04 11:49:34 +00002249
Thomas Daniel671b50132014-08-20 16:24:50 +01002250 /* In the case of execlists, PPGTT is enabled by the context descriptor
2251 * and the PDPs are contained within the context itself. We don't
2252 * need to do anything here. */
2253 if (i915.enable_execlists)
2254 return 0;
2255
Tvrtko Ursulinc6be6072016-11-16 08:55:31 +00002256 if (!USES_PPGTT(dev_priv))
Daniel Vetter82460d92014-08-06 20:19:53 +02002257 return 0;
2258
Tvrtko Ursulin5db94012016-10-13 11:03:10 +01002259 if (IS_GEN6(dev_priv))
Tvrtko Ursulinc6be6072016-11-16 08:55:31 +00002260 gen6_ppgtt_enable(dev_priv);
Tvrtko Ursulin5db94012016-10-13 11:03:10 +01002261 else if (IS_GEN7(dev_priv))
Tvrtko Ursulinc6be6072016-11-16 08:55:31 +00002262 gen7_ppgtt_enable(dev_priv);
2263 else if (INTEL_GEN(dev_priv) >= 8)
2264 gen8_ppgtt_enable(dev_priv);
Daniel Vetter82460d92014-08-06 20:19:53 +02002265 else
Tvrtko Ursulinc6be6072016-11-16 08:55:31 +00002266 MISSING_CASE(INTEL_GEN(dev_priv));
Daniel Vetter82460d92014-08-06 20:19:53 +02002267
John Harrison4ad2fd82015-06-18 13:11:20 +01002268 return 0;
Daniel Vetter1d2a3142012-02-09 17:15:46 +01002269}
John Harrison4ad2fd82015-06-18 13:11:20 +01002270
Daniel Vetter4d884702014-08-06 15:04:47 +02002271struct i915_hw_ppgtt *
Chris Wilson2bfa9962016-08-04 07:52:25 +01002272i915_ppgtt_create(struct drm_i915_private *dev_priv,
Chris Wilson80b204b2016-10-28 13:58:58 +01002273 struct drm_i915_file_private *fpriv,
2274 const char *name)
Daniel Vetter4d884702014-08-06 15:04:47 +02002275{
2276 struct i915_hw_ppgtt *ppgtt;
2277 int ret;
2278
2279 ppgtt = kzalloc(sizeof(*ppgtt), GFP_KERNEL);
2280 if (!ppgtt)
2281 return ERR_PTR(-ENOMEM);
2282
Chris Wilson1188bc62017-02-15 08:43:38 +00002283 ret = __hw_ppgtt_init(ppgtt, dev_priv);
Daniel Vetter4d884702014-08-06 15:04:47 +02002284 if (ret) {
2285 kfree(ppgtt);
2286 return ERR_PTR(ret);
2287 }
2288
Chris Wilson1188bc62017-02-15 08:43:38 +00002289 kref_init(&ppgtt->ref);
2290 i915_address_space_init(&ppgtt->base, dev_priv, name);
2291 ppgtt->base.file = fpriv;
2292
Daniele Ceraolo Spurio198c9742014-11-10 13:44:31 +00002293 trace_i915_ppgtt_create(&ppgtt->base);
2294
Daniel Vetter4d884702014-08-06 15:04:47 +02002295 return ppgtt;
2296}
2297
Chris Wilson0c7eeda2017-01-11 21:09:25 +00002298void i915_ppgtt_close(struct i915_address_space *vm)
2299{
2300 struct list_head *phases[] = {
2301 &vm->active_list,
2302 &vm->inactive_list,
2303 &vm->unbound_list,
2304 NULL,
2305 }, **phase;
2306
2307 GEM_BUG_ON(vm->closed);
2308 vm->closed = true;
2309
2310 for (phase = phases; *phase; phase++) {
2311 struct i915_vma *vma, *vn;
2312
2313 list_for_each_entry_safe(vma, vn, *phase, vm_link)
2314 if (!i915_vma_is_closed(vma))
2315 i915_vma_close(vma);
2316 }
2317}
2318
Matthew Aulded9724d2016-11-17 21:04:10 +00002319void i915_ppgtt_release(struct kref *kref)
Daniel Vetteree960be2014-08-06 15:04:45 +02002320{
2321 struct i915_hw_ppgtt *ppgtt =
2322 container_of(kref, struct i915_hw_ppgtt, ref);
2323
Daniele Ceraolo Spurio198c9742014-11-10 13:44:31 +00002324 trace_i915_ppgtt_release(&ppgtt->base);
2325
Chris Wilson50e046b2016-08-04 07:52:46 +01002326 /* vmas should already be unbound and destroyed */
Daniel Vetteree960be2014-08-06 15:04:45 +02002327 WARN_ON(!list_empty(&ppgtt->base.active_list));
2328 WARN_ON(!list_empty(&ppgtt->base.inactive_list));
Chris Wilson50e046b2016-08-04 07:52:46 +01002329 WARN_ON(!list_empty(&ppgtt->base.unbound_list));
Daniel Vetteree960be2014-08-06 15:04:45 +02002330
2331 ppgtt->base.cleanup(&ppgtt->base);
Chris Wilson84486612017-02-15 08:43:40 +00002332 i915_address_space_fini(&ppgtt->base);
Daniel Vetteree960be2014-08-06 15:04:45 +02002333 kfree(ppgtt);
2334}
Daniel Vetter1d2a3142012-02-09 17:15:46 +01002335
Ben Widawskya81cc002013-01-18 12:30:31 -08002336/* Certain Gen5 chipsets require require idling the GPU before
2337 * unmapping anything from the GTT when VT-d is enabled.
2338 */
Chris Wilson97d6d7a2016-08-04 07:52:22 +01002339static bool needs_idle_maps(struct drm_i915_private *dev_priv)
Ben Widawskya81cc002013-01-18 12:30:31 -08002340{
2341#ifdef CONFIG_INTEL_IOMMU
2342 /* Query intel_iommu to see if we need the workaround. Presumably that
2343 * was loaded first.
2344 */
Chris Wilson97d6d7a2016-08-04 07:52:22 +01002345 if (IS_GEN5(dev_priv) && IS_MOBILE(dev_priv) && intel_iommu_gfx_mapped)
Ben Widawskya81cc002013-01-18 12:30:31 -08002346 return true;
2347#endif
2348 return false;
2349}
2350
Chris Wilsondc979972016-05-10 14:10:04 +01002351void i915_check_and_clear_faults(struct drm_i915_private *dev_priv)
Ben Widawsky828c7902013-10-16 09:21:30 -07002352{
Tvrtko Ursuline2f80392016-03-16 11:00:36 +00002353 struct intel_engine_cs *engine;
Akash Goel3b3f1652016-10-13 22:44:48 +05302354 enum intel_engine_id id;
Ben Widawsky828c7902013-10-16 09:21:30 -07002355
Chris Wilsondc979972016-05-10 14:10:04 +01002356 if (INTEL_INFO(dev_priv)->gen < 6)
Ben Widawsky828c7902013-10-16 09:21:30 -07002357 return;
2358
Akash Goel3b3f1652016-10-13 22:44:48 +05302359 for_each_engine(engine, dev_priv, id) {
Ben Widawsky828c7902013-10-16 09:21:30 -07002360 u32 fault_reg;
Tvrtko Ursuline2f80392016-03-16 11:00:36 +00002361 fault_reg = I915_READ(RING_FAULT_REG(engine));
Ben Widawsky828c7902013-10-16 09:21:30 -07002362 if (fault_reg & RING_FAULT_VALID) {
2363 DRM_DEBUG_DRIVER("Unexpected fault\n"
Paulo Zanoni59a5d292014-10-30 15:52:45 -02002364 "\tAddr: 0x%08lx\n"
Ben Widawsky828c7902013-10-16 09:21:30 -07002365 "\tAddress space: %s\n"
2366 "\tSource ID: %d\n"
2367 "\tType: %d\n",
2368 fault_reg & PAGE_MASK,
2369 fault_reg & RING_FAULT_GTTSEL_MASK ? "GGTT" : "PPGTT",
2370 RING_FAULT_SRCID(fault_reg),
2371 RING_FAULT_FAULT_TYPE(fault_reg));
Tvrtko Ursuline2f80392016-03-16 11:00:36 +00002372 I915_WRITE(RING_FAULT_REG(engine),
Ben Widawsky828c7902013-10-16 09:21:30 -07002373 fault_reg & ~RING_FAULT_VALID);
2374 }
2375 }
Akash Goel3b3f1652016-10-13 22:44:48 +05302376
2377 /* Engine specific init may not have been done till this point. */
2378 if (dev_priv->engine[RCS])
2379 POSTING_READ(RING_FAULT_REG(dev_priv->engine[RCS]));
Ben Widawsky828c7902013-10-16 09:21:30 -07002380}
2381
Tvrtko Ursulin275a9912016-11-16 08:55:34 +00002382void i915_gem_suspend_gtt_mappings(struct drm_i915_private *dev_priv)
Ben Widawsky828c7902013-10-16 09:21:30 -07002383{
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03002384 struct i915_ggtt *ggtt = &dev_priv->ggtt;
Ben Widawsky828c7902013-10-16 09:21:30 -07002385
2386 /* Don't bother messing with faults pre GEN6 as we have little
2387 * documentation supporting that it's a good idea.
2388 */
Tvrtko Ursulin275a9912016-11-16 08:55:34 +00002389 if (INTEL_GEN(dev_priv) < 6)
Ben Widawsky828c7902013-10-16 09:21:30 -07002390 return;
2391
Chris Wilsondc979972016-05-10 14:10:04 +01002392 i915_check_and_clear_faults(dev_priv);
Ben Widawsky828c7902013-10-16 09:21:30 -07002393
Michał Winiarski4fb84d92016-10-13 14:02:40 +02002394 ggtt->base.clear_range(&ggtt->base, ggtt->base.start, ggtt->base.total);
Chris Wilson91e56492014-09-25 10:13:12 +01002395
Chris Wilson7c3f86b2017-01-12 11:00:49 +00002396 i915_ggtt_invalidate(dev_priv);
Ben Widawsky828c7902013-10-16 09:21:30 -07002397}
2398
Chris Wilson03ac84f2016-10-28 13:58:36 +01002399int i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj,
2400 struct sg_table *pages)
Daniel Vetter7c2e6fd2010-11-06 10:10:47 +01002401{
Chris Wilson1a292fa2017-01-06 15:22:39 +00002402 do {
2403 if (dma_map_sg(&obj->base.dev->pdev->dev,
2404 pages->sgl, pages->nents,
2405 PCI_DMA_BIDIRECTIONAL))
2406 return 0;
2407
2408 /* If the DMA remap fails, one cause can be that we have
2409 * too many objects pinned in a small remapping table,
2410 * such as swiotlb. Incrementally purge all other objects and
2411 * try again - if there are no more pages to remove from
2412 * the DMA remapper, i915_gem_shrink will return 0.
2413 */
2414 GEM_BUG_ON(obj->mm.pages == pages);
2415 } while (i915_gem_shrink(to_i915(obj->base.dev),
2416 obj->base.size >> PAGE_SHIFT,
2417 I915_SHRINK_BOUND |
2418 I915_SHRINK_UNBOUND |
2419 I915_SHRINK_ACTIVE));
Chris Wilson9da3da62012-06-01 15:20:22 +01002420
Chris Wilson03ac84f2016-10-28 13:58:36 +01002421 return -ENOSPC;
Daniel Vetter7c2e6fd2010-11-06 10:10:47 +01002422}
2423
Daniel Vetter2c642b02015-04-14 17:35:26 +02002424static void gen8_set_pte(void __iomem *addr, gen8_pte_t pte)
Ben Widawsky94ec8f62013-11-02 21:07:18 -07002425{
Ben Widawsky94ec8f62013-11-02 21:07:18 -07002426 writeq(pte, addr);
Ben Widawsky94ec8f62013-11-02 21:07:18 -07002427}
2428
Chris Wilsond6473f52016-06-10 14:22:59 +05302429static void gen8_ggtt_insert_page(struct i915_address_space *vm,
2430 dma_addr_t addr,
2431 uint64_t offset,
2432 enum i915_cache_level level,
2433 u32 unused)
2434{
Chris Wilson7c3f86b2017-01-12 11:00:49 +00002435 struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
Chris Wilsond6473f52016-06-10 14:22:59 +05302436 gen8_pte_t __iomem *pte =
Chris Wilson7c3f86b2017-01-12 11:00:49 +00002437 (gen8_pte_t __iomem *)ggtt->gsm + (offset >> PAGE_SHIFT);
Chris Wilsond6473f52016-06-10 14:22:59 +05302438
Michał Winiarski4fb84d92016-10-13 14:02:40 +02002439 gen8_set_pte(pte, gen8_pte_encode(addr, level));
Chris Wilsond6473f52016-06-10 14:22:59 +05302440
Chris Wilson7c3f86b2017-01-12 11:00:49 +00002441 ggtt->invalidate(vm->i915);
Chris Wilsond6473f52016-06-10 14:22:59 +05302442}
2443
Ben Widawsky94ec8f62013-11-02 21:07:18 -07002444static void gen8_ggtt_insert_entries(struct i915_address_space *vm,
2445 struct sg_table *st,
Ben Widawsky782f1492014-02-20 11:50:33 -08002446 uint64_t start,
Akash Goel24f3a8c2014-06-17 10:59:42 +05302447 enum i915_cache_level level, u32 unused)
Ben Widawsky94ec8f62013-11-02 21:07:18 -07002448{
Chris Wilsonce7fda22016-04-28 09:56:38 +01002449 struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
Dave Gordon85d12252016-05-20 11:54:06 +01002450 struct sgt_iter sgt_iter;
2451 gen8_pte_t __iomem *gtt_entries;
Chris Wilson894cceb2017-02-15 08:43:37 +00002452 const gen8_pte_t pte_encode = gen8_pte_encode(0, level);
Dave Gordon85d12252016-05-20 11:54:06 +01002453 dma_addr_t addr;
Imre Deakbe694592015-12-15 20:10:38 +02002454
Chris Wilson894cceb2017-02-15 08:43:37 +00002455 gtt_entries = (gen8_pte_t __iomem *)ggtt->gsm;
2456 gtt_entries += start >> PAGE_SHIFT;
2457 for_each_sgt_dma(addr, sgt_iter, st)
2458 gen8_set_pte(gtt_entries++, pte_encode | addr);
Dave Gordon85d12252016-05-20 11:54:06 +01002459
Chris Wilson894cceb2017-02-15 08:43:37 +00002460 wmb();
Ben Widawsky94ec8f62013-11-02 21:07:18 -07002461
Ben Widawsky94ec8f62013-11-02 21:07:18 -07002462 /* This next bit makes the above posting read even more important. We
2463 * want to flush the TLBs only after we're certain all the PTE updates
2464 * have finished.
2465 */
Chris Wilson7c3f86b2017-01-12 11:00:49 +00002466 ggtt->invalidate(vm->i915);
Ben Widawsky94ec8f62013-11-02 21:07:18 -07002467}
2468
Chris Wilsonc1403302015-11-18 15:19:39 +00002469struct insert_entries {
2470 struct i915_address_space *vm;
2471 struct sg_table *st;
2472 uint64_t start;
2473 enum i915_cache_level level;
2474 u32 flags;
2475};
2476
2477static int gen8_ggtt_insert_entries__cb(void *_arg)
2478{
2479 struct insert_entries *arg = _arg;
2480 gen8_ggtt_insert_entries(arg->vm, arg->st,
2481 arg->start, arg->level, arg->flags);
2482 return 0;
2483}
2484
2485static void gen8_ggtt_insert_entries__BKL(struct i915_address_space *vm,
2486 struct sg_table *st,
2487 uint64_t start,
2488 enum i915_cache_level level,
2489 u32 flags)
2490{
2491 struct insert_entries arg = { vm, st, start, level, flags };
2492 stop_machine(gen8_ggtt_insert_entries__cb, &arg, NULL);
2493}
2494
Chris Wilsond6473f52016-06-10 14:22:59 +05302495static void gen6_ggtt_insert_page(struct i915_address_space *vm,
2496 dma_addr_t addr,
2497 uint64_t offset,
2498 enum i915_cache_level level,
2499 u32 flags)
2500{
Chris Wilson7c3f86b2017-01-12 11:00:49 +00002501 struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
Chris Wilsond6473f52016-06-10 14:22:59 +05302502 gen6_pte_t __iomem *pte =
Chris Wilson7c3f86b2017-01-12 11:00:49 +00002503 (gen6_pte_t __iomem *)ggtt->gsm + (offset >> PAGE_SHIFT);
Chris Wilsond6473f52016-06-10 14:22:59 +05302504
Michał Winiarski4fb84d92016-10-13 14:02:40 +02002505 iowrite32(vm->pte_encode(addr, level, flags), pte);
Chris Wilsond6473f52016-06-10 14:22:59 +05302506
Chris Wilson7c3f86b2017-01-12 11:00:49 +00002507 ggtt->invalidate(vm->i915);
Chris Wilsond6473f52016-06-10 14:22:59 +05302508}
2509
Ben Widawskye76e9ae2012-11-04 09:21:27 -08002510/*
2511 * Binds an object into the global gtt with the specified cache level. The object
2512 * will be accessible to the GPU via commands whose operands reference offsets
2513 * within the global GTT as well as accessible by the GPU through the GMADR
2514 * mapped BAR (dev_priv->mm.gtt->gtt).
2515 */
Ben Widawsky853ba5d2013-07-16 16:50:05 -07002516static void gen6_ggtt_insert_entries(struct i915_address_space *vm,
Daniel Vetter7faf1ab2013-01-24 14:44:55 -08002517 struct sg_table *st,
Ben Widawsky782f1492014-02-20 11:50:33 -08002518 uint64_t start,
Akash Goel24f3a8c2014-06-17 10:59:42 +05302519 enum i915_cache_level level, u32 flags)
Ben Widawskye76e9ae2012-11-04 09:21:27 -08002520{
Chris Wilsonce7fda22016-04-28 09:56:38 +01002521 struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
Chris Wilsonb31144c2017-02-15 08:43:36 +00002522 gen6_pte_t __iomem *entries = (gen6_pte_t __iomem *)ggtt->gsm;
2523 unsigned int i = start >> PAGE_SHIFT;
2524 struct sgt_iter iter;
Dave Gordon85d12252016-05-20 11:54:06 +01002525 dma_addr_t addr;
Chris Wilsonb31144c2017-02-15 08:43:36 +00002526 for_each_sgt_dma(addr, iter, st)
2527 iowrite32(vm->pte_encode(addr, level, flags), &entries[i++]);
2528 wmb();
Ben Widawsky0f9b91c2012-11-04 09:21:30 -08002529
2530 /* This next bit makes the above posting read even more important. We
2531 * want to flush the TLBs only after we're certain all the PTE updates
2532 * have finished.
2533 */
Chris Wilson7c3f86b2017-01-12 11:00:49 +00002534 ggtt->invalidate(vm->i915);
Ben Widawskye76e9ae2012-11-04 09:21:27 -08002535}
2536
Chris Wilsonf7770bf2016-05-14 07:26:35 +01002537static void nop_clear_range(struct i915_address_space *vm,
Michał Winiarski4fb84d92016-10-13 14:02:40 +02002538 uint64_t start, uint64_t length)
Chris Wilsonf7770bf2016-05-14 07:26:35 +01002539{
2540}
2541
Ben Widawsky94ec8f62013-11-02 21:07:18 -07002542static void gen8_ggtt_clear_range(struct i915_address_space *vm,
Michał Winiarski4fb84d92016-10-13 14:02:40 +02002543 uint64_t start, uint64_t length)
Ben Widawsky94ec8f62013-11-02 21:07:18 -07002544{
Chris Wilsonce7fda22016-04-28 09:56:38 +01002545 struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
Ben Widawsky782f1492014-02-20 11:50:33 -08002546 unsigned first_entry = start >> PAGE_SHIFT;
2547 unsigned num_entries = length >> PAGE_SHIFT;
Chris Wilson894cceb2017-02-15 08:43:37 +00002548 const gen8_pte_t scratch_pte =
2549 gen8_pte_encode(vm->scratch_page.daddr, I915_CACHE_LLC);
2550 gen8_pte_t __iomem *gtt_base =
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03002551 (gen8_pte_t __iomem *)ggtt->gsm + first_entry;
2552 const int max_entries = ggtt_total_entries(ggtt) - first_entry;
Ben Widawsky94ec8f62013-11-02 21:07:18 -07002553 int i;
2554
2555 if (WARN(num_entries > max_entries,
2556 "First entry = %d; Num entries = %d (max=%d)\n",
2557 first_entry, num_entries, max_entries))
2558 num_entries = max_entries;
2559
Ben Widawsky94ec8f62013-11-02 21:07:18 -07002560 for (i = 0; i < num_entries; i++)
2561 gen8_set_pte(&gtt_base[i], scratch_pte);
2562 readl(gtt_base);
2563}
2564
Ben Widawsky853ba5d2013-07-16 16:50:05 -07002565static void gen6_ggtt_clear_range(struct i915_address_space *vm,
Ben Widawsky782f1492014-02-20 11:50:33 -08002566 uint64_t start,
Michał Winiarski4fb84d92016-10-13 14:02:40 +02002567 uint64_t length)
Daniel Vetter7faf1ab2013-01-24 14:44:55 -08002568{
Chris Wilsonce7fda22016-04-28 09:56:38 +01002569 struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
Ben Widawsky782f1492014-02-20 11:50:33 -08002570 unsigned first_entry = start >> PAGE_SHIFT;
2571 unsigned num_entries = length >> PAGE_SHIFT;
Michel Thierry07749ef2015-03-16 16:00:54 +00002572 gen6_pte_t scratch_pte, __iomem *gtt_base =
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03002573 (gen6_pte_t __iomem *)ggtt->gsm + first_entry;
2574 const int max_entries = ggtt_total_entries(ggtt) - first_entry;
Daniel Vetter7faf1ab2013-01-24 14:44:55 -08002575 int i;
2576
2577 if (WARN(num_entries > max_entries,
2578 "First entry = %d; Num entries = %d (max=%d)\n",
2579 first_entry, num_entries, max_entries))
2580 num_entries = max_entries;
2581
Chris Wilson8bcdd0f72016-08-22 08:44:30 +01002582 scratch_pte = vm->pte_encode(vm->scratch_page.daddr,
Michał Winiarski4fb84d92016-10-13 14:02:40 +02002583 I915_CACHE_LLC, 0);
Ben Widawsky828c7902013-10-16 09:21:30 -07002584
Daniel Vetter7faf1ab2013-01-24 14:44:55 -08002585 for (i = 0; i < num_entries; i++)
2586 iowrite32(scratch_pte, &gtt_base[i]);
2587 readl(gtt_base);
2588}
2589
Chris Wilsond6473f52016-06-10 14:22:59 +05302590static void i915_ggtt_insert_page(struct i915_address_space *vm,
2591 dma_addr_t addr,
2592 uint64_t offset,
2593 enum i915_cache_level cache_level,
2594 u32 unused)
2595{
Chris Wilsond6473f52016-06-10 14:22:59 +05302596 unsigned int flags = (cache_level == I915_CACHE_NONE) ?
2597 AGP_USER_MEMORY : AGP_USER_CACHED_MEMORY;
Chris Wilsond6473f52016-06-10 14:22:59 +05302598
2599 intel_gtt_insert_page(addr, offset >> PAGE_SHIFT, flags);
Chris Wilsond6473f52016-06-10 14:22:59 +05302600}
2601
Daniel Vetterd369d2d2015-04-14 17:35:25 +02002602static void i915_ggtt_insert_entries(struct i915_address_space *vm,
2603 struct sg_table *pages,
2604 uint64_t start,
2605 enum i915_cache_level cache_level, u32 unused)
Daniel Vetter7faf1ab2013-01-24 14:44:55 -08002606{
2607 unsigned int flags = (cache_level == I915_CACHE_NONE) ?
2608 AGP_USER_MEMORY : AGP_USER_CACHED_MEMORY;
2609
Daniel Vetterd369d2d2015-04-14 17:35:25 +02002610 intel_gtt_insert_sg_entries(pages, start >> PAGE_SHIFT, flags);
Daniel Vetter08755462015-04-20 09:04:05 -07002611
Daniel Vetter7faf1ab2013-01-24 14:44:55 -08002612}
2613
Ben Widawsky853ba5d2013-07-16 16:50:05 -07002614static void i915_ggtt_clear_range(struct i915_address_space *vm,
Ben Widawsky782f1492014-02-20 11:50:33 -08002615 uint64_t start,
Michał Winiarski4fb84d92016-10-13 14:02:40 +02002616 uint64_t length)
Daniel Vetter7faf1ab2013-01-24 14:44:55 -08002617{
Chris Wilson2eedfc72016-10-24 13:42:17 +01002618 intel_gtt_clear_range(start >> PAGE_SHIFT, length >> PAGE_SHIFT);
Daniel Vetter7faf1ab2013-01-24 14:44:55 -08002619}
2620
Daniel Vetter70b9f6f2015-04-14 17:35:27 +02002621static int ggtt_bind_vma(struct i915_vma *vma,
2622 enum i915_cache_level cache_level,
2623 u32 flags)
Daniel Vetter7c2e6fd2010-11-06 10:10:47 +01002624{
Chris Wilson49d73912016-11-29 09:50:08 +00002625 struct drm_i915_private *i915 = vma->vm->i915;
Daniel Vetter0a878712015-10-15 14:23:01 +02002626 struct drm_i915_gem_object *obj = vma->obj;
Chris Wilsonba7a5742017-02-15 08:43:35 +00002627 u32 pte_flags;
Daniel Vetter0a878712015-10-15 14:23:01 +02002628
Chris Wilsonba7a5742017-02-15 08:43:35 +00002629 if (unlikely(!vma->pages)) {
2630 int ret = i915_get_ggtt_vma_pages(vma);
2631 if (ret)
2632 return ret;
2633 }
Daniel Vetter0a878712015-10-15 14:23:01 +02002634
2635 /* Currently applicable only to VLV */
Chris Wilsonba7a5742017-02-15 08:43:35 +00002636 pte_flags = 0;
Daniel Vetter0a878712015-10-15 14:23:01 +02002637 if (obj->gt_ro)
2638 pte_flags |= PTE_READ_ONLY;
2639
Chris Wilson9c870d02016-10-24 13:42:15 +01002640 intel_runtime_pm_get(i915);
Chris Wilson247177d2016-08-15 10:48:47 +01002641 vma->vm->insert_entries(vma->vm, vma->pages, vma->node.start,
Daniel Vetter0a878712015-10-15 14:23:01 +02002642 cache_level, pte_flags);
Chris Wilson9c870d02016-10-24 13:42:15 +01002643 intel_runtime_pm_put(i915);
Daniel Vetter0a878712015-10-15 14:23:01 +02002644
2645 /*
2646 * Without aliasing PPGTT there's no difference between
2647 * GLOBAL/LOCAL_BIND, it's all the same ptes. Hence unconditionally
2648 * upgrade to both bound if we bind either to avoid double-binding.
2649 */
Chris Wilson3272db52016-08-04 16:32:32 +01002650 vma->flags |= I915_VMA_GLOBAL_BIND | I915_VMA_LOCAL_BIND;
Daniel Vetter0a878712015-10-15 14:23:01 +02002651
2652 return 0;
2653}
2654
Chris Wilsoncbc4e9e2017-02-15 08:43:39 +00002655static void ggtt_unbind_vma(struct i915_vma *vma)
2656{
2657 struct drm_i915_private *i915 = vma->vm->i915;
2658
2659 intel_runtime_pm_get(i915);
2660 vma->vm->clear_range(vma->vm, vma->node.start, vma->size);
2661 intel_runtime_pm_put(i915);
2662}
2663
Daniel Vetter0a878712015-10-15 14:23:01 +02002664static int aliasing_gtt_bind_vma(struct i915_vma *vma,
2665 enum i915_cache_level cache_level,
2666 u32 flags)
2667{
Chris Wilson49d73912016-11-29 09:50:08 +00002668 struct drm_i915_private *i915 = vma->vm->i915;
Chris Wilson321d1782015-11-20 10:27:18 +00002669 u32 pte_flags;
Daniel Vetter70b9f6f2015-04-14 17:35:27 +02002670
Chris Wilsonba7a5742017-02-15 08:43:35 +00002671 if (unlikely(!vma->pages)) {
2672 int ret = i915_get_ggtt_vma_pages(vma);
2673 if (ret)
2674 return ret;
2675 }
Daniel Vetter7faf1ab2013-01-24 14:44:55 -08002676
Akash Goel24f3a8c2014-06-17 10:59:42 +05302677 /* Currently applicable only to VLV */
Chris Wilson321d1782015-11-20 10:27:18 +00002678 pte_flags = 0;
2679 if (vma->obj->gt_ro)
Daniel Vetterf329f5f2015-04-14 17:35:15 +02002680 pte_flags |= PTE_READ_ONLY;
Akash Goel24f3a8c2014-06-17 10:59:42 +05302681
Chris Wilson3272db52016-08-04 16:32:32 +01002682 if (flags & I915_VMA_GLOBAL_BIND) {
Chris Wilson9c870d02016-10-24 13:42:15 +01002683 intel_runtime_pm_get(i915);
Chris Wilson321d1782015-11-20 10:27:18 +00002684 vma->vm->insert_entries(vma->vm,
Chris Wilson247177d2016-08-15 10:48:47 +01002685 vma->pages, vma->node.start,
Daniel Vetter08755462015-04-20 09:04:05 -07002686 cache_level, pte_flags);
Chris Wilson9c870d02016-10-24 13:42:15 +01002687 intel_runtime_pm_put(i915);
Ben Widawsky6f65e292013-12-06 14:10:56 -08002688 }
Daniel Vetter74898d72012-02-15 23:50:22 +01002689
Chris Wilson3272db52016-08-04 16:32:32 +01002690 if (flags & I915_VMA_LOCAL_BIND) {
Chris Wilson9c870d02016-10-24 13:42:15 +01002691 struct i915_hw_ppgtt *appgtt = i915->mm.aliasing_ppgtt;
Chris Wilson321d1782015-11-20 10:27:18 +00002692 appgtt->base.insert_entries(&appgtt->base,
Chris Wilson247177d2016-08-15 10:48:47 +01002693 vma->pages, vma->node.start,
Daniel Vetterf329f5f2015-04-14 17:35:15 +02002694 cache_level, pte_flags);
Ben Widawsky6f65e292013-12-06 14:10:56 -08002695 }
Daniel Vetter70b9f6f2015-04-14 17:35:27 +02002696
2697 return 0;
Ben Widawsky6f65e292013-12-06 14:10:56 -08002698}
2699
Chris Wilsoncbc4e9e2017-02-15 08:43:39 +00002700static void aliasing_gtt_unbind_vma(struct i915_vma *vma)
Ben Widawsky6f65e292013-12-06 14:10:56 -08002701{
Chris Wilson49d73912016-11-29 09:50:08 +00002702 struct drm_i915_private *i915 = vma->vm->i915;
Ben Widawsky6f65e292013-12-06 14:10:56 -08002703
Chris Wilson9c870d02016-10-24 13:42:15 +01002704 if (vma->flags & I915_VMA_GLOBAL_BIND) {
2705 intel_runtime_pm_get(i915);
Chris Wilsoncbc4e9e2017-02-15 08:43:39 +00002706 vma->vm->clear_range(vma->vm, vma->node.start, vma->size);
Chris Wilson9c870d02016-10-24 13:42:15 +01002707 intel_runtime_pm_put(i915);
2708 }
Ben Widawsky6f65e292013-12-06 14:10:56 -08002709
Chris Wilsoncbc4e9e2017-02-15 08:43:39 +00002710 if (vma->flags & I915_VMA_LOCAL_BIND) {
2711 struct i915_address_space *vm = &i915->mm.aliasing_ppgtt->base;
2712
2713 vm->clear_range(vm, vma->node.start, vma->size);
2714 }
Daniel Vetter74163902012-02-15 23:50:21 +01002715}
2716
Chris Wilson03ac84f2016-10-28 13:58:36 +01002717void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj,
2718 struct sg_table *pages)
Daniel Vetter74163902012-02-15 23:50:21 +01002719{
David Weinehall52a05c32016-08-22 13:32:44 +03002720 struct drm_i915_private *dev_priv = to_i915(obj->base.dev);
2721 struct device *kdev = &dev_priv->drm.pdev->dev;
Chris Wilson307dc252016-08-05 10:14:12 +01002722 struct i915_ggtt *ggtt = &dev_priv->ggtt;
Ben Widawsky5c042282011-10-17 15:51:55 -07002723
Chris Wilson307dc252016-08-05 10:14:12 +01002724 if (unlikely(ggtt->do_idle_maps)) {
Chris Wilson22dd3bb2016-09-09 14:11:50 +01002725 if (i915_gem_wait_for_idle(dev_priv, I915_WAIT_LOCKED)) {
Chris Wilson307dc252016-08-05 10:14:12 +01002726 DRM_ERROR("Failed to wait for idle; VT'd may hang.\n");
2727 /* Wait a bit, in hopes it avoids the hang */
2728 udelay(10);
2729 }
2730 }
Ben Widawsky5c042282011-10-17 15:51:55 -07002731
Chris Wilson03ac84f2016-10-28 13:58:36 +01002732 dma_unmap_sg(kdev, pages->sgl, pages->nents, PCI_DMA_BIDIRECTIONAL);
Daniel Vetter7c2e6fd2010-11-06 10:10:47 +01002733}
Daniel Vetter644ec022012-03-26 09:45:40 +02002734
Chris Wilson45b186f2016-12-16 07:46:42 +00002735static void i915_gtt_color_adjust(const struct drm_mm_node *node,
Chris Wilson42d6ab42012-07-26 11:49:32 +01002736 unsigned long color,
Thierry Reding440fd522015-01-23 09:05:06 +01002737 u64 *start,
2738 u64 *end)
Chris Wilson42d6ab42012-07-26 11:49:32 +01002739{
Chris Wilsona6508de2017-02-06 08:45:47 +00002740 if (node->allocated && node->color != color)
Chris Wilsonf51455d2017-01-10 14:47:34 +00002741 *start += I915_GTT_PAGE_SIZE;
Chris Wilson42d6ab42012-07-26 11:49:32 +01002742
Chris Wilsona6508de2017-02-06 08:45:47 +00002743 /* Also leave a space between the unallocated reserved node after the
2744 * GTT and any objects within the GTT, i.e. we use the color adjustment
2745 * to insert a guard page to prevent prefetches crossing over the
2746 * GTT boundary.
2747 */
Chris Wilsonb44f97f2016-12-16 07:46:40 +00002748 node = list_next_entry(node, node_list);
Chris Wilsona6508de2017-02-06 08:45:47 +00002749 if (node->color != color)
Chris Wilsonf51455d2017-01-10 14:47:34 +00002750 *end -= I915_GTT_PAGE_SIZE;
Chris Wilson42d6ab42012-07-26 11:49:32 +01002751}
Ben Widawskyfbe5d362013-11-04 19:56:49 -08002752
Chris Wilson6cde9a02017-02-13 17:15:50 +00002753int i915_gem_init_aliasing_ppgtt(struct drm_i915_private *i915)
2754{
2755 struct i915_ggtt *ggtt = &i915->ggtt;
2756 struct i915_hw_ppgtt *ppgtt;
2757 int err;
2758
Chris Wilson1188bc62017-02-15 08:43:38 +00002759 ppgtt = i915_ppgtt_create(i915, NULL, "[alias]");
2760 if (IS_ERR(ppgtt))
2761 return PTR_ERR(ppgtt);
Chris Wilson6cde9a02017-02-13 17:15:50 +00002762
2763 if (ppgtt->base.allocate_va_range) {
2764 err = ppgtt->base.allocate_va_range(&ppgtt->base,
2765 0, ppgtt->base.total);
2766 if (err)
Chris Wilson1188bc62017-02-15 08:43:38 +00002767 goto err_ppgtt;
Chris Wilson6cde9a02017-02-13 17:15:50 +00002768 }
2769
2770 ppgtt->base.clear_range(&ppgtt->base,
2771 ppgtt->base.start,
2772 ppgtt->base.total);
2773
2774 i915->mm.aliasing_ppgtt = ppgtt;
Chris Wilsoncbc4e9e2017-02-15 08:43:39 +00002775
Chris Wilson6cde9a02017-02-13 17:15:50 +00002776 WARN_ON(ggtt->base.bind_vma != ggtt_bind_vma);
2777 ggtt->base.bind_vma = aliasing_gtt_bind_vma;
2778
Chris Wilsoncbc4e9e2017-02-15 08:43:39 +00002779 WARN_ON(ggtt->base.unbind_vma != ggtt_unbind_vma);
2780 ggtt->base.unbind_vma = aliasing_gtt_unbind_vma;
2781
Chris Wilson6cde9a02017-02-13 17:15:50 +00002782 return 0;
2783
Chris Wilson6cde9a02017-02-13 17:15:50 +00002784err_ppgtt:
Chris Wilson1188bc62017-02-15 08:43:38 +00002785 i915_ppgtt_put(ppgtt);
Chris Wilson6cde9a02017-02-13 17:15:50 +00002786 return err;
2787}
2788
2789void i915_gem_fini_aliasing_ppgtt(struct drm_i915_private *i915)
2790{
2791 struct i915_ggtt *ggtt = &i915->ggtt;
2792 struct i915_hw_ppgtt *ppgtt;
2793
2794 ppgtt = fetch_and_zero(&i915->mm.aliasing_ppgtt);
2795 if (!ppgtt)
2796 return;
2797
Chris Wilson1188bc62017-02-15 08:43:38 +00002798 i915_ppgtt_put(ppgtt);
Chris Wilson6cde9a02017-02-13 17:15:50 +00002799
2800 ggtt->base.bind_vma = ggtt_bind_vma;
Chris Wilsoncbc4e9e2017-02-15 08:43:39 +00002801 ggtt->base.unbind_vma = ggtt_unbind_vma;
Chris Wilson6cde9a02017-02-13 17:15:50 +00002802}
2803
Chris Wilsonf6b9d5c2016-08-04 07:52:23 +01002804int i915_gem_init_ggtt(struct drm_i915_private *dev_priv)
Daniel Vetter644ec022012-03-26 09:45:40 +02002805{
Ben Widawskye78891c2013-01-25 16:41:04 -08002806 /* Let GEM Manage all of the aperture.
2807 *
2808 * However, leave one page at the end still bound to the scratch page.
2809 * There are a number of places where the hardware apparently prefetches
2810 * past the end of the object, and we've seen multiple hangs with the
2811 * GPU head pointer stuck in a batchbuffer bound at the last page of the
2812 * aperture. One page should be enough to keep any prefetching inside
2813 * of the aperture.
2814 */
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03002815 struct i915_ggtt *ggtt = &dev_priv->ggtt;
Chris Wilsoned2f3452012-11-15 11:32:19 +00002816 unsigned long hole_start, hole_end;
Chris Wilsonf6b9d5c2016-08-04 07:52:23 +01002817 struct drm_mm_node *entry;
Daniel Vetterfa76da32014-08-06 20:19:54 +02002818 int ret;
Daniel Vetter644ec022012-03-26 09:45:40 +02002819
Zhi Wangb02d22a2016-06-16 08:06:59 -04002820 ret = intel_vgt_balloon(dev_priv);
2821 if (ret)
2822 return ret;
Yu Zhang5dda8fa2015-02-10 19:05:48 +08002823
Chris Wilson95374d72016-10-12 10:05:20 +01002824 /* Reserve a mappable slot for our lockless error capture */
Chris Wilson4e64e552017-02-02 21:04:38 +00002825 ret = drm_mm_insert_node_in_range(&ggtt->base.mm, &ggtt->error_capture,
2826 PAGE_SIZE, 0, I915_COLOR_UNEVICTABLE,
2827 0, ggtt->mappable_end,
2828 DRM_MM_INSERT_LOW);
Chris Wilson95374d72016-10-12 10:05:20 +01002829 if (ret)
2830 return ret;
2831
Chris Wilsoned2f3452012-11-15 11:32:19 +00002832 /* Clear any non-preallocated blocks */
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03002833 drm_mm_for_each_hole(entry, &ggtt->base.mm, hole_start, hole_end) {
Chris Wilsoned2f3452012-11-15 11:32:19 +00002834 DRM_DEBUG_KMS("clearing unused GTT space: [%lx, %lx]\n",
2835 hole_start, hole_end);
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03002836 ggtt->base.clear_range(&ggtt->base, hole_start,
Michał Winiarski4fb84d92016-10-13 14:02:40 +02002837 hole_end - hole_start);
Chris Wilsoned2f3452012-11-15 11:32:19 +00002838 }
2839
2840 /* And finally clear the reserved guard page */
Chris Wilsonf6b9d5c2016-08-04 07:52:23 +01002841 ggtt->base.clear_range(&ggtt->base,
Michał Winiarski4fb84d92016-10-13 14:02:40 +02002842 ggtt->base.total - PAGE_SIZE, PAGE_SIZE);
Daniel Vetter6c5566a2014-08-06 15:04:50 +02002843
Chris Wilson97d6d7a2016-08-04 07:52:22 +01002844 if (USES_PPGTT(dev_priv) && !USES_FULL_PPGTT(dev_priv)) {
Chris Wilson6cde9a02017-02-13 17:15:50 +00002845 ret = i915_gem_init_aliasing_ppgtt(dev_priv);
Chris Wilson95374d72016-10-12 10:05:20 +01002846 if (ret)
Chris Wilson6cde9a02017-02-13 17:15:50 +00002847 goto err;
Daniel Vetterfa76da32014-08-06 20:19:54 +02002848 }
2849
Daniel Vetter6c5566a2014-08-06 15:04:50 +02002850 return 0;
Chris Wilson95374d72016-10-12 10:05:20 +01002851
Chris Wilson95374d72016-10-12 10:05:20 +01002852err:
2853 drm_mm_remove_node(&ggtt->error_capture);
2854 return ret;
Ben Widawskye76e9ae2012-11-04 09:21:27 -08002855}
2856
Joonas Lahtinend85489d2016-03-24 16:47:46 +02002857/**
Joonas Lahtinend85489d2016-03-24 16:47:46 +02002858 * i915_ggtt_cleanup_hw - Clean up GGTT hardware initialization
Chris Wilson97d6d7a2016-08-04 07:52:22 +01002859 * @dev_priv: i915 device
Joonas Lahtinend85489d2016-03-24 16:47:46 +02002860 */
Chris Wilson97d6d7a2016-08-04 07:52:22 +01002861void i915_ggtt_cleanup_hw(struct drm_i915_private *dev_priv)
Daniel Vetter90d0a0e2014-08-06 15:04:56 +02002862{
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03002863 struct i915_ggtt *ggtt = &dev_priv->ggtt;
Chris Wilson94d4a2a2017-02-10 16:35:22 +00002864 struct i915_vma *vma, *vn;
2865
2866 ggtt->base.closed = true;
2867
2868 mutex_lock(&dev_priv->drm.struct_mutex);
2869 WARN_ON(!list_empty(&ggtt->base.active_list));
2870 list_for_each_entry_safe(vma, vn, &ggtt->base.inactive_list, vm_link)
2871 WARN_ON(i915_vma_unbind(vma));
2872 mutex_unlock(&dev_priv->drm.struct_mutex);
Daniel Vetter90d0a0e2014-08-06 15:04:56 +02002873
Chris Wilson97d6d7a2016-08-04 07:52:22 +01002874 i915_gem_cleanup_stolen(&dev_priv->drm);
Imre Deaka4eba472016-01-19 15:26:32 +02002875
Chris Wilson1188bc62017-02-15 08:43:38 +00002876 mutex_lock(&dev_priv->drm.struct_mutex);
2877 i915_gem_fini_aliasing_ppgtt(dev_priv);
2878
Chris Wilson95374d72016-10-12 10:05:20 +01002879 if (drm_mm_node_allocated(&ggtt->error_capture))
2880 drm_mm_remove_node(&ggtt->error_capture);
2881
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03002882 if (drm_mm_initialized(&ggtt->base.mm)) {
Zhi Wangb02d22a2016-06-16 08:06:59 -04002883 intel_vgt_deballoon(dev_priv);
Matthew Aulded9724d2016-11-17 21:04:10 +00002884 i915_address_space_fini(&ggtt->base);
Daniel Vetter90d0a0e2014-08-06 15:04:56 +02002885 }
2886
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03002887 ggtt->base.cleanup(&ggtt->base);
Chris Wilson1188bc62017-02-15 08:43:38 +00002888 mutex_unlock(&dev_priv->drm.struct_mutex);
Chris Wilsonf6b9d5c2016-08-04 07:52:23 +01002889
2890 arch_phys_wc_del(ggtt->mtrr);
Chris Wilsonf7bbe782016-08-19 16:54:27 +01002891 io_mapping_fini(&ggtt->mappable);
Daniel Vetter90d0a0e2014-08-06 15:04:56 +02002892}
Daniel Vetter70e32542014-08-06 15:04:57 +02002893
Daniel Vetter2c642b02015-04-14 17:35:26 +02002894static unsigned int gen6_get_total_gtt_size(u16 snb_gmch_ctl)
Ben Widawskye76e9ae2012-11-04 09:21:27 -08002895{
2896 snb_gmch_ctl >>= SNB_GMCH_GGMS_SHIFT;
2897 snb_gmch_ctl &= SNB_GMCH_GGMS_MASK;
2898 return snb_gmch_ctl << 20;
2899}
2900
Daniel Vetter2c642b02015-04-14 17:35:26 +02002901static unsigned int gen8_get_total_gtt_size(u16 bdw_gmch_ctl)
Ben Widawsky9459d252013-11-03 16:53:55 -08002902{
2903 bdw_gmch_ctl >>= BDW_GMCH_GGMS_SHIFT;
2904 bdw_gmch_ctl &= BDW_GMCH_GGMS_MASK;
2905 if (bdw_gmch_ctl)
2906 bdw_gmch_ctl = 1 << bdw_gmch_ctl;
Ben Widawsky562d55d2014-05-27 16:53:08 -07002907
2908#ifdef CONFIG_X86_32
2909 /* Limit 32b platforms to a 2GB GGTT: 4 << 20 / pte size * PAGE_SIZE */
2910 if (bdw_gmch_ctl > 4)
2911 bdw_gmch_ctl = 4;
2912#endif
2913
Ben Widawsky9459d252013-11-03 16:53:55 -08002914 return bdw_gmch_ctl << 20;
2915}
2916
Daniel Vetter2c642b02015-04-14 17:35:26 +02002917static unsigned int chv_get_total_gtt_size(u16 gmch_ctrl)
Damien Lespiaud7f25f22014-05-08 22:19:40 +03002918{
2919 gmch_ctrl >>= SNB_GMCH_GGMS_SHIFT;
2920 gmch_ctrl &= SNB_GMCH_GGMS_MASK;
2921
2922 if (gmch_ctrl)
2923 return 1 << (20 + gmch_ctrl);
2924
2925 return 0;
2926}
2927
Daniel Vetter2c642b02015-04-14 17:35:26 +02002928static size_t gen6_get_stolen_size(u16 snb_gmch_ctl)
Ben Widawskye76e9ae2012-11-04 09:21:27 -08002929{
2930 snb_gmch_ctl >>= SNB_GMCH_GMS_SHIFT;
2931 snb_gmch_ctl &= SNB_GMCH_GMS_MASK;
2932 return snb_gmch_ctl << 25; /* 32 MB units */
2933}
2934
Daniel Vetter2c642b02015-04-14 17:35:26 +02002935static size_t gen8_get_stolen_size(u16 bdw_gmch_ctl)
Ben Widawsky9459d252013-11-03 16:53:55 -08002936{
2937 bdw_gmch_ctl >>= BDW_GMCH_GMS_SHIFT;
2938 bdw_gmch_ctl &= BDW_GMCH_GMS_MASK;
2939 return bdw_gmch_ctl << 25; /* 32 MB units */
2940}
2941
Damien Lespiaud7f25f22014-05-08 22:19:40 +03002942static size_t chv_get_stolen_size(u16 gmch_ctrl)
2943{
2944 gmch_ctrl >>= SNB_GMCH_GMS_SHIFT;
2945 gmch_ctrl &= SNB_GMCH_GMS_MASK;
2946
2947 /*
2948 * 0x0 to 0x10: 32MB increments starting at 0MB
2949 * 0x11 to 0x16: 4MB increments starting at 8MB
2950 * 0x17 to 0x1d: 4MB increments start at 36MB
2951 */
2952 if (gmch_ctrl < 0x11)
2953 return gmch_ctrl << 25;
2954 else if (gmch_ctrl < 0x17)
2955 return (gmch_ctrl - 0x11 + 2) << 22;
2956 else
2957 return (gmch_ctrl - 0x17 + 9) << 22;
2958}
2959
Damien Lespiau66375012014-01-09 18:02:46 +00002960static size_t gen9_get_stolen_size(u16 gen9_gmch_ctl)
2961{
2962 gen9_gmch_ctl >>= BDW_GMCH_GMS_SHIFT;
2963 gen9_gmch_ctl &= BDW_GMCH_GMS_MASK;
2964
2965 if (gen9_gmch_ctl < 0xf0)
2966 return gen9_gmch_ctl << 25; /* 32 MB units */
2967 else
2968 /* 4MB increments starting at 0xf0 for 4MB */
2969 return (gen9_gmch_ctl - 0xf0 + 1) << 22;
2970}
2971
Chris Wilson34c998b2016-08-04 07:52:24 +01002972static int ggtt_probe_common(struct i915_ggtt *ggtt, u64 size)
Ben Widawsky63340132013-11-04 19:32:22 -08002973{
Chris Wilson49d73912016-11-29 09:50:08 +00002974 struct drm_i915_private *dev_priv = ggtt->base.i915;
2975 struct pci_dev *pdev = dev_priv->drm.pdev;
Chris Wilson34c998b2016-08-04 07:52:24 +01002976 phys_addr_t phys_addr;
Chris Wilson8bcdd0f72016-08-22 08:44:30 +01002977 int ret;
Ben Widawsky63340132013-11-04 19:32:22 -08002978
2979 /* For Modern GENs the PTEs and register space are split in the BAR */
Chris Wilson34c998b2016-08-04 07:52:24 +01002980 phys_addr = pci_resource_start(pdev, 0) + pci_resource_len(pdev, 0) / 2;
Ben Widawsky63340132013-11-04 19:32:22 -08002981
Imre Deak2a073f892015-03-27 13:07:33 +02002982 /*
2983 * On BXT writes larger than 64 bit to the GTT pagetable range will be
2984 * dropped. For WC mappings in general we have 64 byte burst writes
2985 * when the WC buffer is flushed, so we can't use it, but have to
2986 * resort to an uncached mapping. The WC issue is easily caught by the
2987 * readback check when writing GTT PTE entries.
2988 */
Ander Conselvan de Oliveiracc3f90f2016-12-02 10:23:49 +02002989 if (IS_GEN9_LP(dev_priv))
Chris Wilson34c998b2016-08-04 07:52:24 +01002990 ggtt->gsm = ioremap_nocache(phys_addr, size);
Imre Deak2a073f892015-03-27 13:07:33 +02002991 else
Chris Wilson34c998b2016-08-04 07:52:24 +01002992 ggtt->gsm = ioremap_wc(phys_addr, size);
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03002993 if (!ggtt->gsm) {
Chris Wilson34c998b2016-08-04 07:52:24 +01002994 DRM_ERROR("Failed to map the ggtt page table\n");
Ben Widawsky63340132013-11-04 19:32:22 -08002995 return -ENOMEM;
2996 }
2997
Chris Wilson84486612017-02-15 08:43:40 +00002998 ret = setup_scratch_page(&ggtt->base, GFP_DMA32);
Chris Wilson8bcdd0f72016-08-22 08:44:30 +01002999 if (ret) {
Ben Widawsky63340132013-11-04 19:32:22 -08003000 DRM_ERROR("Scratch setup failed\n");
3001 /* iounmap will also get called at remove, but meh */
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03003002 iounmap(ggtt->gsm);
Chris Wilson8bcdd0f72016-08-22 08:44:30 +01003003 return ret;
Ben Widawsky63340132013-11-04 19:32:22 -08003004 }
3005
Mika Kuoppala4ad2af12015-06-30 18:16:39 +03003006 return 0;
Ben Widawsky63340132013-11-04 19:32:22 -08003007}
3008
Ben Widawskyfbe5d362013-11-04 19:56:49 -08003009/* The GGTT and PPGTT need a private PPAT setup in order to handle cacheability
3010 * bits. When using advanced contexts each context stores its own PAT, but
3011 * writing this data shouldn't be harmful even in those cases. */
Ville Syrjäläee0ce472014-04-09 13:28:01 +03003012static void bdw_setup_private_ppat(struct drm_i915_private *dev_priv)
Ben Widawskyfbe5d362013-11-04 19:56:49 -08003013{
Ben Widawskyfbe5d362013-11-04 19:56:49 -08003014 uint64_t pat;
3015
3016 pat = GEN8_PPAT(0, GEN8_PPAT_WB | GEN8_PPAT_LLC) | /* for normal objects, no eLLC */
3017 GEN8_PPAT(1, GEN8_PPAT_WC | GEN8_PPAT_LLCELLC) | /* for something pointing to ptes? */
3018 GEN8_PPAT(2, GEN8_PPAT_WT | GEN8_PPAT_LLCELLC) | /* for scanout with eLLC */
3019 GEN8_PPAT(3, GEN8_PPAT_UC) | /* Uncached objects, mostly for scanout */
3020 GEN8_PPAT(4, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(0)) |
3021 GEN8_PPAT(5, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(1)) |
3022 GEN8_PPAT(6, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(2)) |
3023 GEN8_PPAT(7, GEN8_PPAT_WB | GEN8_PPAT_LLCELLC | GEN8_PPAT_AGE(3));
3024
Joonas Lahtinen2d1fe072016-04-07 11:08:05 +03003025 if (!USES_PPGTT(dev_priv))
Rodrigo Vivid6a8b722014-11-05 16:56:36 -08003026 /* Spec: "For GGTT, there is NO pat_sel[2:0] from the entry,
3027 * so RTL will always use the value corresponding to
3028 * pat_sel = 000".
3029 * So let's disable cache for GGTT to avoid screen corruptions.
3030 * MOCS still can be used though.
3031 * - System agent ggtt writes (i.e. cpu gtt mmaps) already work
3032 * before this patch, i.e. the same uncached + snooping access
3033 * like on gen6/7 seems to be in effect.
3034 * - So this just fixes blitter/render access. Again it looks
3035 * like it's not just uncached access, but uncached + snooping.
3036 * So we can still hold onto all our assumptions wrt cpu
3037 * clflushing on LLC machines.
3038 */
3039 pat = GEN8_PPAT(0, GEN8_PPAT_UC);
3040
Ben Widawskyfbe5d362013-11-04 19:56:49 -08003041 /* XXX: spec defines this as 2 distinct registers. It's unclear if a 64b
3042 * write would work. */
Ville Syrjälä7e435ad2015-09-18 20:03:25 +03003043 I915_WRITE(GEN8_PRIVATE_PAT_LO, pat);
3044 I915_WRITE(GEN8_PRIVATE_PAT_HI, pat >> 32);
Ben Widawskyfbe5d362013-11-04 19:56:49 -08003045}
3046
Ville Syrjäläee0ce472014-04-09 13:28:01 +03003047static void chv_setup_private_ppat(struct drm_i915_private *dev_priv)
3048{
3049 uint64_t pat;
3050
3051 /*
3052 * Map WB on BDW to snooped on CHV.
3053 *
3054 * Only the snoop bit has meaning for CHV, the rest is
3055 * ignored.
3056 *
Ville Syrjäläcf3d2622014-11-14 21:02:44 +02003057 * The hardware will never snoop for certain types of accesses:
3058 * - CPU GTT (GMADR->GGTT->no snoop->memory)
3059 * - PPGTT page tables
3060 * - some other special cycles
3061 *
3062 * As with BDW, we also need to consider the following for GT accesses:
3063 * "For GGTT, there is NO pat_sel[2:0] from the entry,
3064 * so RTL will always use the value corresponding to
3065 * pat_sel = 000".
3066 * Which means we must set the snoop bit in PAT entry 0
3067 * in order to keep the global status page working.
Ville Syrjäläee0ce472014-04-09 13:28:01 +03003068 */
3069 pat = GEN8_PPAT(0, CHV_PPAT_SNOOP) |
3070 GEN8_PPAT(1, 0) |
3071 GEN8_PPAT(2, 0) |
3072 GEN8_PPAT(3, 0) |
3073 GEN8_PPAT(4, CHV_PPAT_SNOOP) |
3074 GEN8_PPAT(5, CHV_PPAT_SNOOP) |
3075 GEN8_PPAT(6, CHV_PPAT_SNOOP) |
3076 GEN8_PPAT(7, CHV_PPAT_SNOOP);
3077
Ville Syrjälä7e435ad2015-09-18 20:03:25 +03003078 I915_WRITE(GEN8_PRIVATE_PAT_LO, pat);
3079 I915_WRITE(GEN8_PRIVATE_PAT_HI, pat >> 32);
Ville Syrjäläee0ce472014-04-09 13:28:01 +03003080}
3081
Chris Wilson34c998b2016-08-04 07:52:24 +01003082static void gen6_gmch_remove(struct i915_address_space *vm)
3083{
3084 struct i915_ggtt *ggtt = i915_vm_to_ggtt(vm);
3085
3086 iounmap(ggtt->gsm);
Chris Wilson84486612017-02-15 08:43:40 +00003087 cleanup_scratch_page(vm);
Chris Wilson34c998b2016-08-04 07:52:24 +01003088}
3089
Joonas Lahtinend507d732016-03-18 10:42:58 +02003090static int gen8_gmch_probe(struct i915_ggtt *ggtt)
Ben Widawsky63340132013-11-04 19:32:22 -08003091{
Chris Wilson49d73912016-11-29 09:50:08 +00003092 struct drm_i915_private *dev_priv = ggtt->base.i915;
Chris Wilson97d6d7a2016-08-04 07:52:22 +01003093 struct pci_dev *pdev = dev_priv->drm.pdev;
Chris Wilson34c998b2016-08-04 07:52:24 +01003094 unsigned int size;
Ben Widawsky63340132013-11-04 19:32:22 -08003095 u16 snb_gmch_ctl;
Ben Widawsky63340132013-11-04 19:32:22 -08003096
3097 /* TODO: We're not aware of mappable constraints on gen8 yet */
Chris Wilson97d6d7a2016-08-04 07:52:22 +01003098 ggtt->mappable_base = pci_resource_start(pdev, 2);
3099 ggtt->mappable_end = pci_resource_len(pdev, 2);
Ben Widawsky63340132013-11-04 19:32:22 -08003100
Chris Wilson97d6d7a2016-08-04 07:52:22 +01003101 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(39)))
3102 pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(39));
Ben Widawsky63340132013-11-04 19:32:22 -08003103
Chris Wilson97d6d7a2016-08-04 07:52:22 +01003104 pci_read_config_word(pdev, SNB_GMCH_CTRL, &snb_gmch_ctl);
Ben Widawsky63340132013-11-04 19:32:22 -08003105
Chris Wilson97d6d7a2016-08-04 07:52:22 +01003106 if (INTEL_GEN(dev_priv) >= 9) {
Joonas Lahtinend507d732016-03-18 10:42:58 +02003107 ggtt->stolen_size = gen9_get_stolen_size(snb_gmch_ctl);
Chris Wilson34c998b2016-08-04 07:52:24 +01003108 size = gen8_get_total_gtt_size(snb_gmch_ctl);
Chris Wilson97d6d7a2016-08-04 07:52:22 +01003109 } else if (IS_CHERRYVIEW(dev_priv)) {
Joonas Lahtinend507d732016-03-18 10:42:58 +02003110 ggtt->stolen_size = chv_get_stolen_size(snb_gmch_ctl);
Chris Wilson34c998b2016-08-04 07:52:24 +01003111 size = chv_get_total_gtt_size(snb_gmch_ctl);
Damien Lespiaud7f25f22014-05-08 22:19:40 +03003112 } else {
Joonas Lahtinend507d732016-03-18 10:42:58 +02003113 ggtt->stolen_size = gen8_get_stolen_size(snb_gmch_ctl);
Chris Wilson34c998b2016-08-04 07:52:24 +01003114 size = gen8_get_total_gtt_size(snb_gmch_ctl);
Damien Lespiaud7f25f22014-05-08 22:19:40 +03003115 }
Ben Widawsky63340132013-11-04 19:32:22 -08003116
Chris Wilson34c998b2016-08-04 07:52:24 +01003117 ggtt->base.total = (size / sizeof(gen8_pte_t)) << PAGE_SHIFT;
Ben Widawsky63340132013-11-04 19:32:22 -08003118
Ander Conselvan de Oliveiracc3f90f2016-12-02 10:23:49 +02003119 if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv))
Ville Syrjäläee0ce472014-04-09 13:28:01 +03003120 chv_setup_private_ppat(dev_priv);
3121 else
3122 bdw_setup_private_ppat(dev_priv);
Ben Widawskyfbe5d362013-11-04 19:56:49 -08003123
Chris Wilson34c998b2016-08-04 07:52:24 +01003124 ggtt->base.cleanup = gen6_gmch_remove;
Joonas Lahtinend507d732016-03-18 10:42:58 +02003125 ggtt->base.bind_vma = ggtt_bind_vma;
3126 ggtt->base.unbind_vma = ggtt_unbind_vma;
Chris Wilsond6473f52016-06-10 14:22:59 +05303127 ggtt->base.insert_page = gen8_ggtt_insert_page;
Chris Wilsonf7770bf2016-05-14 07:26:35 +01003128 ggtt->base.clear_range = nop_clear_range;
Chris Wilson48f112f2016-06-24 14:07:14 +01003129 if (!USES_FULL_PPGTT(dev_priv) || intel_scanout_needs_vtd_wa(dev_priv))
Chris Wilsonf7770bf2016-05-14 07:26:35 +01003130 ggtt->base.clear_range = gen8_ggtt_clear_range;
3131
3132 ggtt->base.insert_entries = gen8_ggtt_insert_entries;
3133 if (IS_CHERRYVIEW(dev_priv))
3134 ggtt->base.insert_entries = gen8_ggtt_insert_entries__BKL;
3135
Chris Wilson7c3f86b2017-01-12 11:00:49 +00003136 ggtt->invalidate = gen6_ggtt_invalidate;
3137
Chris Wilson34c998b2016-08-04 07:52:24 +01003138 return ggtt_probe_common(ggtt, size);
Ben Widawsky63340132013-11-04 19:32:22 -08003139}
3140
Joonas Lahtinend507d732016-03-18 10:42:58 +02003141static int gen6_gmch_probe(struct i915_ggtt *ggtt)
Ben Widawskye76e9ae2012-11-04 09:21:27 -08003142{
Chris Wilson49d73912016-11-29 09:50:08 +00003143 struct drm_i915_private *dev_priv = ggtt->base.i915;
Chris Wilson97d6d7a2016-08-04 07:52:22 +01003144 struct pci_dev *pdev = dev_priv->drm.pdev;
Chris Wilson34c998b2016-08-04 07:52:24 +01003145 unsigned int size;
Ben Widawskye76e9ae2012-11-04 09:21:27 -08003146 u16 snb_gmch_ctl;
Ben Widawskye76e9ae2012-11-04 09:21:27 -08003147
Chris Wilson97d6d7a2016-08-04 07:52:22 +01003148 ggtt->mappable_base = pci_resource_start(pdev, 2);
3149 ggtt->mappable_end = pci_resource_len(pdev, 2);
Ben Widawsky41907dd2013-02-08 11:32:47 -08003150
Ben Widawskybaa09f52013-01-24 13:49:57 -08003151 /* 64/512MB is the current min/max we actually know of, but this is just
3152 * a coarse sanity check.
Ben Widawskye76e9ae2012-11-04 09:21:27 -08003153 */
Chris Wilson34c998b2016-08-04 07:52:24 +01003154 if (ggtt->mappable_end < (64<<20) || ggtt->mappable_end > (512<<20)) {
Joonas Lahtinend507d732016-03-18 10:42:58 +02003155 DRM_ERROR("Unknown GMADR size (%llx)\n", ggtt->mappable_end);
Ben Widawskybaa09f52013-01-24 13:49:57 -08003156 return -ENXIO;
Ben Widawskye76e9ae2012-11-04 09:21:27 -08003157 }
3158
Chris Wilson97d6d7a2016-08-04 07:52:22 +01003159 if (!pci_set_dma_mask(pdev, DMA_BIT_MASK(40)))
3160 pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(40));
3161 pci_read_config_word(pdev, SNB_GMCH_CTRL, &snb_gmch_ctl);
Ben Widawskybaa09f52013-01-24 13:49:57 -08003162
Joonas Lahtinend507d732016-03-18 10:42:58 +02003163 ggtt->stolen_size = gen6_get_stolen_size(snb_gmch_ctl);
Ben Widawskybaa09f52013-01-24 13:49:57 -08003164
Chris Wilson34c998b2016-08-04 07:52:24 +01003165 size = gen6_get_total_gtt_size(snb_gmch_ctl);
3166 ggtt->base.total = (size / sizeof(gen6_pte_t)) << PAGE_SHIFT;
Ben Widawskybaa09f52013-01-24 13:49:57 -08003167
Joonas Lahtinend507d732016-03-18 10:42:58 +02003168 ggtt->base.clear_range = gen6_ggtt_clear_range;
Chris Wilsond6473f52016-06-10 14:22:59 +05303169 ggtt->base.insert_page = gen6_ggtt_insert_page;
Joonas Lahtinend507d732016-03-18 10:42:58 +02003170 ggtt->base.insert_entries = gen6_ggtt_insert_entries;
3171 ggtt->base.bind_vma = ggtt_bind_vma;
3172 ggtt->base.unbind_vma = ggtt_unbind_vma;
Chris Wilson34c998b2016-08-04 07:52:24 +01003173 ggtt->base.cleanup = gen6_gmch_remove;
Ben Widawskybaa09f52013-01-24 13:49:57 -08003174
Chris Wilson7c3f86b2017-01-12 11:00:49 +00003175 ggtt->invalidate = gen6_ggtt_invalidate;
3176
Chris Wilson34c998b2016-08-04 07:52:24 +01003177 if (HAS_EDRAM(dev_priv))
3178 ggtt->base.pte_encode = iris_pte_encode;
3179 else if (IS_HASWELL(dev_priv))
3180 ggtt->base.pte_encode = hsw_pte_encode;
3181 else if (IS_VALLEYVIEW(dev_priv))
3182 ggtt->base.pte_encode = byt_pte_encode;
3183 else if (INTEL_GEN(dev_priv) >= 7)
3184 ggtt->base.pte_encode = ivb_pte_encode;
3185 else
3186 ggtt->base.pte_encode = snb_pte_encode;
3187
3188 return ggtt_probe_common(ggtt, size);
Ben Widawskybaa09f52013-01-24 13:49:57 -08003189}
3190
Chris Wilson34c998b2016-08-04 07:52:24 +01003191static void i915_gmch_remove(struct i915_address_space *vm)
Ben Widawskybaa09f52013-01-24 13:49:57 -08003192{
Chris Wilson34c998b2016-08-04 07:52:24 +01003193 intel_gmch_remove();
Ben Widawskybaa09f52013-01-24 13:49:57 -08003194}
3195
Joonas Lahtinend507d732016-03-18 10:42:58 +02003196static int i915_gmch_probe(struct i915_ggtt *ggtt)
Ben Widawskybaa09f52013-01-24 13:49:57 -08003197{
Chris Wilson49d73912016-11-29 09:50:08 +00003198 struct drm_i915_private *dev_priv = ggtt->base.i915;
Ben Widawskybaa09f52013-01-24 13:49:57 -08003199 int ret;
3200
Chris Wilson91c8a322016-07-05 10:40:23 +01003201 ret = intel_gmch_probe(dev_priv->bridge_dev, dev_priv->drm.pdev, NULL);
Ben Widawskybaa09f52013-01-24 13:49:57 -08003202 if (!ret) {
3203 DRM_ERROR("failed to set up gmch\n");
3204 return -EIO;
3205 }
3206
Chris Wilsonedd1f2f2017-01-06 15:20:11 +00003207 intel_gtt_get(&ggtt->base.total,
3208 &ggtt->stolen_size,
3209 &ggtt->mappable_base,
3210 &ggtt->mappable_end);
Ben Widawskybaa09f52013-01-24 13:49:57 -08003211
Chris Wilson97d6d7a2016-08-04 07:52:22 +01003212 ggtt->do_idle_maps = needs_idle_maps(dev_priv);
Chris Wilsond6473f52016-06-10 14:22:59 +05303213 ggtt->base.insert_page = i915_ggtt_insert_page;
Joonas Lahtinend507d732016-03-18 10:42:58 +02003214 ggtt->base.insert_entries = i915_ggtt_insert_entries;
3215 ggtt->base.clear_range = i915_ggtt_clear_range;
3216 ggtt->base.bind_vma = ggtt_bind_vma;
3217 ggtt->base.unbind_vma = ggtt_unbind_vma;
Chris Wilson34c998b2016-08-04 07:52:24 +01003218 ggtt->base.cleanup = i915_gmch_remove;
Ben Widawskybaa09f52013-01-24 13:49:57 -08003219
Chris Wilson7c3f86b2017-01-12 11:00:49 +00003220 ggtt->invalidate = gmch_ggtt_invalidate;
3221
Joonas Lahtinend507d732016-03-18 10:42:58 +02003222 if (unlikely(ggtt->do_idle_maps))
Chris Wilsonc0a7f812013-12-30 12:16:15 +00003223 DRM_INFO("applying Ironlake quirks for intel_iommu\n");
3224
Ben Widawskybaa09f52013-01-24 13:49:57 -08003225 return 0;
3226}
3227
Joonas Lahtinend85489d2016-03-24 16:47:46 +02003228/**
Chris Wilson0088e522016-08-04 07:52:21 +01003229 * i915_ggtt_probe_hw - Probe GGTT hardware location
Chris Wilson97d6d7a2016-08-04 07:52:22 +01003230 * @dev_priv: i915 device
Joonas Lahtinend85489d2016-03-24 16:47:46 +02003231 */
Chris Wilson97d6d7a2016-08-04 07:52:22 +01003232int i915_ggtt_probe_hw(struct drm_i915_private *dev_priv)
Ben Widawskybaa09f52013-01-24 13:49:57 -08003233{
Joonas Lahtinen62106b42016-03-18 10:42:57 +02003234 struct i915_ggtt *ggtt = &dev_priv->ggtt;
Ben Widawskybaa09f52013-01-24 13:49:57 -08003235 int ret;
Ben Widawskye76e9ae2012-11-04 09:21:27 -08003236
Chris Wilson49d73912016-11-29 09:50:08 +00003237 ggtt->base.i915 = dev_priv;
Chris Wilson84486612017-02-15 08:43:40 +00003238 ggtt->base.dma = &dev_priv->drm.pdev->dev;
Mika Kuoppalac114f762015-06-25 18:35:13 +03003239
Chris Wilson34c998b2016-08-04 07:52:24 +01003240 if (INTEL_GEN(dev_priv) <= 5)
3241 ret = i915_gmch_probe(ggtt);
3242 else if (INTEL_GEN(dev_priv) < 8)
3243 ret = gen6_gmch_probe(ggtt);
3244 else
3245 ret = gen8_gmch_probe(ggtt);
Ben Widawskya54c0c22013-01-24 14:45:00 -08003246 if (ret)
Ben Widawskybaa09f52013-01-24 13:49:57 -08003247 return ret;
Ben Widawskye76e9ae2012-11-04 09:21:27 -08003248
Chris Wilsondb9309a2017-01-05 15:30:23 +00003249 /* Trim the GGTT to fit the GuC mappable upper range (when enabled).
3250 * This is easier than doing range restriction on the fly, as we
3251 * currently don't have any bits spare to pass in this upper
3252 * restriction!
3253 */
3254 if (HAS_GUC(dev_priv) && i915.enable_guc_loading) {
3255 ggtt->base.total = min_t(u64, ggtt->base.total, GUC_GGTT_TOP);
3256 ggtt->mappable_end = min(ggtt->mappable_end, ggtt->base.total);
3257 }
3258
Chris Wilsonc890e2d2016-03-18 10:42:59 +02003259 if ((ggtt->base.total - 1) >> 32) {
3260 DRM_ERROR("We never expected a Global GTT with more than 32bits"
Chris Wilsonf6b9d5c2016-08-04 07:52:23 +01003261 " of address space! Found %lldM!\n",
Chris Wilsonc890e2d2016-03-18 10:42:59 +02003262 ggtt->base.total >> 20);
3263 ggtt->base.total = 1ULL << 32;
3264 ggtt->mappable_end = min(ggtt->mappable_end, ggtt->base.total);
3265 }
3266
Chris Wilsonf6b9d5c2016-08-04 07:52:23 +01003267 if (ggtt->mappable_end > ggtt->base.total) {
3268 DRM_ERROR("mappable aperture extends past end of GGTT,"
3269 " aperture=%llx, total=%llx\n",
3270 ggtt->mappable_end, ggtt->base.total);
3271 ggtt->mappable_end = ggtt->base.total;
3272 }
3273
Ben Widawskybaa09f52013-01-24 13:49:57 -08003274 /* GMADR is the PCI mmio aperture into the global GTT. */
Mika Kuoppalac44ef602015-06-25 18:35:05 +03003275 DRM_INFO("Memory usable by graphics device = %lluM\n",
Joonas Lahtinen62106b42016-03-18 10:42:57 +02003276 ggtt->base.total >> 20);
3277 DRM_DEBUG_DRIVER("GMADR size = %lldM\n", ggtt->mappable_end >> 20);
Chris Wilsonedd1f2f2017-01-06 15:20:11 +00003278 DRM_DEBUG_DRIVER("GTT stolen size = %uM\n", ggtt->stolen_size >> 20);
Daniel Vetter5db6c732014-03-31 16:23:04 +02003279#ifdef CONFIG_INTEL_IOMMU
3280 if (intel_iommu_gfx_mapped)
3281 DRM_INFO("VT-d active for gfx access\n");
3282#endif
Daniel Vetter7faf1ab2013-01-24 14:44:55 -08003283
Ben Widawskye76e9ae2012-11-04 09:21:27 -08003284 return 0;
Chris Wilson0088e522016-08-04 07:52:21 +01003285}
3286
3287/**
3288 * i915_ggtt_init_hw - Initialize GGTT hardware
Chris Wilson97d6d7a2016-08-04 07:52:22 +01003289 * @dev_priv: i915 device
Chris Wilson0088e522016-08-04 07:52:21 +01003290 */
Chris Wilson97d6d7a2016-08-04 07:52:22 +01003291int i915_ggtt_init_hw(struct drm_i915_private *dev_priv)
Chris Wilson0088e522016-08-04 07:52:21 +01003292{
Chris Wilson0088e522016-08-04 07:52:21 +01003293 struct i915_ggtt *ggtt = &dev_priv->ggtt;
3294 int ret;
3295
Chris Wilsonf6b9d5c2016-08-04 07:52:23 +01003296 INIT_LIST_HEAD(&dev_priv->vm_list);
3297
Chris Wilsona6508de2017-02-06 08:45:47 +00003298 /* Note that we use page colouring to enforce a guard page at the
3299 * end of the address space. This is required as the CS may prefetch
3300 * beyond the end of the batch buffer, across the page boundary,
3301 * and beyond the end of the GTT if we do not provide a guard.
Chris Wilsonf6b9d5c2016-08-04 07:52:23 +01003302 */
Chris Wilson80b204b2016-10-28 13:58:58 +01003303 mutex_lock(&dev_priv->drm.struct_mutex);
Chris Wilson80b204b2016-10-28 13:58:58 +01003304 i915_address_space_init(&ggtt->base, dev_priv, "[global]");
Chris Wilsona6508de2017-02-06 08:45:47 +00003305 if (!HAS_LLC(dev_priv) && !USES_PPGTT(dev_priv))
Chris Wilsonf6b9d5c2016-08-04 07:52:23 +01003306 ggtt->base.mm.color_adjust = i915_gtt_color_adjust;
Chris Wilson80b204b2016-10-28 13:58:58 +01003307 mutex_unlock(&dev_priv->drm.struct_mutex);
Chris Wilsonf6b9d5c2016-08-04 07:52:23 +01003308
Chris Wilsonf7bbe782016-08-19 16:54:27 +01003309 if (!io_mapping_init_wc(&dev_priv->ggtt.mappable,
3310 dev_priv->ggtt.mappable_base,
3311 dev_priv->ggtt.mappable_end)) {
Chris Wilsonf6b9d5c2016-08-04 07:52:23 +01003312 ret = -EIO;
3313 goto out_gtt_cleanup;
3314 }
3315
3316 ggtt->mtrr = arch_phys_wc_add(ggtt->mappable_base, ggtt->mappable_end);
3317
Chris Wilson0088e522016-08-04 07:52:21 +01003318 /*
3319 * Initialise stolen early so that we may reserve preallocated
3320 * objects for the BIOS to KMS transition.
3321 */
Tvrtko Ursulin7ace3d32016-11-16 08:55:35 +00003322 ret = i915_gem_init_stolen(dev_priv);
Chris Wilson0088e522016-08-04 07:52:21 +01003323 if (ret)
3324 goto out_gtt_cleanup;
3325
3326 return 0;
Imre Deaka4eba472016-01-19 15:26:32 +02003327
3328out_gtt_cleanup:
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03003329 ggtt->base.cleanup(&ggtt->base);
Imre Deaka4eba472016-01-19 15:26:32 +02003330 return ret;
Daniel Vetter644ec022012-03-26 09:45:40 +02003331}
Ben Widawsky6f65e292013-12-06 14:10:56 -08003332
Chris Wilson97d6d7a2016-08-04 07:52:22 +01003333int i915_ggtt_enable_hw(struct drm_i915_private *dev_priv)
Ville Syrjäläac840ae2016-05-06 21:35:55 +03003334{
Chris Wilson97d6d7a2016-08-04 07:52:22 +01003335 if (INTEL_GEN(dev_priv) < 6 && !intel_enable_gtt())
Ville Syrjäläac840ae2016-05-06 21:35:55 +03003336 return -EIO;
3337
3338 return 0;
3339}
3340
Chris Wilson7c3f86b2017-01-12 11:00:49 +00003341void i915_ggtt_enable_guc(struct drm_i915_private *i915)
3342{
3343 i915->ggtt.invalidate = guc_ggtt_invalidate;
3344}
3345
3346void i915_ggtt_disable_guc(struct drm_i915_private *i915)
3347{
3348 i915->ggtt.invalidate = gen6_ggtt_invalidate;
3349}
3350
Tvrtko Ursulin275a9912016-11-16 08:55:34 +00003351void i915_gem_restore_gtt_mappings(struct drm_i915_private *dev_priv)
Daniel Vetterfa423312015-04-14 17:35:23 +02003352{
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03003353 struct i915_ggtt *ggtt = &dev_priv->ggtt;
Chris Wilsonfbb30a5c2016-09-09 21:19:57 +01003354 struct drm_i915_gem_object *obj, *on;
Daniel Vetterfa423312015-04-14 17:35:23 +02003355
Chris Wilsondc979972016-05-10 14:10:04 +01003356 i915_check_and_clear_faults(dev_priv);
Daniel Vetterfa423312015-04-14 17:35:23 +02003357
3358 /* First fill our portion of the GTT with scratch pages */
Michał Winiarski4fb84d92016-10-13 14:02:40 +02003359 ggtt->base.clear_range(&ggtt->base, ggtt->base.start, ggtt->base.total);
Daniel Vetterfa423312015-04-14 17:35:23 +02003360
Chris Wilsonfbb30a5c2016-09-09 21:19:57 +01003361 ggtt->base.closed = true; /* skip rewriting PTE on VMA unbind */
3362
3363 /* clflush objects bound into the GGTT and rebind them. */
3364 list_for_each_entry_safe(obj, on,
Joonas Lahtinen56cea322016-11-02 12:16:04 +02003365 &dev_priv->mm.bound_list, global_link) {
Chris Wilsonfbb30a5c2016-09-09 21:19:57 +01003366 bool ggtt_bound = false;
3367 struct i915_vma *vma;
3368
Chris Wilson1c7f4bc2016-02-26 11:03:19 +00003369 list_for_each_entry(vma, &obj->vma_list, obj_link) {
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03003370 if (vma->vm != &ggtt->base)
Tvrtko Ursulin2c3d9982015-07-06 15:15:01 +01003371 continue;
Daniel Vetterfa423312015-04-14 17:35:23 +02003372
Chris Wilsonfbb30a5c2016-09-09 21:19:57 +01003373 if (!i915_vma_unbind(vma))
3374 continue;
3375
Tvrtko Ursulin2c3d9982015-07-06 15:15:01 +01003376 WARN_ON(i915_vma_bind(vma, obj->cache_level,
3377 PIN_UPDATE));
Chris Wilsonfbb30a5c2016-09-09 21:19:57 +01003378 ggtt_bound = true;
Tvrtko Ursulin2c3d9982015-07-06 15:15:01 +01003379 }
3380
Chris Wilsonfbb30a5c2016-09-09 21:19:57 +01003381 if (ggtt_bound)
Chris Wilson975f7ff2016-05-14 07:26:34 +01003382 WARN_ON(i915_gem_object_set_to_gtt_domain(obj, false));
Daniel Vetterfa423312015-04-14 17:35:23 +02003383 }
3384
Chris Wilsonfbb30a5c2016-09-09 21:19:57 +01003385 ggtt->base.closed = false;
3386
Tvrtko Ursulin275a9912016-11-16 08:55:34 +00003387 if (INTEL_GEN(dev_priv) >= 8) {
Ander Conselvan de Oliveiracc3f90f2016-12-02 10:23:49 +02003388 if (IS_CHERRYVIEW(dev_priv) || IS_GEN9_LP(dev_priv))
Daniel Vetterfa423312015-04-14 17:35:23 +02003389 chv_setup_private_ppat(dev_priv);
3390 else
3391 bdw_setup_private_ppat(dev_priv);
3392
3393 return;
3394 }
3395
Tvrtko Ursulin275a9912016-11-16 08:55:34 +00003396 if (USES_PPGTT(dev_priv)) {
Joonas Lahtinen72e96d62016-03-30 16:57:10 +03003397 struct i915_address_space *vm;
3398
Daniel Vetterfa423312015-04-14 17:35:23 +02003399 list_for_each_entry(vm, &dev_priv->vm_list, global_link) {
3400 /* TODO: Perhaps it shouldn't be gen6 specific */
3401
Joonas Lahtinene5716f52016-04-07 11:08:03 +03003402 struct i915_hw_ppgtt *ppgtt;
Daniel Vetterfa423312015-04-14 17:35:23 +02003403
Chris Wilson2bfa9962016-08-04 07:52:25 +01003404 if (i915_is_ggtt(vm))
Daniel Vetterfa423312015-04-14 17:35:23 +02003405 ppgtt = dev_priv->mm.aliasing_ppgtt;
Joonas Lahtinene5716f52016-04-07 11:08:03 +03003406 else
3407 ppgtt = i915_vm_to_ppgtt(vm);
Daniel Vetterfa423312015-04-14 17:35:23 +02003408
3409 gen6_write_page_range(dev_priv, &ppgtt->pd,
3410 0, ppgtt->base.total);
3411 }
3412 }
3413
Chris Wilson7c3f86b2017-01-12 11:00:49 +00003414 i915_ggtt_invalidate(dev_priv);
Daniel Vetterfa423312015-04-14 17:35:23 +02003415}
3416
Tvrtko Ursulin804beb42015-09-21 10:45:33 +01003417static struct scatterlist *
Ville Syrjälä2d7f3bd2016-01-14 15:22:11 +02003418rotate_pages(const dma_addr_t *in, unsigned int offset,
Tvrtko Ursulin804beb42015-09-21 10:45:33 +01003419 unsigned int width, unsigned int height,
Ville Syrjälä87130252016-01-20 21:05:23 +02003420 unsigned int stride,
Tvrtko Ursulin804beb42015-09-21 10:45:33 +01003421 struct sg_table *st, struct scatterlist *sg)
Tvrtko Ursulinfe14d5f2014-12-10 17:27:58 +00003422{
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003423 unsigned int column, row;
3424 unsigned int src_idx;
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003425
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003426 for (column = 0; column < width; column++) {
Ville Syrjälä87130252016-01-20 21:05:23 +02003427 src_idx = stride * (height - 1) + column;
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003428 for (row = 0; row < height; row++) {
3429 st->nents++;
3430 /* We don't need the pages, but need to initialize
3431 * the entries so the sg list can be happily traversed.
3432 * The only thing we need are DMA addresses.
3433 */
3434 sg_set_page(sg, NULL, PAGE_SIZE, 0);
Tvrtko Ursulin804beb42015-09-21 10:45:33 +01003435 sg_dma_address(sg) = in[offset + src_idx];
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003436 sg_dma_len(sg) = PAGE_SIZE;
3437 sg = sg_next(sg);
Ville Syrjälä87130252016-01-20 21:05:23 +02003438 src_idx -= stride;
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003439 }
3440 }
Tvrtko Ursulin804beb42015-09-21 10:45:33 +01003441
3442 return sg;
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003443}
3444
Chris Wilsonba7a5742017-02-15 08:43:35 +00003445static noinline struct sg_table *
3446intel_rotate_pages(struct intel_rotation_info *rot_info,
3447 struct drm_i915_gem_object *obj)
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003448{
Dave Gordon85d12252016-05-20 11:54:06 +01003449 const size_t n_pages = obj->base.size / PAGE_SIZE;
Ville Syrjälä6687c902015-09-15 13:16:41 +03003450 unsigned int size = intel_rotation_info_size(rot_info);
Dave Gordon85d12252016-05-20 11:54:06 +01003451 struct sgt_iter sgt_iter;
3452 dma_addr_t dma_addr;
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003453 unsigned long i;
3454 dma_addr_t *page_addr_list;
3455 struct sg_table *st;
Tvrtko Ursulin89e3e142015-09-21 10:45:34 +01003456 struct scatterlist *sg;
Tvrtko Ursulin1d00dad2015-03-25 10:15:26 +00003457 int ret = -ENOMEM;
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003458
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003459 /* Allocate a temporary list of source pages for random access. */
Dave Gordon85d12252016-05-20 11:54:06 +01003460 page_addr_list = drm_malloc_gfp(n_pages,
Chris Wilsonf2a85e12016-04-08 12:11:13 +01003461 sizeof(dma_addr_t),
3462 GFP_TEMPORARY);
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003463 if (!page_addr_list)
3464 return ERR_PTR(ret);
3465
3466 /* Allocate target SG list. */
3467 st = kmalloc(sizeof(*st), GFP_KERNEL);
3468 if (!st)
3469 goto err_st_alloc;
3470
Ville Syrjälä6687c902015-09-15 13:16:41 +03003471 ret = sg_alloc_table(st, size, GFP_KERNEL);
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003472 if (ret)
3473 goto err_sg_alloc;
3474
3475 /* Populate source page list from the object. */
3476 i = 0;
Chris Wilsona4f5ea62016-10-28 13:58:35 +01003477 for_each_sgt_dma(dma_addr, sgt_iter, obj->mm.pages)
Dave Gordon85d12252016-05-20 11:54:06 +01003478 page_addr_list[i++] = dma_addr;
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003479
Dave Gordon85d12252016-05-20 11:54:06 +01003480 GEM_BUG_ON(i != n_pages);
Ville Syrjälä11f20322016-02-15 22:54:46 +02003481 st->nents = 0;
3482 sg = st->sgl;
3483
Ville Syrjälä6687c902015-09-15 13:16:41 +03003484 for (i = 0 ; i < ARRAY_SIZE(rot_info->plane); i++) {
3485 sg = rotate_pages(page_addr_list, rot_info->plane[i].offset,
3486 rot_info->plane[i].width, rot_info->plane[i].height,
3487 rot_info->plane[i].stride, st, sg);
Tvrtko Ursulin89e3e142015-09-21 10:45:34 +01003488 }
3489
Ville Syrjälä6687c902015-09-15 13:16:41 +03003490 DRM_DEBUG_KMS("Created rotated page mapping for object size %zu (%ux%u tiles, %u pages)\n",
3491 obj->base.size, rot_info->plane[0].width, rot_info->plane[0].height, size);
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003492
3493 drm_free_large(page_addr_list);
3494
3495 return st;
3496
3497err_sg_alloc:
3498 kfree(st);
3499err_st_alloc:
3500 drm_free_large(page_addr_list);
3501
Ville Syrjälä6687c902015-09-15 13:16:41 +03003502 DRM_DEBUG_KMS("Failed to create rotated mapping for object size %zu! (%ux%u tiles, %u pages)\n",
3503 obj->base.size, rot_info->plane[0].width, rot_info->plane[0].height, size);
3504
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003505 return ERR_PTR(ret);
3506}
3507
Chris Wilsonba7a5742017-02-15 08:43:35 +00003508static noinline struct sg_table *
Joonas Lahtinen8bd7ef12015-05-06 14:35:38 +03003509intel_partial_pages(const struct i915_ggtt_view *view,
3510 struct drm_i915_gem_object *obj)
3511{
3512 struct sg_table *st;
Chris Wilsond2a84a72016-10-28 13:58:34 +01003513 struct scatterlist *sg, *iter;
Chris Wilson8bab11932017-01-14 00:28:25 +00003514 unsigned int count = view->partial.size;
Chris Wilsond2a84a72016-10-28 13:58:34 +01003515 unsigned int offset;
Joonas Lahtinen8bd7ef12015-05-06 14:35:38 +03003516 int ret = -ENOMEM;
3517
3518 st = kmalloc(sizeof(*st), GFP_KERNEL);
3519 if (!st)
3520 goto err_st_alloc;
3521
Chris Wilsond2a84a72016-10-28 13:58:34 +01003522 ret = sg_alloc_table(st, count, GFP_KERNEL);
Joonas Lahtinen8bd7ef12015-05-06 14:35:38 +03003523 if (ret)
3524 goto err_sg_alloc;
3525
Chris Wilson8bab11932017-01-14 00:28:25 +00003526 iter = i915_gem_object_get_sg(obj, view->partial.offset, &offset);
Chris Wilsond2a84a72016-10-28 13:58:34 +01003527 GEM_BUG_ON(!iter);
3528
Joonas Lahtinen8bd7ef12015-05-06 14:35:38 +03003529 sg = st->sgl;
3530 st->nents = 0;
Chris Wilsond2a84a72016-10-28 13:58:34 +01003531 do {
3532 unsigned int len;
Joonas Lahtinen8bd7ef12015-05-06 14:35:38 +03003533
Chris Wilsond2a84a72016-10-28 13:58:34 +01003534 len = min(iter->length - (offset << PAGE_SHIFT),
3535 count << PAGE_SHIFT);
3536 sg_set_page(sg, NULL, len, 0);
3537 sg_dma_address(sg) =
3538 sg_dma_address(iter) + (offset << PAGE_SHIFT);
3539 sg_dma_len(sg) = len;
Joonas Lahtinen8bd7ef12015-05-06 14:35:38 +03003540
Joonas Lahtinen8bd7ef12015-05-06 14:35:38 +03003541 st->nents++;
Chris Wilsond2a84a72016-10-28 13:58:34 +01003542 count -= len >> PAGE_SHIFT;
3543 if (count == 0) {
3544 sg_mark_end(sg);
3545 return st;
3546 }
Joonas Lahtinen8bd7ef12015-05-06 14:35:38 +03003547
Chris Wilsond2a84a72016-10-28 13:58:34 +01003548 sg = __sg_next(sg);
3549 iter = __sg_next(iter);
3550 offset = 0;
3551 } while (1);
Joonas Lahtinen8bd7ef12015-05-06 14:35:38 +03003552
3553err_sg_alloc:
3554 kfree(st);
3555err_st_alloc:
3556 return ERR_PTR(ret);
3557}
3558
Daniel Vetter70b9f6f2015-04-14 17:35:27 +02003559static int
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003560i915_get_ggtt_vma_pages(struct i915_vma *vma)
3561{
Chris Wilsonba7a5742017-02-15 08:43:35 +00003562 int ret;
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003563
Chris Wilson2c3a3f42016-11-04 10:30:01 +00003564 /* The vma->pages are only valid within the lifespan of the borrowed
3565 * obj->mm.pages. When the obj->mm.pages sg_table is regenerated, so
3566 * must be the vma->pages. A simple rule is that vma->pages must only
3567 * be accessed when the obj->mm.pages are pinned.
3568 */
3569 GEM_BUG_ON(!i915_gem_object_has_pinned_pages(vma->obj));
3570
Chris Wilsonba7a5742017-02-15 08:43:35 +00003571 switch (vma->ggtt_view.type) {
3572 case I915_GGTT_VIEW_NORMAL:
3573 vma->pages = vma->obj->mm.pages;
Tvrtko Ursulinfe14d5f2014-12-10 17:27:58 +00003574 return 0;
3575
Chris Wilsonba7a5742017-02-15 08:43:35 +00003576 case I915_GGTT_VIEW_ROTATED:
Chris Wilson247177d2016-08-15 10:48:47 +01003577 vma->pages =
Chris Wilsonba7a5742017-02-15 08:43:35 +00003578 intel_rotate_pages(&vma->ggtt_view.rotated, vma->obj);
3579 break;
3580
3581 case I915_GGTT_VIEW_PARTIAL:
Chris Wilson247177d2016-08-15 10:48:47 +01003582 vma->pages = intel_partial_pages(&vma->ggtt_view, vma->obj);
Chris Wilsonba7a5742017-02-15 08:43:35 +00003583 break;
3584
3585 default:
Tvrtko Ursulinfe14d5f2014-12-10 17:27:58 +00003586 WARN_ONCE(1, "GGTT view %u not implemented!\n",
3587 vma->ggtt_view.type);
Chris Wilsonba7a5742017-02-15 08:43:35 +00003588 return -EINVAL;
3589 }
Tvrtko Ursulinfe14d5f2014-12-10 17:27:58 +00003590
Chris Wilsonba7a5742017-02-15 08:43:35 +00003591 ret = 0;
3592 if (unlikely(IS_ERR(vma->pages))) {
Chris Wilson247177d2016-08-15 10:48:47 +01003593 ret = PTR_ERR(vma->pages);
3594 vma->pages = NULL;
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003595 DRM_ERROR("Failed to get pages for VMA view type %u (%d)!\n",
3596 vma->ggtt_view.type, ret);
Tvrtko Ursulinfe14d5f2014-12-10 17:27:58 +00003597 }
Tvrtko Ursulin50470bb2015-03-23 11:10:36 +00003598 return ret;
Tvrtko Ursulinfe14d5f2014-12-10 17:27:58 +00003599}
3600
Chris Wilsone007b192017-01-11 11:23:10 +00003601/**
Chris Wilson625d9882017-01-11 11:23:11 +00003602 * i915_gem_gtt_reserve - reserve a node in an address_space (GTT)
Chris Wilsona4dbf7c2017-01-12 16:45:59 +00003603 * @vm: the &struct i915_address_space
3604 * @node: the &struct drm_mm_node (typically i915_vma.mode)
3605 * @size: how much space to allocate inside the GTT,
3606 * must be #I915_GTT_PAGE_SIZE aligned
3607 * @offset: where to insert inside the GTT,
3608 * must be #I915_GTT_MIN_ALIGNMENT aligned, and the node
3609 * (@offset + @size) must fit within the address space
3610 * @color: color to apply to node, if this node is not from a VMA,
3611 * color must be #I915_COLOR_UNEVICTABLE
3612 * @flags: control search and eviction behaviour
Chris Wilson625d9882017-01-11 11:23:11 +00003613 *
3614 * i915_gem_gtt_reserve() tries to insert the @node at the exact @offset inside
3615 * the address space (using @size and @color). If the @node does not fit, it
3616 * tries to evict any overlapping nodes from the GTT, including any
3617 * neighbouring nodes if the colors do not match (to ensure guard pages between
3618 * differing domains). See i915_gem_evict_for_node() for the gory details
3619 * on the eviction algorithm. #PIN_NONBLOCK may used to prevent waiting on
3620 * evicting active overlapping objects, and any overlapping node that is pinned
3621 * or marked as unevictable will also result in failure.
3622 *
3623 * Returns: 0 on success, -ENOSPC if no suitable hole is found, -EINTR if
3624 * asked to wait for eviction and interrupted.
3625 */
3626int i915_gem_gtt_reserve(struct i915_address_space *vm,
3627 struct drm_mm_node *node,
3628 u64 size, u64 offset, unsigned long color,
3629 unsigned int flags)
3630{
3631 int err;
3632
3633 GEM_BUG_ON(!size);
3634 GEM_BUG_ON(!IS_ALIGNED(size, I915_GTT_PAGE_SIZE));
3635 GEM_BUG_ON(!IS_ALIGNED(offset, I915_GTT_MIN_ALIGNMENT));
3636 GEM_BUG_ON(range_overflows(offset, size, vm->total));
Chris Wilson3fec7ec2017-01-15 13:47:46 +00003637 GEM_BUG_ON(vm == &vm->i915->mm.aliasing_ppgtt->base);
Chris Wilson9734ad12017-01-15 17:27:40 +00003638 GEM_BUG_ON(drm_mm_node_allocated(node));
Chris Wilson625d9882017-01-11 11:23:11 +00003639
3640 node->size = size;
3641 node->start = offset;
3642 node->color = color;
3643
3644 err = drm_mm_reserve_node(&vm->mm, node);
3645 if (err != -ENOSPC)
3646 return err;
3647
3648 err = i915_gem_evict_for_node(vm, node, flags);
3649 if (err == 0)
3650 err = drm_mm_reserve_node(&vm->mm, node);
3651
3652 return err;
3653}
3654
Chris Wilson606fec92017-01-11 11:23:12 +00003655static u64 random_offset(u64 start, u64 end, u64 len, u64 align)
3656{
3657 u64 range, addr;
3658
3659 GEM_BUG_ON(range_overflows(start, len, end));
3660 GEM_BUG_ON(round_up(start, align) > round_down(end - len, align));
3661
3662 range = round_down(end - len, align) - round_up(start, align);
3663 if (range) {
3664 if (sizeof(unsigned long) == sizeof(u64)) {
3665 addr = get_random_long();
3666 } else {
3667 addr = get_random_int();
3668 if (range > U32_MAX) {
3669 addr <<= 32;
3670 addr |= get_random_int();
3671 }
3672 }
3673 div64_u64_rem(addr, range, &addr);
3674 start += addr;
3675 }
3676
3677 return round_up(start, align);
3678}
3679
Chris Wilson625d9882017-01-11 11:23:11 +00003680/**
Chris Wilsone007b192017-01-11 11:23:10 +00003681 * i915_gem_gtt_insert - insert a node into an address_space (GTT)
Chris Wilsona4dbf7c2017-01-12 16:45:59 +00003682 * @vm: the &struct i915_address_space
3683 * @node: the &struct drm_mm_node (typically i915_vma.node)
3684 * @size: how much space to allocate inside the GTT,
3685 * must be #I915_GTT_PAGE_SIZE aligned
3686 * @alignment: required alignment of starting offset, may be 0 but
3687 * if specified, this must be a power-of-two and at least
3688 * #I915_GTT_MIN_ALIGNMENT
3689 * @color: color to apply to node
3690 * @start: start of any range restriction inside GTT (0 for all),
Chris Wilsone007b192017-01-11 11:23:10 +00003691 * must be #I915_GTT_PAGE_SIZE aligned
Chris Wilsona4dbf7c2017-01-12 16:45:59 +00003692 * @end: end of any range restriction inside GTT (U64_MAX for all),
3693 * must be #I915_GTT_PAGE_SIZE aligned if not U64_MAX
3694 * @flags: control search and eviction behaviour
Chris Wilsone007b192017-01-11 11:23:10 +00003695 *
3696 * i915_gem_gtt_insert() first searches for an available hole into which
3697 * is can insert the node. The hole address is aligned to @alignment and
3698 * its @size must then fit entirely within the [@start, @end] bounds. The
3699 * nodes on either side of the hole must match @color, or else a guard page
3700 * will be inserted between the two nodes (or the node evicted). If no
Chris Wilson606fec92017-01-11 11:23:12 +00003701 * suitable hole is found, first a victim is randomly selected and tested
3702 * for eviction, otherwise then the LRU list of objects within the GTT
Chris Wilsone007b192017-01-11 11:23:10 +00003703 * is scanned to find the first set of replacement nodes to create the hole.
3704 * Those old overlapping nodes are evicted from the GTT (and so must be
3705 * rebound before any future use). Any node that is currently pinned cannot
3706 * be evicted (see i915_vma_pin()). Similar if the node's VMA is currently
3707 * active and #PIN_NONBLOCK is specified, that node is also skipped when
3708 * searching for an eviction candidate. See i915_gem_evict_something() for
3709 * the gory details on the eviction algorithm.
3710 *
3711 * Returns: 0 on success, -ENOSPC if no suitable hole is found, -EINTR if
3712 * asked to wait for eviction and interrupted.
3713 */
3714int i915_gem_gtt_insert(struct i915_address_space *vm,
3715 struct drm_mm_node *node,
3716 u64 size, u64 alignment, unsigned long color,
3717 u64 start, u64 end, unsigned int flags)
3718{
Chris Wilson4e64e552017-02-02 21:04:38 +00003719 enum drm_mm_insert_mode mode;
Chris Wilson606fec92017-01-11 11:23:12 +00003720 u64 offset;
Chris Wilsone007b192017-01-11 11:23:10 +00003721 int err;
3722
3723 lockdep_assert_held(&vm->i915->drm.struct_mutex);
3724 GEM_BUG_ON(!size);
3725 GEM_BUG_ON(!IS_ALIGNED(size, I915_GTT_PAGE_SIZE));
3726 GEM_BUG_ON(alignment && !is_power_of_2(alignment));
3727 GEM_BUG_ON(alignment && !IS_ALIGNED(alignment, I915_GTT_MIN_ALIGNMENT));
3728 GEM_BUG_ON(start >= end);
3729 GEM_BUG_ON(start > 0 && !IS_ALIGNED(start, I915_GTT_PAGE_SIZE));
3730 GEM_BUG_ON(end < U64_MAX && !IS_ALIGNED(end, I915_GTT_PAGE_SIZE));
Chris Wilson3fec7ec2017-01-15 13:47:46 +00003731 GEM_BUG_ON(vm == &vm->i915->mm.aliasing_ppgtt->base);
Chris Wilson9734ad12017-01-15 17:27:40 +00003732 GEM_BUG_ON(drm_mm_node_allocated(node));
Chris Wilsone007b192017-01-11 11:23:10 +00003733
3734 if (unlikely(range_overflows(start, size, end)))
3735 return -ENOSPC;
3736
3737 if (unlikely(round_up(start, alignment) > round_down(end - size, alignment)))
3738 return -ENOSPC;
3739
Chris Wilson4e64e552017-02-02 21:04:38 +00003740 mode = DRM_MM_INSERT_BEST;
3741 if (flags & PIN_HIGH)
3742 mode = DRM_MM_INSERT_HIGH;
3743 if (flags & PIN_MAPPABLE)
3744 mode = DRM_MM_INSERT_LOW;
Chris Wilsone007b192017-01-11 11:23:10 +00003745
3746 /* We only allocate in PAGE_SIZE/GTT_PAGE_SIZE (4096) chunks,
3747 * so we know that we always have a minimum alignment of 4096.
3748 * The drm_mm range manager is optimised to return results
3749 * with zero alignment, so where possible use the optimal
3750 * path.
3751 */
3752 BUILD_BUG_ON(I915_GTT_MIN_ALIGNMENT > I915_GTT_PAGE_SIZE);
3753 if (alignment <= I915_GTT_MIN_ALIGNMENT)
3754 alignment = 0;
3755
Chris Wilson4e64e552017-02-02 21:04:38 +00003756 err = drm_mm_insert_node_in_range(&vm->mm, node,
3757 size, alignment, color,
3758 start, end, mode);
Chris Wilsone007b192017-01-11 11:23:10 +00003759 if (err != -ENOSPC)
3760 return err;
3761
Chris Wilson606fec92017-01-11 11:23:12 +00003762 /* No free space, pick a slot at random.
3763 *
3764 * There is a pathological case here using a GTT shared between
3765 * mmap and GPU (i.e. ggtt/aliasing_ppgtt but not full-ppgtt):
3766 *
3767 * |<-- 256 MiB aperture -->||<-- 1792 MiB unmappable -->|
3768 * (64k objects) (448k objects)
3769 *
3770 * Now imagine that the eviction LRU is ordered top-down (just because
3771 * pathology meets real life), and that we need to evict an object to
3772 * make room inside the aperture. The eviction scan then has to walk
3773 * the 448k list before it finds one within range. And now imagine that
3774 * it has to search for a new hole between every byte inside the memcpy,
3775 * for several simultaneous clients.
3776 *
3777 * On a full-ppgtt system, if we have run out of available space, there
3778 * will be lots and lots of objects in the eviction list! Again,
3779 * searching that LRU list may be slow if we are also applying any
3780 * range restrictions (e.g. restriction to low 4GiB) and so, for
3781 * simplicity and similarilty between different GTT, try the single
3782 * random replacement first.
3783 */
3784 offset = random_offset(start, end,
3785 size, alignment ?: I915_GTT_MIN_ALIGNMENT);
3786 err = i915_gem_gtt_reserve(vm, node, size, offset, color, flags);
3787 if (err != -ENOSPC)
3788 return err;
3789
3790 /* Randomly selected placement is pinned, do a search */
Chris Wilsone007b192017-01-11 11:23:10 +00003791 err = i915_gem_evict_something(vm, size, alignment, color,
3792 start, end, flags);
3793 if (err)
3794 return err;
3795
Chris Wilson4e64e552017-02-02 21:04:38 +00003796 return drm_mm_insert_node_in_range(&vm->mm, node,
3797 size, alignment, color,
3798 start, end, DRM_MM_INSERT_EVICT);
Chris Wilsone007b192017-01-11 11:23:10 +00003799}
Chris Wilson3b5bb0a2017-02-13 17:15:18 +00003800
3801#if IS_ENABLED(CONFIG_DRM_I915_SELFTEST)
3802#include "selftests/mock_gtt.c"
Chris Wilson1c428192017-02-13 17:15:38 +00003803#include "selftests/i915_gem_gtt.c"
Chris Wilson3b5bb0a2017-02-13 17:15:18 +00003804#endif