xref: /dflybsd-src/sys/dev/drm/i915/i915_gem_gtt.h (revision 3f2dd94a569761201b5b0a18b2f697f97fe1b9dc)
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