1ba55f2f5SFrançois Tigeot /*
2ba55f2f5SFrançois Tigeot * Copyright © 2014 Intel Corporation
3ba55f2f5SFrançois Tigeot *
4ba55f2f5SFrançois Tigeot * Permission is hereby granted, free of charge, to any person obtaining a
5ba55f2f5SFrançois Tigeot * copy of this software and associated documentation files (the "Software"),
6ba55f2f5SFrançois Tigeot * to deal in the Software without restriction, including without limitation
7ba55f2f5SFrançois Tigeot * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8ba55f2f5SFrançois Tigeot * and/or sell copies of the Software, and to permit persons to whom the
9ba55f2f5SFrançois Tigeot * Software is furnished to do so, subject to the following conditions:
10ba55f2f5SFrançois Tigeot *
11ba55f2f5SFrançois Tigeot * The above copyright notice and this permission notice (including the next
12ba55f2f5SFrançois Tigeot * paragraph) shall be included in all copies or substantial portions of the
13ba55f2f5SFrançois Tigeot * Software.
14ba55f2f5SFrançois Tigeot *
15ba55f2f5SFrançois Tigeot * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16ba55f2f5SFrançois Tigeot * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17ba55f2f5SFrançois Tigeot * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18ba55f2f5SFrançois Tigeot * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19ba55f2f5SFrançois Tigeot * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20ba55f2f5SFrançois Tigeot * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21ba55f2f5SFrançois Tigeot * IN THE SOFTWARE.
22ba55f2f5SFrançois Tigeot *
23ba55f2f5SFrançois Tigeot * Please try to maintain the following order within this file unless it makes
24ba55f2f5SFrançois Tigeot * sense to do otherwise. From top to bottom:
25ba55f2f5SFrançois Tigeot * 1. typedefs
26ba55f2f5SFrançois Tigeot * 2. #defines, and macros
27ba55f2f5SFrançois Tigeot * 3. structure definitions
28ba55f2f5SFrançois Tigeot * 4. function prototypes
29ba55f2f5SFrançois Tigeot *
30ba55f2f5SFrançois Tigeot * Within each section, please try to order by generation in ascending order,
31ba55f2f5SFrançois Tigeot * from top to bottom (ie. gen6 on the top, gen8 on the bottom).
32ba55f2f5SFrançois Tigeot */
33ba55f2f5SFrançois Tigeot
34ba55f2f5SFrançois Tigeot #ifndef __I915_GEM_GTT_H__
35ba55f2f5SFrançois Tigeot #define __I915_GEM_GTT_H__
36ba55f2f5SFrançois Tigeot
371487f786SFrançois Tigeot #include <linux/io-mapping.h>
384be47400SFrançois Tigeot #include <linux/mm.h>
39a85cb24fSFrançois Tigeot #include <linux/pagevec.h>
401487f786SFrançois Tigeot
414be47400SFrançois Tigeot #include "i915_gem_timeline.h"
4271f41f3eSFrançois Tigeot #include "i915_gem_request.h"
43a85cb24fSFrançois Tigeot #include "i915_selftest.h"
44a85cb24fSFrançois Tigeot
45*3f2dd94aSFrançois Tigeot #define I915_GTT_PAGE_SIZE_4K BIT(12)
46*3f2dd94aSFrançois Tigeot #define I915_GTT_PAGE_SIZE_64K BIT(16)
47*3f2dd94aSFrançois Tigeot #define I915_GTT_PAGE_SIZE_2M BIT(21)
48*3f2dd94aSFrançois Tigeot
49*3f2dd94aSFrançois Tigeot #define I915_GTT_PAGE_SIZE I915_GTT_PAGE_SIZE_4K
50*3f2dd94aSFrançois Tigeot #define I915_GTT_MAX_PAGE_SIZE I915_GTT_PAGE_SIZE_2M
51*3f2dd94aSFrançois Tigeot
52a85cb24fSFrançois Tigeot #define I915_GTT_MIN_ALIGNMENT I915_GTT_PAGE_SIZE
5371f41f3eSFrançois Tigeot
541e12ee3bSFrançois Tigeot #define I915_FENCE_REG_NONE -1
551e12ee3bSFrançois Tigeot #define I915_MAX_NUM_FENCES 32
561e12ee3bSFrançois Tigeot /* 32 fences + sign bit for FENCE_REG_NONE */
571e12ee3bSFrançois Tigeot #define I915_MAX_NUM_FENCE_BITS 6
581e12ee3bSFrançois Tigeot
591b13d190SFrançois Tigeot struct drm_i915_file_private;
601e12ee3bSFrançois Tigeot struct drm_i915_fence_reg;
611b13d190SFrançois Tigeot
62a85cb24fSFrançois Tigeot typedef u32 gen6_pte_t;
63a85cb24fSFrançois Tigeot typedef u64 gen8_pte_t;
64a85cb24fSFrançois Tigeot typedef u64 gen8_pde_t;
65a85cb24fSFrançois Tigeot typedef u64 gen8_ppgtt_pdpe_t;
66a85cb24fSFrançois Tigeot typedef u64 gen8_ppgtt_pml4e_t;
67ba55f2f5SFrançois Tigeot
688621f407SFrançois Tigeot #define ggtt_total_entries(ggtt) ((ggtt)->base.total >> PAGE_SHIFT)
69ba55f2f5SFrançois Tigeot
70ba55f2f5SFrançois Tigeot /* gen6-hsw has bit 11-4 for physical addr bit 39-32 */
71ba55f2f5SFrançois Tigeot #define GEN6_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0xff0))
72ba55f2f5SFrançois Tigeot #define GEN6_PTE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr)
73ba55f2f5SFrançois Tigeot #define GEN6_PDE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr)
74ba55f2f5SFrançois Tigeot #define GEN6_PTE_CACHE_LLC (2 << 1)
75ba55f2f5SFrançois Tigeot #define GEN6_PTE_UNCACHED (1 << 1)
76ba55f2f5SFrançois Tigeot #define GEN6_PTE_VALID (1 << 0)
77ba55f2f5SFrançois Tigeot
78a85cb24fSFrançois Tigeot #define I915_PTES(pte_len) ((unsigned int)(PAGE_SIZE / (pte_len)))
79477eb7f9SFrançois Tigeot #define I915_PTE_MASK(pte_len) (I915_PTES(pte_len) - 1)
80477eb7f9SFrançois Tigeot #define I915_PDES 512
81477eb7f9SFrançois Tigeot #define I915_PDE_MASK (I915_PDES - 1)
82477eb7f9SFrançois Tigeot #define NUM_PTE(pde_shift) (1 << (pde_shift - PAGE_SHIFT))
83477eb7f9SFrançois Tigeot
84477eb7f9SFrançois Tigeot #define GEN6_PTES I915_PTES(sizeof(gen6_pte_t))
85477eb7f9SFrançois Tigeot #define GEN6_PD_SIZE (I915_PDES * PAGE_SIZE)
86ba55f2f5SFrançois Tigeot #define GEN6_PD_ALIGN (PAGE_SIZE * 16)
87477eb7f9SFrançois Tigeot #define GEN6_PDE_SHIFT 22
88ba55f2f5SFrançois Tigeot #define GEN6_PDE_VALID (1 << 0)
89ba55f2f5SFrançois Tigeot
90ba55f2f5SFrançois Tigeot #define GEN7_PTE_CACHE_L3_LLC (3 << 1)
91ba55f2f5SFrançois Tigeot
92ba55f2f5SFrançois Tigeot #define BYT_PTE_SNOOPED_BY_CPU_CACHES (1 << 2)
93ba55f2f5SFrançois Tigeot #define BYT_PTE_WRITEABLE (1 << 1)
94ba55f2f5SFrançois Tigeot
95ba55f2f5SFrançois Tigeot /* Cacheability Control is a 4-bit value. The low three bits are stored in bits
96ba55f2f5SFrançois Tigeot * 3:1 of the PTE, while the fourth bit is stored in bit 11 of the PTE.
97ba55f2f5SFrançois Tigeot */
98ba55f2f5SFrançois Tigeot #define HSW_CACHEABILITY_CONTROL(bits) ((((bits) & 0x7) << 1) | \
99ba55f2f5SFrançois Tigeot (((bits) & 0x8) << (11 - 3)))
100ba55f2f5SFrançois Tigeot #define HSW_WB_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x2)
101ba55f2f5SFrançois Tigeot #define HSW_WB_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x3)
102ba55f2f5SFrançois Tigeot #define HSW_WB_ELLC_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x8)
103ba55f2f5SFrançois Tigeot #define HSW_WB_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0xb)
104ba55f2f5SFrançois Tigeot #define HSW_WT_ELLC_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x7)
105ba55f2f5SFrançois Tigeot #define HSW_WT_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x6)
106ba55f2f5SFrançois Tigeot #define HSW_PTE_UNCACHED (0)
107ba55f2f5SFrançois Tigeot #define HSW_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0x7f0))
108ba55f2f5SFrançois Tigeot #define HSW_PTE_ADDR_ENCODE(addr) HSW_GTT_ADDR_ENCODE(addr)
109ba55f2f5SFrançois Tigeot
110a85cb24fSFrançois Tigeot /* GEN8 32b style address is defined as a 3 level page table:
111ba55f2f5SFrançois Tigeot * 31:30 | 29:21 | 20:12 | 11:0
112ba55f2f5SFrançois Tigeot * PDPE | PDE | PTE | offset
113ba55f2f5SFrançois Tigeot * The difference as compared to normal x86 3 level page table is the PDPEs are
114ba55f2f5SFrançois Tigeot * programmed via register.
115a85cb24fSFrançois Tigeot */
116a85cb24fSFrançois Tigeot #define GEN8_3LVL_PDPES 4
117a85cb24fSFrançois Tigeot #define GEN8_PDE_SHIFT 21
118a85cb24fSFrançois Tigeot #define GEN8_PDE_MASK 0x1ff
119a85cb24fSFrançois Tigeot #define GEN8_PTE_SHIFT 12
120a85cb24fSFrançois Tigeot #define GEN8_PTE_MASK 0x1ff
121a85cb24fSFrançois Tigeot #define GEN8_PTES I915_PTES(sizeof(gen8_pte_t))
122a85cb24fSFrançois Tigeot
123a85cb24fSFrançois Tigeot /* GEN8 48b style address is defined as a 4 level page table:
124352ff8bdSFrançois Tigeot * 47:39 | 38:30 | 29:21 | 20:12 | 11:0
125352ff8bdSFrançois Tigeot * PML4E | PDPE | PDE | PTE | offset
126ba55f2f5SFrançois Tigeot */
127352ff8bdSFrançois Tigeot #define GEN8_PML4ES_PER_PML4 512
128352ff8bdSFrançois Tigeot #define GEN8_PML4E_SHIFT 39
129352ff8bdSFrançois Tigeot #define GEN8_PML4E_MASK (GEN8_PML4ES_PER_PML4 - 1)
130ba55f2f5SFrançois Tigeot #define GEN8_PDPE_SHIFT 30
131352ff8bdSFrançois Tigeot /* NB: GEN8_PDPE_MASK is untrue for 32b platforms, but it has no impact on 32b page
132352ff8bdSFrançois Tigeot * tables */
133352ff8bdSFrançois Tigeot #define GEN8_PDPE_MASK 0x1ff
134352ff8bdSFrançois Tigeot
135*3f2dd94aSFrançois Tigeot #define PPAT_UNCACHED (_PAGE_PWT | _PAGE_PCD)
136*3f2dd94aSFrançois Tigeot #define PPAT_CACHED_PDE 0 /* WB LLC */
137*3f2dd94aSFrançois Tigeot #define PPAT_CACHED _PAGE_PAT /* WB LLCeLLC */
138*3f2dd94aSFrançois Tigeot #define PPAT_DISPLAY_ELLC _PAGE_PCD /* WT eLLC */
139ba55f2f5SFrançois Tigeot
140ba55f2f5SFrançois Tigeot #define CHV_PPAT_SNOOP (1<<6)
141*3f2dd94aSFrançois Tigeot #define GEN8_PPAT_AGE(x) ((x)<<4)
142ba55f2f5SFrançois Tigeot #define GEN8_PPAT_LLCeLLC (3<<2)
143ba55f2f5SFrançois Tigeot #define GEN8_PPAT_LLCELLC (2<<2)
144ba55f2f5SFrançois Tigeot #define GEN8_PPAT_LLC (1<<2)
145ba55f2f5SFrançois Tigeot #define GEN8_PPAT_WB (3<<0)
146ba55f2f5SFrançois Tigeot #define GEN8_PPAT_WT (2<<0)
147ba55f2f5SFrançois Tigeot #define GEN8_PPAT_WC (1<<0)
148ba55f2f5SFrançois Tigeot #define GEN8_PPAT_UC (0<<0)
149ba55f2f5SFrançois Tigeot #define GEN8_PPAT_ELLC_OVERRIDE (0<<2)
150a85cb24fSFrançois Tigeot #define GEN8_PPAT(i, x) ((u64)(x) << ((i) * 8))
151ba55f2f5SFrançois Tigeot
152*3f2dd94aSFrançois Tigeot #define GEN8_PPAT_GET_CA(x) ((x) & 3)
153*3f2dd94aSFrançois Tigeot #define GEN8_PPAT_GET_TC(x) ((x) & (3 << 2))
154*3f2dd94aSFrançois Tigeot #define GEN8_PPAT_GET_AGE(x) ((x) & (3 << 4))
155*3f2dd94aSFrançois Tigeot #define CHV_PPAT_GET_SNOOP(x) ((x) & (1 << 6))
156*3f2dd94aSFrançois Tigeot
157*3f2dd94aSFrançois Tigeot #define GEN8_PDE_IPS_64K BIT(11)
158*3f2dd94aSFrançois Tigeot #define GEN8_PDE_PS_2M BIT(7)
159*3f2dd94aSFrançois Tigeot
1604be47400SFrançois Tigeot struct sg_table;
1614be47400SFrançois Tigeot
162477eb7f9SFrançois Tigeot struct intel_rotation_info {
163a85cb24fSFrançois Tigeot struct intel_rotation_plane_info {
1648621f407SFrançois Tigeot /* tiles */
1651e12ee3bSFrançois Tigeot unsigned int width, height, stride, offset;
1668621f407SFrançois Tigeot } plane[2];
167a85cb24fSFrançois Tigeot } __packed;
168a85cb24fSFrançois Tigeot
assert_intel_rotation_info_is_packed(void)169a85cb24fSFrançois Tigeot static inline void assert_intel_rotation_info_is_packed(void)
170a85cb24fSFrançois Tigeot {
171a85cb24fSFrançois Tigeot BUILD_BUG_ON(sizeof(struct intel_rotation_info) != 8*sizeof(unsigned int));
172a85cb24fSFrançois Tigeot }
173a85cb24fSFrançois Tigeot
174a85cb24fSFrançois Tigeot struct intel_partial_info {
175a85cb24fSFrançois Tigeot u64 offset;
176a85cb24fSFrançois Tigeot unsigned int size;
177a85cb24fSFrançois Tigeot } __packed;
178a85cb24fSFrançois Tigeot
assert_intel_partial_info_is_packed(void)179a85cb24fSFrançois Tigeot static inline void assert_intel_partial_info_is_packed(void)
180a85cb24fSFrançois Tigeot {
181a85cb24fSFrançois Tigeot BUILD_BUG_ON(sizeof(struct intel_partial_info) != sizeof(u64) + sizeof(unsigned int));
182a85cb24fSFrançois Tigeot }
183a85cb24fSFrançois Tigeot
184a85cb24fSFrançois Tigeot enum i915_ggtt_view_type {
185a85cb24fSFrançois Tigeot I915_GGTT_VIEW_NORMAL = 0,
186a85cb24fSFrançois Tigeot I915_GGTT_VIEW_ROTATED = sizeof(struct intel_rotation_info),
187a85cb24fSFrançois Tigeot I915_GGTT_VIEW_PARTIAL = sizeof(struct intel_partial_info),
1882c9916cdSFrançois Tigeot };
1892c9916cdSFrançois Tigeot
assert_i915_ggtt_view_type_is_unique(void)190a85cb24fSFrançois Tigeot static inline void assert_i915_ggtt_view_type_is_unique(void)
191a85cb24fSFrançois Tigeot {
192a85cb24fSFrançois Tigeot /* As we encode the size of each branch inside the union into its type,
193a85cb24fSFrançois Tigeot * we have to be careful that each branch has a unique size.
194a85cb24fSFrançois Tigeot */
195a85cb24fSFrançois Tigeot switch ((enum i915_ggtt_view_type)0) {
196a85cb24fSFrançois Tigeot case I915_GGTT_VIEW_NORMAL:
197a85cb24fSFrançois Tigeot case I915_GGTT_VIEW_PARTIAL:
198a85cb24fSFrançois Tigeot case I915_GGTT_VIEW_ROTATED:
199a85cb24fSFrançois Tigeot /* gcc complains if these are identical cases */
200a85cb24fSFrançois Tigeot break;
201a85cb24fSFrançois Tigeot }
202a85cb24fSFrançois Tigeot }
203a85cb24fSFrançois Tigeot
2042c9916cdSFrançois Tigeot struct i915_ggtt_view {
2052c9916cdSFrançois Tigeot enum i915_ggtt_view_type type;
20619c468b4SFrançois Tigeot union {
207a85cb24fSFrançois Tigeot /* Members need to contain no holes/padding */
208a85cb24fSFrançois Tigeot struct intel_partial_info partial;
209c0e85e96SFrançois Tigeot struct intel_rotation_info rotated;
2102c9916cdSFrançois Tigeot };
211a85cb24fSFrançois Tigeot };
2122c9916cdSFrançois Tigeot
213ba55f2f5SFrançois Tigeot enum i915_cache_level;
2142c9916cdSFrançois Tigeot
2154be47400SFrançois Tigeot struct i915_vma;
2161e12ee3bSFrançois Tigeot
217a05eeebfSFrançois Tigeot struct i915_page_dma {
218f0bba3d1SFrançois Tigeot struct page *page;
219*3f2dd94aSFrançois Tigeot int order;
220a05eeebfSFrançois Tigeot union {
221477eb7f9SFrançois Tigeot dma_addr_t daddr;
222477eb7f9SFrançois Tigeot
223a05eeebfSFrançois Tigeot /* For gen6/gen7 only. This is the offset in the GGTT
224a05eeebfSFrançois Tigeot * where the page directory entries for PPGTT begin
225a05eeebfSFrançois Tigeot */
226a85cb24fSFrançois Tigeot u32 ggtt_offset;
227a05eeebfSFrançois Tigeot };
228a05eeebfSFrançois Tigeot };
229a05eeebfSFrançois Tigeot
230a05eeebfSFrançois Tigeot #define px_base(px) (&(px)->base)
231a05eeebfSFrançois Tigeot #define px_page(px) (px_base(px)->page)
232a05eeebfSFrançois Tigeot #define px_dma(px) (px_base(px)->daddr)
233a05eeebfSFrançois Tigeot
234a05eeebfSFrançois Tigeot struct i915_page_table {
235a05eeebfSFrançois Tigeot struct i915_page_dma base;
236a85cb24fSFrançois Tigeot unsigned int used_ptes;
237477eb7f9SFrançois Tigeot };
238477eb7f9SFrançois Tigeot
23919c468b4SFrançois Tigeot struct i915_page_directory {
240a05eeebfSFrançois Tigeot struct i915_page_dma base;
241477eb7f9SFrançois Tigeot
24219c468b4SFrançois Tigeot struct i915_page_table *page_table[I915_PDES]; /* PDEs */
243a85cb24fSFrançois Tigeot unsigned int used_pdes;
244477eb7f9SFrançois Tigeot };
245477eb7f9SFrançois Tigeot
24619c468b4SFrançois Tigeot struct i915_page_directory_pointer {
247352ff8bdSFrançois Tigeot struct i915_page_dma base;
248352ff8bdSFrançois Tigeot struct i915_page_directory **page_directory;
249a85cb24fSFrançois Tigeot unsigned int used_pdpes;
250352ff8bdSFrançois Tigeot };
251352ff8bdSFrançois Tigeot
252352ff8bdSFrançois Tigeot struct i915_pml4 {
253352ff8bdSFrançois Tigeot struct i915_page_dma base;
254352ff8bdSFrançois Tigeot struct i915_page_directory_pointer *pdps[GEN8_PML4ES_PER_PML4];
255477eb7f9SFrançois Tigeot };
256477eb7f9SFrançois Tigeot
257ba55f2f5SFrançois Tigeot struct i915_address_space {
258ba55f2f5SFrançois Tigeot struct drm_mm mm;
2594be47400SFrançois Tigeot struct i915_gem_timeline timeline;
260a85cb24fSFrançois Tigeot struct drm_i915_private *i915;
261a85cb24fSFrançois Tigeot struct device *dma;
26271f41f3eSFrançois Tigeot /* Every address space belongs to a struct file - except for the global
26371f41f3eSFrançois Tigeot * GTT that is owned by the driver (and so @file is set to NULL). In
26471f41f3eSFrançois Tigeot * principle, no information should leak from one context to another
26571f41f3eSFrançois Tigeot * (or between files/processes etc) unless explicitly shared by the
26671f41f3eSFrançois Tigeot * owner. Tracking the owner is important in order to free up per-file
26771f41f3eSFrançois Tigeot * objects along with the file, to aide resource tracking, and to
26871f41f3eSFrançois Tigeot * assign blame.
26971f41f3eSFrançois Tigeot */
27071f41f3eSFrançois Tigeot struct drm_i915_file_private *file;
271ba55f2f5SFrançois Tigeot struct list_head global_link;
272a05eeebfSFrançois Tigeot u64 total; /* size addr space maps (ex. 2GB for ggtt) */
273*3f2dd94aSFrançois Tigeot u64 reserved; /* size addr space reserved */
274ba55f2f5SFrançois Tigeot
27571f41f3eSFrançois Tigeot bool closed;
276c0e85e96SFrançois Tigeot
2771e12ee3bSFrançois Tigeot struct i915_page_dma scratch_page;
278a05eeebfSFrançois Tigeot struct i915_page_table *scratch_pt;
279a05eeebfSFrançois Tigeot struct i915_page_directory *scratch_pd;
280352ff8bdSFrançois Tigeot struct i915_page_directory_pointer *scratch_pdp; /* GEN8+ & 48b PPGTT */
281ba55f2f5SFrançois Tigeot
282ba55f2f5SFrançois Tigeot /**
283ba55f2f5SFrançois Tigeot * List of objects currently involved in rendering.
284ba55f2f5SFrançois Tigeot *
285ba55f2f5SFrançois Tigeot * Includes buffers having the contents of their GPU caches
2862c9916cdSFrançois Tigeot * flushed, not necessarily primitives. last_read_req
287ba55f2f5SFrançois Tigeot * represents when the rendering involved will be completed.
288ba55f2f5SFrançois Tigeot *
289ba55f2f5SFrançois Tigeot * A reference is held on the buffer while on this list.
290ba55f2f5SFrançois Tigeot */
291ba55f2f5SFrançois Tigeot struct list_head active_list;
292ba55f2f5SFrançois Tigeot
293ba55f2f5SFrançois Tigeot /**
294ba55f2f5SFrançois Tigeot * LRU list of objects which are not in the ringbuffer and
295ba55f2f5SFrançois Tigeot * are ready to unbind, but are still in the GTT.
296ba55f2f5SFrançois Tigeot *
2972c9916cdSFrançois Tigeot * last_read_req is NULL while an object is in this list.
298ba55f2f5SFrançois Tigeot *
299ba55f2f5SFrançois Tigeot * A reference is not held on the buffer while on this list,
300ba55f2f5SFrançois Tigeot * as merely being GTT-bound shouldn't prevent its being
301ba55f2f5SFrançois Tigeot * freed, and we'll pull it off the list in the free path.
302ba55f2f5SFrançois Tigeot */
303ba55f2f5SFrançois Tigeot struct list_head inactive_list;
304ba55f2f5SFrançois Tigeot
30571f41f3eSFrançois Tigeot /**
30671f41f3eSFrançois Tigeot * List of vma that have been unbound.
30771f41f3eSFrançois Tigeot *
30871f41f3eSFrançois Tigeot * A reference is not held on the buffer while on this list.
30971f41f3eSFrançois Tigeot */
31071f41f3eSFrançois Tigeot struct list_head unbound_list;
31171f41f3eSFrançois Tigeot
312a85cb24fSFrançois Tigeot struct pagevec free_pages;
313a85cb24fSFrançois Tigeot bool pt_kmap_wc;
314a85cb24fSFrançois Tigeot
315ba55f2f5SFrançois Tigeot /* FIXME: Need a more generic return type */
316477eb7f9SFrançois Tigeot gen6_pte_t (*pte_encode)(dma_addr_t addr,
317ba55f2f5SFrançois Tigeot enum i915_cache_level level,
3181e12ee3bSFrançois Tigeot u32 flags); /* Create a valid PTE */
31919c468b4SFrançois Tigeot /* flags for pte_encode */
32019c468b4SFrançois Tigeot #define PTE_READ_ONLY (1<<0)
321477eb7f9SFrançois Tigeot int (*allocate_va_range)(struct i915_address_space *vm,
322a85cb24fSFrançois Tigeot u64 start, u64 length);
323ba55f2f5SFrançois Tigeot void (*clear_range)(struct i915_address_space *vm,
324a85cb24fSFrançois Tigeot u64 start, u64 length);
3251487f786SFrançois Tigeot void (*insert_page)(struct i915_address_space *vm,
3261487f786SFrançois Tigeot dma_addr_t addr,
327a85cb24fSFrançois Tigeot u64 offset,
3281487f786SFrançois Tigeot enum i915_cache_level cache_level,
3291487f786SFrançois Tigeot u32 flags);
330ba55f2f5SFrançois Tigeot void (*insert_entries)(struct i915_address_space *vm,
331*3f2dd94aSFrançois Tigeot struct i915_vma *vma,
332a85cb24fSFrançois Tigeot enum i915_cache_level cache_level,
333a85cb24fSFrançois Tigeot u32 flags);
334ba55f2f5SFrançois Tigeot void (*cleanup)(struct i915_address_space *vm);
33519c468b4SFrançois Tigeot /** Unmap an object from an address space. This usually consists of
33619c468b4SFrançois Tigeot * setting the valid PTE entries to a reserved scratch page. */
33719c468b4SFrançois Tigeot void (*unbind_vma)(struct i915_vma *vma);
33819c468b4SFrançois Tigeot /* Map an object into an address space with the given cache flags. */
33919c468b4SFrançois Tigeot int (*bind_vma)(struct i915_vma *vma,
34019c468b4SFrançois Tigeot enum i915_cache_level cache_level,
34119c468b4SFrançois Tigeot u32 flags);
342*3f2dd94aSFrançois Tigeot int (*set_pages)(struct i915_vma *vma);
343*3f2dd94aSFrançois Tigeot void (*clear_pages)(struct i915_vma *vma);
344a85cb24fSFrançois Tigeot
345a85cb24fSFrançois Tigeot I915_SELFTEST_DECLARE(struct fault_attr fault_attr);
346ba55f2f5SFrançois Tigeot };
347ba55f2f5SFrançois Tigeot
34871f41f3eSFrançois Tigeot #define i915_is_ggtt(V) (!(V)->file)
349c0e85e96SFrançois Tigeot
350a85cb24fSFrançois Tigeot static inline bool
i915_vm_is_48bit(const struct i915_address_space * vm)351a85cb24fSFrançois Tigeot i915_vm_is_48bit(const struct i915_address_space *vm)
352a85cb24fSFrançois Tigeot {
353a85cb24fSFrançois Tigeot return (vm->total - 1) >> 32;
354a85cb24fSFrançois Tigeot }
355a85cb24fSFrançois Tigeot
356*3f2dd94aSFrançois Tigeot static inline bool
i915_vm_has_scratch_64K(struct i915_address_space * vm)357*3f2dd94aSFrançois Tigeot i915_vm_has_scratch_64K(struct i915_address_space *vm)
358*3f2dd94aSFrançois Tigeot {
359*3f2dd94aSFrançois Tigeot return vm->scratch_page.order == get_order(I915_GTT_PAGE_SIZE_64K);
360*3f2dd94aSFrançois Tigeot }
361*3f2dd94aSFrançois Tigeot
362ba55f2f5SFrançois Tigeot /* The Graphics Translation Table is the way in which GEN hardware translates a
363ba55f2f5SFrançois Tigeot * Graphics Virtual Address into a Physical Address. In addition to the normal
364ba55f2f5SFrançois Tigeot * collateral associated with any va->pa translations GEN hardware also has a
365ba55f2f5SFrançois Tigeot * portion of the GTT which can be mapped by the CPU and remain both coherent
366ba55f2f5SFrançois Tigeot * and correct (in cases like swizzling). That region is referred to as GMADR in
367ba55f2f5SFrançois Tigeot * the spec.
368ba55f2f5SFrançois Tigeot */
3698621f407SFrançois Tigeot struct i915_ggtt {
370ba55f2f5SFrançois Tigeot struct i915_address_space base;
3711e12ee3bSFrançois Tigeot struct io_mapping mappable; /* Mapping to our CPU mappable region */
372ba55f2f5SFrançois Tigeot
373ba55f2f5SFrançois Tigeot phys_addr_t mappable_base; /* PA of our GMADR */
374a85cb24fSFrançois Tigeot u64 mappable_end; /* End offset that we can CPU map */
375a85cb24fSFrançois Tigeot
376a85cb24fSFrançois Tigeot /* Stolen memory is segmented in hardware with different portions
377a85cb24fSFrançois Tigeot * offlimits to certain functions.
378a85cb24fSFrançois Tigeot *
379a85cb24fSFrançois Tigeot * The drm_mm is initialised to the total accessible range, as found
380a85cb24fSFrançois Tigeot * from the PCI config. On Broadwell+, this is further restricted to
381a85cb24fSFrançois Tigeot * avoid the first page! The upper end of stolen memory is reserved for
382a85cb24fSFrançois Tigeot * hardware functions and similarly removed from the accessible range.
383a85cb24fSFrançois Tigeot */
384a85cb24fSFrançois Tigeot u32 stolen_size; /* Total size of stolen memory */
385a85cb24fSFrançois Tigeot u32 stolen_usable_size; /* Total size minus reserved ranges */
386a85cb24fSFrançois Tigeot u32 stolen_reserved_base;
387a85cb24fSFrançois Tigeot u32 stolen_reserved_size;
388ba55f2f5SFrançois Tigeot
389ba55f2f5SFrançois Tigeot /** "Graphics Stolen Memory" holds the global PTEs */
390ba55f2f5SFrançois Tigeot void __iomem *gsm;
391a85cb24fSFrançois Tigeot void (*invalidate)(struct drm_i915_private *dev_priv);
392ba55f2f5SFrançois Tigeot
393ba55f2f5SFrançois Tigeot bool do_idle_maps;
394ba55f2f5SFrançois Tigeot
395ba55f2f5SFrançois Tigeot int mtrr;
3961e12ee3bSFrançois Tigeot
3971e12ee3bSFrançois Tigeot struct drm_mm_node error_capture;
398ba55f2f5SFrançois Tigeot };
399ba55f2f5SFrançois Tigeot
400ba55f2f5SFrançois Tigeot struct i915_hw_ppgtt {
401ba55f2f5SFrançois Tigeot struct i915_address_space base;
402ba55f2f5SFrançois Tigeot struct kref ref;
403ba55f2f5SFrançois Tigeot struct drm_mm_node node;
404477eb7f9SFrançois Tigeot unsigned long pd_dirty_rings;
405ba55f2f5SFrançois Tigeot union {
406352ff8bdSFrançois Tigeot struct i915_pml4 pml4; /* GEN8+ & 48b PPGTT */
407352ff8bdSFrançois Tigeot struct i915_page_directory_pointer pdp; /* GEN8+ */
408352ff8bdSFrançois Tigeot struct i915_page_directory pd; /* GEN6-7 */
409ba55f2f5SFrançois Tigeot };
410ba55f2f5SFrançois Tigeot
411477eb7f9SFrançois Tigeot gen6_pte_t __iomem *pd_addr;
412477eb7f9SFrançois Tigeot
413ba55f2f5SFrançois Tigeot int (*switch_mm)(struct i915_hw_ppgtt *ppgtt,
414a05eeebfSFrançois Tigeot struct drm_i915_gem_request *req);
415ba55f2f5SFrançois Tigeot void (*debug_dump)(struct i915_hw_ppgtt *ppgtt, struct seq_file *m);
416ba55f2f5SFrançois Tigeot };
417ba55f2f5SFrançois Tigeot
4181487f786SFrançois Tigeot /*
4191487f786SFrançois Tigeot * gen6_for_each_pde() iterates over every pde from start until start+length.
4201487f786SFrançois Tigeot * If start and start+length are not perfectly divisible, the macro will round
4211487f786SFrançois Tigeot * down and up as needed. Start=0 and length=2G effectively iterates over
4221487f786SFrançois Tigeot * every PDE in the system. The macro modifies ALL its parameters except 'pd',
4231487f786SFrançois Tigeot * so each of the other parameters should preferably be a simple variable, or
4241487f786SFrançois Tigeot * at most an lvalue with no side-effects!
425477eb7f9SFrançois Tigeot */
4261487f786SFrançois Tigeot #define gen6_for_each_pde(pt, pd, start, length, iter) \
427477eb7f9SFrançois Tigeot for (iter = gen6_pde_index(start); \
4281487f786SFrançois Tigeot length > 0 && iter < I915_PDES && \
4291487f786SFrançois Tigeot (pt = (pd)->page_table[iter], true); \
4301487f786SFrançois Tigeot ({ u32 temp = ALIGN(start+1, 1 << GEN6_PDE_SHIFT); \
4311487f786SFrançois Tigeot temp = min(temp - start, length); \
4321487f786SFrançois Tigeot start += temp, length -= temp; }), ++iter)
433477eb7f9SFrançois Tigeot
4341487f786SFrançois Tigeot #define gen6_for_all_pdes(pt, pd, iter) \
43519c468b4SFrançois Tigeot for (iter = 0; \
4361487f786SFrançois Tigeot iter < I915_PDES && \
4371487f786SFrançois Tigeot (pt = (pd)->page_table[iter], true); \
4381487f786SFrançois Tigeot ++iter)
43919c468b4SFrançois Tigeot
i915_pte_index(u64 address,unsigned int pde_shift)440a85cb24fSFrançois Tigeot static inline u32 i915_pte_index(u64 address, unsigned int pde_shift)
441477eb7f9SFrançois Tigeot {
442a85cb24fSFrançois Tigeot const u32 mask = NUM_PTE(pde_shift) - 1;
443477eb7f9SFrançois Tigeot
444477eb7f9SFrançois Tigeot return (address >> PAGE_SHIFT) & mask;
445477eb7f9SFrançois Tigeot }
446477eb7f9SFrançois Tigeot
447477eb7f9SFrançois Tigeot /* Helper to counts the number of PTEs within the given length. This count
448477eb7f9SFrançois Tigeot * does not cross a page table boundary, so the max value would be
449477eb7f9SFrançois Tigeot * GEN6_PTES for GEN6, and GEN8_PTES for GEN8.
450477eb7f9SFrançois Tigeot */
i915_pte_count(u64 addr,u64 length,unsigned int pde_shift)451a85cb24fSFrançois Tigeot static inline u32 i915_pte_count(u64 addr, u64 length, unsigned int pde_shift)
452477eb7f9SFrançois Tigeot {
453a85cb24fSFrançois Tigeot const u64 mask = ~((1ULL << pde_shift) - 1);
454a85cb24fSFrançois Tigeot u64 end;
455477eb7f9SFrançois Tigeot
456477eb7f9SFrançois Tigeot WARN_ON(length == 0);
457477eb7f9SFrançois Tigeot WARN_ON(offset_in_page(addr|length));
458477eb7f9SFrançois Tigeot
459477eb7f9SFrançois Tigeot end = addr + length;
460477eb7f9SFrançois Tigeot
461477eb7f9SFrançois Tigeot if ((addr & mask) != (end & mask))
462477eb7f9SFrançois Tigeot return NUM_PTE(pde_shift) - i915_pte_index(addr, pde_shift);
463477eb7f9SFrançois Tigeot
464477eb7f9SFrançois Tigeot return i915_pte_index(end, pde_shift) - i915_pte_index(addr, pde_shift);
465477eb7f9SFrançois Tigeot }
466477eb7f9SFrançois Tigeot
i915_pde_index(u64 addr,u32 shift)467a85cb24fSFrançois Tigeot static inline u32 i915_pde_index(u64 addr, u32 shift)
468477eb7f9SFrançois Tigeot {
469477eb7f9SFrançois Tigeot return (addr >> shift) & I915_PDE_MASK;
470477eb7f9SFrançois Tigeot }
471477eb7f9SFrançois Tigeot
gen6_pte_index(u32 addr)472a85cb24fSFrançois Tigeot static inline u32 gen6_pte_index(u32 addr)
473477eb7f9SFrançois Tigeot {
474477eb7f9SFrançois Tigeot return i915_pte_index(addr, GEN6_PDE_SHIFT);
475477eb7f9SFrançois Tigeot }
476477eb7f9SFrançois Tigeot
gen6_pte_count(u32 addr,u32 length)477a85cb24fSFrançois Tigeot static inline u32 gen6_pte_count(u32 addr, u32 length)
478477eb7f9SFrançois Tigeot {
479477eb7f9SFrançois Tigeot return i915_pte_count(addr, length, GEN6_PDE_SHIFT);
480477eb7f9SFrançois Tigeot }
481477eb7f9SFrançois Tigeot
gen6_pde_index(u32 addr)482a85cb24fSFrançois Tigeot static inline u32 gen6_pde_index(u32 addr)
483477eb7f9SFrançois Tigeot {
484477eb7f9SFrançois Tigeot return i915_pde_index(addr, GEN6_PDE_SHIFT);
485477eb7f9SFrançois Tigeot }
486477eb7f9SFrançois Tigeot
487a85cb24fSFrançois Tigeot static inline unsigned int
i915_pdpes_per_pdp(const struct i915_address_space * vm)488a85cb24fSFrançois Tigeot i915_pdpes_per_pdp(const struct i915_address_space *vm)
489a85cb24fSFrançois Tigeot {
490a85cb24fSFrançois Tigeot if (i915_vm_is_48bit(vm))
491a85cb24fSFrançois Tigeot return GEN8_PML4ES_PER_PML4;
492a85cb24fSFrançois Tigeot
493a85cb24fSFrançois Tigeot return GEN8_3LVL_PDPES;
494a85cb24fSFrançois Tigeot }
495a85cb24fSFrançois Tigeot
49619c468b4SFrançois Tigeot /* Equivalent to the gen6 version, For each pde iterates over every pde
49719c468b4SFrançois Tigeot * between from start until start + length. On gen8+ it simply iterates
49819c468b4SFrançois Tigeot * over every page directory entry in a page directory.
49919c468b4SFrançois Tigeot */
500aee94f86SFrançois Tigeot #define gen8_for_each_pde(pt, pd, start, length, iter) \
50119c468b4SFrançois Tigeot for (iter = gen8_pde_index(start); \
502aee94f86SFrançois Tigeot length > 0 && iter < I915_PDES && \
503aee94f86SFrançois Tigeot (pt = (pd)->page_table[iter], true); \
504aee94f86SFrançois Tigeot ({ u64 temp = ALIGN(start+1, 1 << GEN8_PDE_SHIFT); \
505aee94f86SFrançois Tigeot temp = min(temp - start, length); \
506aee94f86SFrançois Tigeot start += temp, length -= temp; }), ++iter)
50719c468b4SFrançois Tigeot
508aee94f86SFrançois Tigeot #define gen8_for_each_pdpe(pd, pdp, start, length, iter) \
50919c468b4SFrançois Tigeot for (iter = gen8_pdpe_index(start); \
510a85cb24fSFrançois Tigeot length > 0 && iter < i915_pdpes_per_pdp(vm) && \
511aee94f86SFrançois Tigeot (pd = (pdp)->page_directory[iter], true); \
512aee94f86SFrançois Tigeot ({ u64 temp = ALIGN(start+1, 1 << GEN8_PDPE_SHIFT); \
513aee94f86SFrançois Tigeot temp = min(temp - start, length); \
514aee94f86SFrançois Tigeot start += temp, length -= temp; }), ++iter)
51519c468b4SFrançois Tigeot
516aee94f86SFrançois Tigeot #define gen8_for_each_pml4e(pdp, pml4, start, length, iter) \
517352ff8bdSFrançois Tigeot for (iter = gen8_pml4e_index(start); \
518aee94f86SFrançois Tigeot length > 0 && iter < GEN8_PML4ES_PER_PML4 && \
519aee94f86SFrançois Tigeot (pdp = (pml4)->pdps[iter], true); \
520aee94f86SFrançois Tigeot ({ u64 temp = ALIGN(start+1, 1ULL << GEN8_PML4E_SHIFT); \
521aee94f86SFrançois Tigeot temp = min(temp - start, length); \
522aee94f86SFrançois Tigeot start += temp, length -= temp; }), ++iter)
52319c468b4SFrançois Tigeot
gen8_pte_index(u64 address)524a85cb24fSFrançois Tigeot static inline u32 gen8_pte_index(u64 address)
52519c468b4SFrançois Tigeot {
52619c468b4SFrançois Tigeot return i915_pte_index(address, GEN8_PDE_SHIFT);
52719c468b4SFrançois Tigeot }
52819c468b4SFrançois Tigeot
gen8_pde_index(u64 address)529a85cb24fSFrançois Tigeot static inline u32 gen8_pde_index(u64 address)
53019c468b4SFrançois Tigeot {
53119c468b4SFrançois Tigeot return i915_pde_index(address, GEN8_PDE_SHIFT);
53219c468b4SFrançois Tigeot }
53319c468b4SFrançois Tigeot
gen8_pdpe_index(u64 address)534a85cb24fSFrançois Tigeot static inline u32 gen8_pdpe_index(u64 address)
53519c468b4SFrançois Tigeot {
53619c468b4SFrançois Tigeot return (address >> GEN8_PDPE_SHIFT) & GEN8_PDPE_MASK;
53719c468b4SFrançois Tigeot }
53819c468b4SFrançois Tigeot
gen8_pml4e_index(u64 address)539a85cb24fSFrançois Tigeot static inline u32 gen8_pml4e_index(u64 address)
54019c468b4SFrançois Tigeot {
541352ff8bdSFrançois Tigeot return (address >> GEN8_PML4E_SHIFT) & GEN8_PML4E_MASK;
54219c468b4SFrançois Tigeot }
54319c468b4SFrançois Tigeot
gen8_pte_count(u64 address,u64 length)544a85cb24fSFrançois Tigeot static inline u64 gen8_pte_count(u64 address, u64 length)
54519c468b4SFrançois Tigeot {
54619c468b4SFrançois Tigeot return i915_pte_count(address, length, GEN8_PDE_SHIFT);
54719c468b4SFrançois Tigeot }
54819c468b4SFrançois Tigeot
549a05eeebfSFrançois Tigeot static inline dma_addr_t
i915_page_dir_dma_addr(const struct i915_hw_ppgtt * ppgtt,const unsigned n)5501e12ee3bSFrançois Tigeot i915_page_dir_dma_addr(const struct i915_hw_ppgtt *ppgtt, const unsigned n)
551a05eeebfSFrançois Tigeot {
552a85cb24fSFrançois Tigeot return px_dma(ppgtt->pdp.page_directory[n]);
553a05eeebfSFrançois Tigeot }
554a05eeebfSFrançois Tigeot
5554be47400SFrançois Tigeot static inline struct i915_ggtt *
i915_vm_to_ggtt(struct i915_address_space * vm)5564be47400SFrançois Tigeot i915_vm_to_ggtt(struct i915_address_space *vm)
5574be47400SFrançois Tigeot {
5584be47400SFrançois Tigeot GEM_BUG_ON(!i915_is_ggtt(vm));
5594be47400SFrançois Tigeot return container_of(vm, struct i915_ggtt, base);
5604be47400SFrançois Tigeot }
5614be47400SFrançois Tigeot
562*3f2dd94aSFrançois Tigeot #define INTEL_MAX_PPAT_ENTRIES 8
563*3f2dd94aSFrançois Tigeot #define INTEL_PPAT_PERFECT_MATCH (~0U)
564*3f2dd94aSFrançois Tigeot
565*3f2dd94aSFrançois Tigeot struct intel_ppat;
566*3f2dd94aSFrançois Tigeot
567*3f2dd94aSFrançois Tigeot struct intel_ppat_entry {
568*3f2dd94aSFrançois Tigeot struct intel_ppat *ppat;
569*3f2dd94aSFrançois Tigeot struct kref ref;
570*3f2dd94aSFrançois Tigeot u8 value;
571*3f2dd94aSFrançois Tigeot };
572*3f2dd94aSFrançois Tigeot
573*3f2dd94aSFrançois Tigeot struct intel_ppat {
574*3f2dd94aSFrançois Tigeot struct intel_ppat_entry entries[INTEL_MAX_PPAT_ENTRIES];
575*3f2dd94aSFrançois Tigeot DECLARE_BITMAP(used, INTEL_MAX_PPAT_ENTRIES);
576*3f2dd94aSFrançois Tigeot DECLARE_BITMAP(dirty, INTEL_MAX_PPAT_ENTRIES);
577*3f2dd94aSFrançois Tigeot unsigned int max_entries;
578*3f2dd94aSFrançois Tigeot u8 clear_value;
579*3f2dd94aSFrançois Tigeot /*
580*3f2dd94aSFrançois Tigeot * Return a score to show how two PPAT values match,
581*3f2dd94aSFrançois Tigeot * a INTEL_PPAT_PERFECT_MATCH indicates a perfect match
582*3f2dd94aSFrançois Tigeot */
583*3f2dd94aSFrançois Tigeot unsigned int (*match)(u8 src, u8 dst);
584*3f2dd94aSFrançois Tigeot void (*update_hw)(struct drm_i915_private *i915);
585*3f2dd94aSFrançois Tigeot
586*3f2dd94aSFrançois Tigeot struct drm_i915_private *i915;
587*3f2dd94aSFrançois Tigeot };
588*3f2dd94aSFrançois Tigeot
589*3f2dd94aSFrançois Tigeot const struct intel_ppat_entry *
590*3f2dd94aSFrançois Tigeot intel_ppat_get(struct drm_i915_private *i915, u8 value);
591*3f2dd94aSFrançois Tigeot void intel_ppat_put(const struct intel_ppat_entry *entry);
592*3f2dd94aSFrançois Tigeot
593a85cb24fSFrançois Tigeot int i915_gem_init_aliasing_ppgtt(struct drm_i915_private *i915);
594a85cb24fSFrançois Tigeot void i915_gem_fini_aliasing_ppgtt(struct drm_i915_private *i915);
595a85cb24fSFrançois Tigeot
59671f41f3eSFrançois Tigeot int i915_ggtt_probe_hw(struct drm_i915_private *dev_priv);
59771f41f3eSFrançois Tigeot int i915_ggtt_init_hw(struct drm_i915_private *dev_priv);
59871f41f3eSFrançois Tigeot int i915_ggtt_enable_hw(struct drm_i915_private *dev_priv);
599a85cb24fSFrançois Tigeot void i915_ggtt_enable_guc(struct drm_i915_private *i915);
600a85cb24fSFrançois Tigeot void i915_ggtt_disable_guc(struct drm_i915_private *i915);
60171f41f3eSFrançois Tigeot int i915_gem_init_ggtt(struct drm_i915_private *dev_priv);
60271f41f3eSFrançois Tigeot void i915_ggtt_cleanup_hw(struct drm_i915_private *dev_priv);
6031b13d190SFrançois Tigeot
6044be47400SFrançois Tigeot int i915_ppgtt_init_hw(struct drm_i915_private *dev_priv);
6051b13d190SFrançois Tigeot void i915_ppgtt_release(struct kref *kref);
60671f41f3eSFrançois Tigeot struct i915_hw_ppgtt *i915_ppgtt_create(struct drm_i915_private *dev_priv,
6074be47400SFrançois Tigeot struct drm_i915_file_private *fpriv,
6084be47400SFrançois Tigeot const char *name);
609a85cb24fSFrançois Tigeot void i915_ppgtt_close(struct i915_address_space *vm);
i915_ppgtt_get(struct i915_hw_ppgtt * ppgtt)6101b13d190SFrançois Tigeot static inline void i915_ppgtt_get(struct i915_hw_ppgtt *ppgtt)
6111b13d190SFrançois Tigeot {
6121b13d190SFrançois Tigeot if (ppgtt)
6131b13d190SFrançois Tigeot kref_get(&ppgtt->ref);
6141b13d190SFrançois Tigeot }
i915_ppgtt_put(struct i915_hw_ppgtt * ppgtt)6151b13d190SFrançois Tigeot static inline void i915_ppgtt_put(struct i915_hw_ppgtt *ppgtt)
6161b13d190SFrançois Tigeot {
6171b13d190SFrançois Tigeot if (ppgtt)
6181b13d190SFrançois Tigeot kref_put(&ppgtt->ref, i915_ppgtt_release);
6191b13d190SFrançois Tigeot }
620ba55f2f5SFrançois Tigeot
6211487f786SFrançois Tigeot void i915_check_and_clear_faults(struct drm_i915_private *dev_priv);
6224be47400SFrançois Tigeot void i915_gem_suspend_gtt_mappings(struct drm_i915_private *dev_priv);
6234be47400SFrançois Tigeot void i915_gem_restore_gtt_mappings(struct drm_i915_private *dev_priv);
624ba55f2f5SFrançois Tigeot
6254be47400SFrançois Tigeot int __must_check i915_gem_gtt_prepare_pages(struct drm_i915_gem_object *obj,
6264be47400SFrançois Tigeot struct sg_table *pages);
6274be47400SFrançois Tigeot void i915_gem_gtt_finish_pages(struct drm_i915_gem_object *obj,
6284be47400SFrançois Tigeot struct sg_table *pages);
629ba55f2f5SFrançois Tigeot
630a85cb24fSFrançois Tigeot int i915_gem_gtt_reserve(struct i915_address_space *vm,
631a85cb24fSFrançois Tigeot struct drm_mm_node *node,
632a85cb24fSFrançois Tigeot u64 size, u64 offset, unsigned long color,
633a85cb24fSFrançois Tigeot unsigned int flags);
634a85cb24fSFrançois Tigeot
635a85cb24fSFrançois Tigeot int i915_gem_gtt_insert(struct i915_address_space *vm,
636a85cb24fSFrançois Tigeot struct drm_mm_node *node,
637a85cb24fSFrançois Tigeot u64 size, u64 alignment, unsigned long color,
638a85cb24fSFrançois Tigeot u64 start, u64 end, unsigned int flags);
639a85cb24fSFrançois Tigeot
64071f41f3eSFrançois Tigeot /* Flags used by pin/bind&friends. */
64171f41f3eSFrançois Tigeot #define PIN_NONBLOCK BIT(0)
64271f41f3eSFrançois Tigeot #define PIN_MAPPABLE BIT(1)
64371f41f3eSFrançois Tigeot #define PIN_ZONE_4G BIT(2)
6441e12ee3bSFrançois Tigeot #define PIN_NONFAULT BIT(3)
645*3f2dd94aSFrançois Tigeot #define PIN_NOEVICT BIT(4)
64671f41f3eSFrançois Tigeot
64771f41f3eSFrançois Tigeot #define PIN_MBZ BIT(5) /* I915_VMA_PIN_OVERFLOW */
64871f41f3eSFrançois Tigeot #define PIN_GLOBAL BIT(6) /* I915_VMA_GLOBAL_BIND */
64971f41f3eSFrançois Tigeot #define PIN_USER BIT(7) /* I915_VMA_LOCAL_BIND */
65071f41f3eSFrançois Tigeot #define PIN_UPDATE BIT(8)
65171f41f3eSFrançois Tigeot
65271f41f3eSFrançois Tigeot #define PIN_HIGH BIT(9)
65371f41f3eSFrançois Tigeot #define PIN_OFFSET_BIAS BIT(10)
65471f41f3eSFrançois Tigeot #define PIN_OFFSET_FIXED BIT(11)
655a85cb24fSFrançois Tigeot #define PIN_OFFSET_MASK (-I915_GTT_PAGE_SIZE)
65671f41f3eSFrançois Tigeot
657ba55f2f5SFrançois Tigeot #endif
658