1c349dbc7Sjsg /* SPDX-License-Identifier: MIT */ 2c349dbc7Sjsg /* 3c349dbc7Sjsg * Copyright © 2020 Intel Corporation 4c349dbc7Sjsg * 5c349dbc7Sjsg * Please try to maintain the following order within this file unless it makes 6c349dbc7Sjsg * sense to do otherwise. From top to bottom: 7c349dbc7Sjsg * 1. typedefs 8c349dbc7Sjsg * 2. #defines, and macros 9c349dbc7Sjsg * 3. structure definitions 10c349dbc7Sjsg * 4. function prototypes 11c349dbc7Sjsg * 12c349dbc7Sjsg * Within each section, please try to order by generation in ascending order, 13c349dbc7Sjsg * from top to bottom (ie. gen6 on the top, gen8 on the bottom). 14c349dbc7Sjsg */ 15c349dbc7Sjsg 16c349dbc7Sjsg #ifndef __INTEL_GTT_H__ 17c349dbc7Sjsg #define __INTEL_GTT_H__ 18c349dbc7Sjsg 19c349dbc7Sjsg #include <linux/io-mapping.h> 20c349dbc7Sjsg #include <linux/kref.h> 21c349dbc7Sjsg #include <linux/mm.h> 22c349dbc7Sjsg #include <linux/pagevec.h> 23c349dbc7Sjsg #include <linux/scatterlist.h> 24c349dbc7Sjsg #include <linux/workqueue.h> 25c349dbc7Sjsg 26c349dbc7Sjsg #include <drm/drm_mm.h> 27c349dbc7Sjsg 28c349dbc7Sjsg #include "gt/intel_reset.h" 29c349dbc7Sjsg #include "i915_selftest.h" 301bb76ff1Sjsg #include "i915_vma_resource.h" 31c349dbc7Sjsg #include "i915_vma_types.h" 321bb76ff1Sjsg #include "i915_params.h" 331bb76ff1Sjsg #include "intel_memory_region.h" 34c349dbc7Sjsg 35c349dbc7Sjsg #define I915_GFP_ALLOW_FAIL (GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN) 36c349dbc7Sjsg 37c349dbc7Sjsg #if IS_ENABLED(CONFIG_DRM_I915_TRACE_GTT) 38c349dbc7Sjsg #define DBG(...) trace_printk(__VA_ARGS__) 39c349dbc7Sjsg #else 40c349dbc7Sjsg #define DBG(...) 41c349dbc7Sjsg #endif 42c349dbc7Sjsg 43c349dbc7Sjsg #define NALLOC 3 /* 1 normal, 1 for concurrent threads, 1 for preallocation */ 44c349dbc7Sjsg 45c349dbc7Sjsg #define I915_GTT_PAGE_SIZE_4K BIT_ULL(12) 46c349dbc7Sjsg #define I915_GTT_PAGE_SIZE_64K BIT_ULL(16) 47c349dbc7Sjsg #define I915_GTT_PAGE_SIZE_2M BIT_ULL(21) 48c349dbc7Sjsg 49c349dbc7Sjsg #define I915_GTT_PAGE_SIZE I915_GTT_PAGE_SIZE_4K 50c349dbc7Sjsg #define I915_GTT_MAX_PAGE_SIZE I915_GTT_PAGE_SIZE_2M 51c349dbc7Sjsg 52c349dbc7Sjsg #define I915_GTT_PAGE_MASK -I915_GTT_PAGE_SIZE 53c349dbc7Sjsg 54c349dbc7Sjsg #define I915_GTT_MIN_ALIGNMENT I915_GTT_PAGE_SIZE 55c349dbc7Sjsg 56c349dbc7Sjsg #define I915_FENCE_REG_NONE -1 57c349dbc7Sjsg #define I915_MAX_NUM_FENCES 32 58c349dbc7Sjsg /* 32 fences + sign bit for FENCE_REG_NONE */ 59c349dbc7Sjsg #define I915_MAX_NUM_FENCE_BITS 6 60c349dbc7Sjsg 61c349dbc7Sjsg typedef u32 gen6_pte_t; 62c349dbc7Sjsg typedef u64 gen8_pte_t; 63c349dbc7Sjsg 64c349dbc7Sjsg #define ggtt_total_entries(ggtt) ((ggtt)->vm.total >> PAGE_SHIFT) 65c349dbc7Sjsg 66c349dbc7Sjsg #define I915_PTES(pte_len) ((unsigned int)(PAGE_SIZE / (pte_len))) 67c349dbc7Sjsg #define I915_PTE_MASK(pte_len) (I915_PTES(pte_len) - 1) 68c349dbc7Sjsg #define I915_PDES 512 69c349dbc7Sjsg #define I915_PDE_MASK (I915_PDES - 1) 70c349dbc7Sjsg 71c349dbc7Sjsg /* gen6-hsw has bit 11-4 for physical addr bit 39-32 */ 72c349dbc7Sjsg #define GEN6_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0xff0)) 73c349dbc7Sjsg #define GEN6_PTE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) 74c349dbc7Sjsg #define GEN6_PDE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) 75c349dbc7Sjsg #define GEN6_PTE_CACHE_LLC (2 << 1) 76c349dbc7Sjsg #define GEN6_PTE_UNCACHED (1 << 1) 77c349dbc7Sjsg #define GEN6_PTE_VALID REG_BIT(0) 78c349dbc7Sjsg 79c349dbc7Sjsg #define GEN6_PTES I915_PTES(sizeof(gen6_pte_t)) 80c349dbc7Sjsg #define GEN6_PD_SIZE (I915_PDES * PAGE_SIZE) 81c349dbc7Sjsg #define GEN6_PD_ALIGN (PAGE_SIZE * 16) 82c349dbc7Sjsg #define GEN6_PDE_SHIFT 22 83c349dbc7Sjsg #define GEN6_PDE_VALID REG_BIT(0) 84c349dbc7Sjsg #define NUM_PTE(pde_shift) (1 << (pde_shift - PAGE_SHIFT)) 85c349dbc7Sjsg 86c349dbc7Sjsg #define GEN7_PTE_CACHE_L3_LLC (3 << 1) 87c349dbc7Sjsg 88c349dbc7Sjsg #define BYT_PTE_SNOOPED_BY_CPU_CACHES REG_BIT(2) 89c349dbc7Sjsg #define BYT_PTE_WRITEABLE REG_BIT(1) 90c349dbc7Sjsg 91f005ef32Sjsg #define MTL_PPGTT_PTE_PAT3 BIT_ULL(62) 925ca02815Sjsg #define GEN12_PPGTT_PTE_LM BIT_ULL(11) 93f005ef32Sjsg #define GEN12_PPGTT_PTE_PAT2 BIT_ULL(7) 94f005ef32Sjsg #define GEN12_PPGTT_PTE_PAT1 BIT_ULL(4) 95f005ef32Sjsg #define GEN12_PPGTT_PTE_PAT0 BIT_ULL(3) 965ca02815Sjsg 975ca02815Sjsg #define GEN12_GGTT_PTE_LM BIT_ULL(1) 98f005ef32Sjsg #define MTL_GGTT_PTE_PAT0 BIT_ULL(52) 99f005ef32Sjsg #define MTL_GGTT_PTE_PAT1 BIT_ULL(53) 100f005ef32Sjsg #define GEN12_GGTT_PTE_ADDR_MASK GENMASK_ULL(45, 12) 101f005ef32Sjsg #define MTL_GGTT_PTE_PAT_MASK GENMASK_ULL(53, 52) 1025ca02815Sjsg 1031bb76ff1Sjsg #define GEN12_PDE_64K BIT(6) 104f005ef32Sjsg #define GEN12_PTE_PS64 BIT(8) 1051bb76ff1Sjsg 106c349dbc7Sjsg /* 107c349dbc7Sjsg * Cacheability Control is a 4-bit value. The low three bits are stored in bits 108c349dbc7Sjsg * 3:1 of the PTE, while the fourth bit is stored in bit 11 of the PTE. 109c349dbc7Sjsg */ 110c349dbc7Sjsg #define HSW_CACHEABILITY_CONTROL(bits) ((((bits) & 0x7) << 1) | \ 111c349dbc7Sjsg (((bits) & 0x8) << (11 - 3))) 112c349dbc7Sjsg #define HSW_WB_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x2) 113c349dbc7Sjsg #define HSW_WB_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x3) 114c349dbc7Sjsg #define HSW_WB_ELLC_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x8) 115c349dbc7Sjsg #define HSW_WB_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0xb) 116c349dbc7Sjsg #define HSW_WT_ELLC_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x7) 117c349dbc7Sjsg #define HSW_WT_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x6) 118c349dbc7Sjsg #define HSW_PTE_UNCACHED (0) 119c349dbc7Sjsg #define HSW_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0x7f0)) 120c349dbc7Sjsg #define HSW_PTE_ADDR_ENCODE(addr) HSW_GTT_ADDR_ENCODE(addr) 121c349dbc7Sjsg 122c349dbc7Sjsg /* 123c349dbc7Sjsg * GEN8 32b style address is defined as a 3 level page table: 124c349dbc7Sjsg * 31:30 | 29:21 | 20:12 | 11:0 125c349dbc7Sjsg * PDPE | PDE | PTE | offset 126c349dbc7Sjsg * The difference as compared to normal x86 3 level page table is the PDPEs are 127c349dbc7Sjsg * programmed via register. 128c349dbc7Sjsg * 129c349dbc7Sjsg * GEN8 48b style address is defined as a 4 level page table: 130c349dbc7Sjsg * 47:39 | 38:30 | 29:21 | 20:12 | 11:0 131c349dbc7Sjsg * PML4E | PDPE | PDE | PTE | offset 132c349dbc7Sjsg */ 133c349dbc7Sjsg #define GEN8_3LVL_PDPES 4 134c349dbc7Sjsg 135c349dbc7Sjsg #define PPAT_UNCACHED (_PAGE_PWT | _PAGE_PCD) 136c349dbc7Sjsg #define PPAT_CACHED_PDE 0 /* WB LLC */ 137c349dbc7Sjsg #define PPAT_CACHED _PAGE_PAT /* WB LLCeLLC */ 138c349dbc7Sjsg #define PPAT_DISPLAY_ELLC _PAGE_PCD /* WT eLLC */ 139c349dbc7Sjsg 140c349dbc7Sjsg #define CHV_PPAT_SNOOP REG_BIT(6) 141c349dbc7Sjsg #define GEN8_PPAT_AGE(x) ((x)<<4) 142c349dbc7Sjsg #define GEN8_PPAT_LLCeLLC (3<<2) 143c349dbc7Sjsg #define GEN8_PPAT_LLCELLC (2<<2) 144c349dbc7Sjsg #define GEN8_PPAT_LLC (1<<2) 145c349dbc7Sjsg #define GEN8_PPAT_WB (3<<0) 146c349dbc7Sjsg #define GEN8_PPAT_WT (2<<0) 147c349dbc7Sjsg #define GEN8_PPAT_WC (1<<0) 148c349dbc7Sjsg #define GEN8_PPAT_UC (0<<0) 149c349dbc7Sjsg #define GEN8_PPAT_ELLC_OVERRIDE (0<<2) 150c349dbc7Sjsg #define GEN8_PPAT(i, x) ((u64)(x) << ((i) * 8)) 151c349dbc7Sjsg 1521bb76ff1Sjsg #define GEN8_PAGE_PRESENT BIT_ULL(0) 1531bb76ff1Sjsg #define GEN8_PAGE_RW BIT_ULL(1) 1541bb76ff1Sjsg 155c349dbc7Sjsg #define GEN8_PDE_IPS_64K BIT(11) 156c349dbc7Sjsg #define GEN8_PDE_PS_2M BIT(7) 157c349dbc7Sjsg 158f005ef32Sjsg #define MTL_PPAT_L4_CACHE_POLICY_MASK REG_GENMASK(3, 2) 159f005ef32Sjsg #define MTL_PAT_INDEX_COH_MODE_MASK REG_GENMASK(1, 0) 160f005ef32Sjsg #define MTL_PPAT_L4_3_UC REG_FIELD_PREP(MTL_PPAT_L4_CACHE_POLICY_MASK, 3) 161f005ef32Sjsg #define MTL_PPAT_L4_1_WT REG_FIELD_PREP(MTL_PPAT_L4_CACHE_POLICY_MASK, 1) 162f005ef32Sjsg #define MTL_PPAT_L4_0_WB REG_FIELD_PREP(MTL_PPAT_L4_CACHE_POLICY_MASK, 0) 163f005ef32Sjsg #define MTL_3_COH_2W REG_FIELD_PREP(MTL_PAT_INDEX_COH_MODE_MASK, 3) 164f005ef32Sjsg #define MTL_2_COH_1W REG_FIELD_PREP(MTL_PAT_INDEX_COH_MODE_MASK, 2) 165ad8b1aafSjsg 166ad8b1aafSjsg struct drm_i915_gem_object; 167ad8b1aafSjsg struct i915_fence_reg; 168ad8b1aafSjsg struct i915_vma; 169ad8b1aafSjsg struct intel_gt; 170ad8b1aafSjsg 171c349dbc7Sjsg #define for_each_sgt_daddr(__dp, __iter, __sgt) \ 172c349dbc7Sjsg __for_each_sgt_daddr(__dp, __iter, __sgt, I915_GTT_PAGE_SIZE) 173c349dbc7Sjsg 174c6b3c815Sjsg #define for_each_sgt_daddr_next(__dp, __iter) \ 175c6b3c815Sjsg __for_each_daddr_next(__dp, __iter, I915_GTT_PAGE_SIZE) 176c6b3c815Sjsg 177c349dbc7Sjsg struct i915_page_table { 178ad8b1aafSjsg struct drm_i915_gem_object *base; 179ad8b1aafSjsg union { 180c349dbc7Sjsg atomic_t used; 181ad8b1aafSjsg struct i915_page_table *stash; 182ad8b1aafSjsg }; 1831bb76ff1Sjsg bool is_compact; 184c349dbc7Sjsg }; 185c349dbc7Sjsg 186c349dbc7Sjsg struct i915_page_directory { 187c349dbc7Sjsg struct i915_page_table pt; 188c349dbc7Sjsg spinlock_t lock; 189ad8b1aafSjsg void **entry; 190c349dbc7Sjsg }; 191c349dbc7Sjsg 192c349dbc7Sjsg #define __px_choose_expr(x, type, expr, other) \ 193c349dbc7Sjsg __builtin_choose_expr( \ 194c349dbc7Sjsg __builtin_types_compatible_p(typeof(x), type) || \ 195c349dbc7Sjsg __builtin_types_compatible_p(typeof(x), const type), \ 196c349dbc7Sjsg ({ type __x = (type)(x); expr; }), \ 197c349dbc7Sjsg other) 198c349dbc7Sjsg 199c349dbc7Sjsg #define px_base(px) \ 200ad8b1aafSjsg __px_choose_expr(px, struct drm_i915_gem_object *, __x, \ 201ad8b1aafSjsg __px_choose_expr(px, struct i915_page_table *, __x->base, \ 202ad8b1aafSjsg __px_choose_expr(px, struct i915_page_directory *, __x->pt.base, \ 203ad8b1aafSjsg (void)0))) 204ad8b1aafSjsg 205ad8b1aafSjsg struct vm_page *__px_page(struct drm_i915_gem_object *p); 206ad8b1aafSjsg dma_addr_t __px_dma(struct drm_i915_gem_object *p); 207ad8b1aafSjsg #define px_dma(px) (__px_dma(px_base(px))) 208c349dbc7Sjsg 2095ca02815Sjsg void *__px_vaddr(struct drm_i915_gem_object *p); 2105ca02815Sjsg #define px_vaddr(px) (__px_vaddr(px_base(px))) 2115ca02815Sjsg 212c349dbc7Sjsg #define px_pt(px) \ 213c349dbc7Sjsg __px_choose_expr(px, struct i915_page_table *, __x, \ 214c349dbc7Sjsg __px_choose_expr(px, struct i915_page_directory *, &__x->pt, \ 215c349dbc7Sjsg (void)0)) 216c349dbc7Sjsg #define px_used(px) (&px_pt(px)->used) 217c349dbc7Sjsg 218ad8b1aafSjsg struct i915_vm_pt_stash { 219ad8b1aafSjsg /* preallocated chains of page tables/directories */ 220ad8b1aafSjsg struct i915_page_table *pt[2]; 2211bb76ff1Sjsg /* 2221bb76ff1Sjsg * Optionally override the alignment/size of the physical page that 2231bb76ff1Sjsg * contains each PT. If not set defaults back to the usual 2241bb76ff1Sjsg * I915_GTT_PAGE_SIZE_4K. This does not influence the other paging 2251bb76ff1Sjsg * structures. MUST be a power-of-two. ONLY applicable on discrete 2261bb76ff1Sjsg * platforms. 2271bb76ff1Sjsg */ 2281bb76ff1Sjsg int pt_sz; 229ad8b1aafSjsg }; 230c349dbc7Sjsg 231c349dbc7Sjsg struct i915_vma_ops { 232c349dbc7Sjsg /* Map an object into an address space with the given cache flags. */ 233ad8b1aafSjsg void (*bind_vma)(struct i915_address_space *vm, 234ad8b1aafSjsg struct i915_vm_pt_stash *stash, 2351bb76ff1Sjsg struct i915_vma_resource *vma_res, 236f005ef32Sjsg unsigned int pat_index, 237c349dbc7Sjsg u32 flags); 238c349dbc7Sjsg /* 239c349dbc7Sjsg * Unmap an object from an address space. This usually consists of 240c349dbc7Sjsg * setting the valid PTE entries to a reserved scratch page. 241c349dbc7Sjsg */ 242ad8b1aafSjsg void (*unbind_vma)(struct i915_address_space *vm, 2431bb76ff1Sjsg struct i915_vma_resource *vma_res); 244c349dbc7Sjsg 245c349dbc7Sjsg }; 246c349dbc7Sjsg 247c349dbc7Sjsg struct i915_address_space { 248c349dbc7Sjsg struct kref ref; 2491bb76ff1Sjsg struct work_struct release_work; 250c349dbc7Sjsg 251c349dbc7Sjsg struct drm_mm mm; 252c349dbc7Sjsg struct intel_gt *gt; 253c349dbc7Sjsg struct drm_i915_private *i915; 254c349dbc7Sjsg struct device *dma; 255c349dbc7Sjsg u64 total; /* size addr space maps (ex. 2GB for ggtt) */ 256c349dbc7Sjsg u64 reserved; /* size addr space reserved */ 2571bb76ff1Sjsg u64 min_alignment[INTEL_MEMORY_STOLEN_LOCAL + 1]; 258c349dbc7Sjsg 259c349dbc7Sjsg unsigned int bind_async_flags; 260c349dbc7Sjsg 261c349dbc7Sjsg struct rwlock mutex; /* protects vma and our lists */ 2625ca02815Sjsg 2635ca02815Sjsg struct kref resv_ref; /* kref to keep the reservation lock alive. */ 2645ca02815Sjsg struct dma_resv _resv; /* reservation lock for all pd objects, and buffer pool */ 265c349dbc7Sjsg #define VM_CLASS_GGTT 0 266c349dbc7Sjsg #define VM_CLASS_PPGTT 1 2675ca02815Sjsg #define VM_CLASS_DPT 2 268c349dbc7Sjsg 269ad8b1aafSjsg struct drm_i915_gem_object *scratch[4]; 270c349dbc7Sjsg /** 271c349dbc7Sjsg * List of vma currently bound. 272c349dbc7Sjsg */ 273c349dbc7Sjsg struct list_head bound_list; 274c349dbc7Sjsg 2751bb76ff1Sjsg /** 2761bb76ff1Sjsg * List of vmas not yet bound or evicted. 2771bb76ff1Sjsg */ 2781bb76ff1Sjsg struct list_head unbound_list; 2791bb76ff1Sjsg 280c349dbc7Sjsg /* Global GTT */ 281c349dbc7Sjsg bool is_ggtt:1; 282c349dbc7Sjsg 2835ca02815Sjsg /* Display page table */ 2845ca02815Sjsg bool is_dpt:1; 2855ca02815Sjsg 286c349dbc7Sjsg /* Some systems support read-only mappings for GGTT and/or PPGTT */ 287c349dbc7Sjsg bool has_read_only:1; 288c349dbc7Sjsg 2891bb76ff1Sjsg /* Skip pte rewrite on unbind for suspend. Protected by @mutex */ 2901bb76ff1Sjsg bool skip_pte_rewrite:1; 2911bb76ff1Sjsg 292ad8b1aafSjsg u8 top; 293ad8b1aafSjsg u8 pd_shift; 294ad8b1aafSjsg u8 scratch_order; 295ad8b1aafSjsg 2961bb76ff1Sjsg /* Flags used when creating page-table objects for this vm */ 2971bb76ff1Sjsg unsigned long lmem_pt_obj_flags; 2981bb76ff1Sjsg 2991bb76ff1Sjsg /* Interval tree for pending unbind vma resources */ 3001bb76ff1Sjsg struct rb_root_cached pending_unbind; 3011bb76ff1Sjsg 302ad8b1aafSjsg struct drm_i915_gem_object * 303ad8b1aafSjsg (*alloc_pt_dma)(struct i915_address_space *vm, int sz); 3041bb76ff1Sjsg struct drm_i915_gem_object * 3051bb76ff1Sjsg (*alloc_scratch_dma)(struct i915_address_space *vm, int sz); 306ad8b1aafSjsg 307c349dbc7Sjsg u64 (*pte_encode)(dma_addr_t addr, 308f005ef32Sjsg unsigned int pat_index, 309c349dbc7Sjsg u32 flags); /* Create a valid PTE */ 310c349dbc7Sjsg #define PTE_READ_ONLY BIT(0) 3115ca02815Sjsg #define PTE_LM BIT(1) 312c349dbc7Sjsg 313ad8b1aafSjsg void (*allocate_va_range)(struct i915_address_space *vm, 314ad8b1aafSjsg struct i915_vm_pt_stash *stash, 315c349dbc7Sjsg u64 start, u64 length); 316c349dbc7Sjsg void (*clear_range)(struct i915_address_space *vm, 317c349dbc7Sjsg u64 start, u64 length); 318f005ef32Sjsg void (*scratch_range)(struct i915_address_space *vm, 319f005ef32Sjsg u64 start, u64 length); 320c349dbc7Sjsg void (*insert_page)(struct i915_address_space *vm, 321c349dbc7Sjsg dma_addr_t addr, 322c349dbc7Sjsg u64 offset, 323f005ef32Sjsg unsigned int pat_index, 324c349dbc7Sjsg u32 flags); 325c349dbc7Sjsg void (*insert_entries)(struct i915_address_space *vm, 3261bb76ff1Sjsg struct i915_vma_resource *vma_res, 327f005ef32Sjsg unsigned int pat_index, 3281bb76ff1Sjsg u32 flags); 3291bb76ff1Sjsg void (*raw_insert_page)(struct i915_address_space *vm, 3301bb76ff1Sjsg dma_addr_t addr, 3311bb76ff1Sjsg u64 offset, 332f005ef32Sjsg unsigned int pat_index, 3331bb76ff1Sjsg u32 flags); 3341bb76ff1Sjsg void (*raw_insert_entries)(struct i915_address_space *vm, 3351bb76ff1Sjsg struct i915_vma_resource *vma_res, 336f005ef32Sjsg unsigned int pat_index, 337c349dbc7Sjsg u32 flags); 338c349dbc7Sjsg void (*cleanup)(struct i915_address_space *vm); 339c349dbc7Sjsg 3405ca02815Sjsg void (*foreach)(struct i915_address_space *vm, 3415ca02815Sjsg u64 start, u64 length, 3425ca02815Sjsg void (*fn)(struct i915_address_space *vm, 3435ca02815Sjsg struct i915_page_table *pt, 3445ca02815Sjsg void *data), 3455ca02815Sjsg void *data); 3465ca02815Sjsg 347c349dbc7Sjsg struct i915_vma_ops vma_ops; 348c349dbc7Sjsg 349c349dbc7Sjsg I915_SELFTEST_DECLARE(struct fault_attr fault_attr); 350c349dbc7Sjsg I915_SELFTEST_DECLARE(bool scrub_64K); 351c349dbc7Sjsg }; 352c349dbc7Sjsg 353c349dbc7Sjsg /* 354c349dbc7Sjsg * The Graphics Translation Table is the way in which GEN hardware translates a 355c349dbc7Sjsg * Graphics Virtual Address into a Physical Address. In addition to the normal 356c349dbc7Sjsg * collateral associated with any va->pa translations GEN hardware also has a 357c349dbc7Sjsg * portion of the GTT which can be mapped by the CPU and remain both coherent 358c349dbc7Sjsg * and correct (in cases like swizzling). That region is referred to as GMADR in 359c349dbc7Sjsg * the spec. 360c349dbc7Sjsg */ 361c349dbc7Sjsg struct i915_ggtt { 362c349dbc7Sjsg struct i915_address_space vm; 363c349dbc7Sjsg 364c349dbc7Sjsg struct io_mapping iomap; /* Mapping to our CPU mappable region */ 365c349dbc7Sjsg struct resource gmadr; /* GMADR resource */ 366c349dbc7Sjsg resource_size_t mappable_end; /* End offset that we can CPU map */ 367c349dbc7Sjsg 368c349dbc7Sjsg /** "Graphics Stolen Memory" holds the global PTEs */ 369c349dbc7Sjsg void __iomem *gsm; 370c349dbc7Sjsg bus_space_handle_t gsm_bsh; 371c349dbc7Sjsg bus_size_t gsm_size; 372c349dbc7Sjsg void (*invalidate)(struct i915_ggtt *ggtt); 373c349dbc7Sjsg 374c349dbc7Sjsg /** PPGTT used for aliasing the PPGTT with the GTT */ 375c349dbc7Sjsg struct i915_ppgtt *alias; 376c349dbc7Sjsg 377c349dbc7Sjsg bool do_idle_maps; 378c349dbc7Sjsg 379c349dbc7Sjsg int mtrr; 380c349dbc7Sjsg 381c349dbc7Sjsg /** Bit 6 swizzling required for X tiling */ 382c349dbc7Sjsg u32 bit_6_swizzle_x; 383c349dbc7Sjsg /** Bit 6 swizzling required for Y tiling */ 384c349dbc7Sjsg u32 bit_6_swizzle_y; 385c349dbc7Sjsg 386c349dbc7Sjsg u32 pin_bias; 387c349dbc7Sjsg 388c349dbc7Sjsg unsigned int num_fences; 389ad8b1aafSjsg struct i915_fence_reg *fence_regs; 390c349dbc7Sjsg struct list_head fence_list; 391c349dbc7Sjsg 392c349dbc7Sjsg /** 393c349dbc7Sjsg * List of all objects in gtt_space, currently mmaped by userspace. 394c349dbc7Sjsg * All objects within this list must also be on bound_list. 395c349dbc7Sjsg */ 396c349dbc7Sjsg struct list_head userfault_list; 397c349dbc7Sjsg 398c349dbc7Sjsg struct rwlock error_mutex; 399c349dbc7Sjsg struct drm_mm_node error_capture; 400c349dbc7Sjsg struct drm_mm_node uc_fw; 401f005ef32Sjsg 402f005ef32Sjsg /** List of GTs mapping this GGTT */ 403f005ef32Sjsg struct list_head gt_list; 404c349dbc7Sjsg }; 405c349dbc7Sjsg 406c349dbc7Sjsg struct i915_ppgtt { 407c349dbc7Sjsg struct i915_address_space vm; 408c349dbc7Sjsg 409c349dbc7Sjsg struct i915_page_directory *pd; 410c349dbc7Sjsg }; 411c349dbc7Sjsg 412c349dbc7Sjsg #define i915_is_ggtt(vm) ((vm)->is_ggtt) 4135ca02815Sjsg #define i915_is_dpt(vm) ((vm)->is_dpt) 4145ca02815Sjsg #define i915_is_ggtt_or_dpt(vm) (i915_is_ggtt(vm) || i915_is_dpt(vm)) 4155ca02815Sjsg 4161bb76ff1Sjsg bool intel_vm_no_concurrent_access_wa(struct drm_i915_private *i915); 4171bb76ff1Sjsg 4185ca02815Sjsg int __must_check 4195ca02815Sjsg i915_vm_lock_objects(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww); 420c349dbc7Sjsg 421c349dbc7Sjsg static inline bool 422c349dbc7Sjsg i915_vm_is_4lvl(const struct i915_address_space *vm) 423c349dbc7Sjsg { 424c349dbc7Sjsg return (vm->total - 1) >> 32; 425c349dbc7Sjsg } 426c349dbc7Sjsg 427c349dbc7Sjsg static inline bool 428c349dbc7Sjsg i915_vm_has_scratch_64K(struct i915_address_space *vm) 429c349dbc7Sjsg { 430c349dbc7Sjsg return vm->scratch_order == get_order(I915_GTT_PAGE_SIZE_64K); 431c349dbc7Sjsg } 432c349dbc7Sjsg 4331bb76ff1Sjsg static inline u64 i915_vm_min_alignment(struct i915_address_space *vm, 4341bb76ff1Sjsg enum intel_memory_type type) 4351bb76ff1Sjsg { 4361bb76ff1Sjsg /* avoid INTEL_MEMORY_MOCK overflow */ 4371bb76ff1Sjsg if ((int)type >= ARRAY_SIZE(vm->min_alignment)) 4381bb76ff1Sjsg type = INTEL_MEMORY_SYSTEM; 4391bb76ff1Sjsg 4401bb76ff1Sjsg return vm->min_alignment[type]; 4411bb76ff1Sjsg } 4421bb76ff1Sjsg 4431bb76ff1Sjsg static inline u64 i915_vm_obj_min_alignment(struct i915_address_space *vm, 4441bb76ff1Sjsg struct drm_i915_gem_object *obj) 4451bb76ff1Sjsg { 4461bb76ff1Sjsg struct intel_memory_region *mr = READ_ONCE(obj->mm.region); 4471bb76ff1Sjsg enum intel_memory_type type = mr ? mr->type : INTEL_MEMORY_SYSTEM; 4481bb76ff1Sjsg 4491bb76ff1Sjsg return i915_vm_min_alignment(vm, type); 4501bb76ff1Sjsg } 4511bb76ff1Sjsg 452c349dbc7Sjsg static inline bool 453c349dbc7Sjsg i915_vm_has_cache_coloring(struct i915_address_space *vm) 454c349dbc7Sjsg { 455c349dbc7Sjsg return i915_is_ggtt(vm) && vm->mm.color_adjust; 456c349dbc7Sjsg } 457c349dbc7Sjsg 458c349dbc7Sjsg static inline struct i915_ggtt * 459c349dbc7Sjsg i915_vm_to_ggtt(struct i915_address_space *vm) 460c349dbc7Sjsg { 461c349dbc7Sjsg BUILD_BUG_ON(offsetof(struct i915_ggtt, vm)); 462c349dbc7Sjsg GEM_BUG_ON(!i915_is_ggtt(vm)); 463c349dbc7Sjsg return container_of(vm, struct i915_ggtt, vm); 464c349dbc7Sjsg } 465c349dbc7Sjsg 466c349dbc7Sjsg static inline struct i915_ppgtt * 467c349dbc7Sjsg i915_vm_to_ppgtt(struct i915_address_space *vm) 468c349dbc7Sjsg { 469c349dbc7Sjsg BUILD_BUG_ON(offsetof(struct i915_ppgtt, vm)); 4705ca02815Sjsg GEM_BUG_ON(i915_is_ggtt_or_dpt(vm)); 471c349dbc7Sjsg return container_of(vm, struct i915_ppgtt, vm); 472c349dbc7Sjsg } 473c349dbc7Sjsg 474c349dbc7Sjsg static inline struct i915_address_space * 475c349dbc7Sjsg i915_vm_get(struct i915_address_space *vm) 476c349dbc7Sjsg { 477c349dbc7Sjsg kref_get(&vm->ref); 478c349dbc7Sjsg return vm; 479c349dbc7Sjsg } 480c349dbc7Sjsg 4811bb76ff1Sjsg static inline struct i915_address_space * 4821bb76ff1Sjsg i915_vm_tryget(struct i915_address_space *vm) 4831bb76ff1Sjsg { 4841bb76ff1Sjsg return kref_get_unless_zero(&vm->ref) ? vm : NULL; 4851bb76ff1Sjsg } 4861bb76ff1Sjsg 4871bb76ff1Sjsg static inline void assert_vm_alive(struct i915_address_space *vm) 4881bb76ff1Sjsg { 4891bb76ff1Sjsg GEM_BUG_ON(!kref_read(&vm->ref)); 4901bb76ff1Sjsg } 4911bb76ff1Sjsg 4925ca02815Sjsg /** 4935ca02815Sjsg * i915_vm_resv_get - Obtain a reference on the vm's reservation lock 4945ca02815Sjsg * @vm: The vm whose reservation lock we want to share. 4955ca02815Sjsg * 4965ca02815Sjsg * Return: A pointer to the vm's reservation lock. 4975ca02815Sjsg */ 4985ca02815Sjsg static inline struct dma_resv *i915_vm_resv_get(struct i915_address_space *vm) 4995ca02815Sjsg { 5005ca02815Sjsg kref_get(&vm->resv_ref); 5015ca02815Sjsg return &vm->_resv; 5025ca02815Sjsg } 5035ca02815Sjsg 504c349dbc7Sjsg void i915_vm_release(struct kref *kref); 505c349dbc7Sjsg 5065ca02815Sjsg void i915_vm_resv_release(struct kref *kref); 5075ca02815Sjsg 508c349dbc7Sjsg static inline void i915_vm_put(struct i915_address_space *vm) 509c349dbc7Sjsg { 510c349dbc7Sjsg kref_put(&vm->ref, i915_vm_release); 511c349dbc7Sjsg } 512c349dbc7Sjsg 5135ca02815Sjsg /** 5145ca02815Sjsg * i915_vm_resv_put - Release a reference on the vm's reservation lock 515f005ef32Sjsg * @vm: The vm whose reservation lock reference we want to release 5165ca02815Sjsg */ 5175ca02815Sjsg static inline void i915_vm_resv_put(struct i915_address_space *vm) 5185ca02815Sjsg { 5195ca02815Sjsg kref_put(&vm->resv_ref, i915_vm_resv_release); 5205ca02815Sjsg } 5215ca02815Sjsg 522c349dbc7Sjsg void i915_address_space_init(struct i915_address_space *vm, int subclass); 523c349dbc7Sjsg void i915_address_space_fini(struct i915_address_space *vm); 524c349dbc7Sjsg 525c349dbc7Sjsg static inline u32 i915_pte_index(u64 address, unsigned int pde_shift) 526c349dbc7Sjsg { 527c349dbc7Sjsg const u32 mask = NUM_PTE(pde_shift) - 1; 528c349dbc7Sjsg 529c349dbc7Sjsg return (address >> PAGE_SHIFT) & mask; 530c349dbc7Sjsg } 531c349dbc7Sjsg 532c349dbc7Sjsg /* 533c349dbc7Sjsg * Helper to counts the number of PTEs within the given length. This count 534c349dbc7Sjsg * does not cross a page table boundary, so the max value would be 535c349dbc7Sjsg * GEN6_PTES for GEN6, and GEN8_PTES for GEN8. 536c349dbc7Sjsg */ 537c349dbc7Sjsg static inline u32 i915_pte_count(u64 addr, u64 length, unsigned int pde_shift) 538c349dbc7Sjsg { 539c349dbc7Sjsg const u64 mask = ~((1ULL << pde_shift) - 1); 540c349dbc7Sjsg u64 end; 541c349dbc7Sjsg 542c349dbc7Sjsg GEM_BUG_ON(length == 0); 543c349dbc7Sjsg GEM_BUG_ON(offset_in_page(addr | length)); 544c349dbc7Sjsg 545c349dbc7Sjsg end = addr + length; 546c349dbc7Sjsg 547c349dbc7Sjsg if ((addr & mask) != (end & mask)) 548c349dbc7Sjsg return NUM_PTE(pde_shift) - i915_pte_index(addr, pde_shift); 549c349dbc7Sjsg 550c349dbc7Sjsg return i915_pte_index(end, pde_shift) - i915_pte_index(addr, pde_shift); 551c349dbc7Sjsg } 552c349dbc7Sjsg 553c349dbc7Sjsg static inline u32 i915_pde_index(u64 addr, u32 shift) 554c349dbc7Sjsg { 555c349dbc7Sjsg return (addr >> shift) & I915_PDE_MASK; 556c349dbc7Sjsg } 557c349dbc7Sjsg 558c349dbc7Sjsg static inline struct i915_page_table * 559c349dbc7Sjsg i915_pt_entry(const struct i915_page_directory * const pd, 560c349dbc7Sjsg const unsigned short n) 561c349dbc7Sjsg { 562c349dbc7Sjsg return pd->entry[n]; 563c349dbc7Sjsg } 564c349dbc7Sjsg 565c349dbc7Sjsg static inline struct i915_page_directory * 566c349dbc7Sjsg i915_pd_entry(const struct i915_page_directory * const pdp, 567c349dbc7Sjsg const unsigned short n) 568c349dbc7Sjsg { 569c349dbc7Sjsg return pdp->entry[n]; 570c349dbc7Sjsg } 571c349dbc7Sjsg 572c349dbc7Sjsg static inline dma_addr_t 573c349dbc7Sjsg i915_page_dir_dma_addr(const struct i915_ppgtt *ppgtt, const unsigned int n) 574c349dbc7Sjsg { 575ad8b1aafSjsg struct i915_page_table *pt = ppgtt->pd->entry[n]; 576c349dbc7Sjsg 577ad8b1aafSjsg return __px_dma(pt ? px_base(pt) : ppgtt->vm.scratch[ppgtt->vm.top]); 578c349dbc7Sjsg } 579c349dbc7Sjsg 5801bb76ff1Sjsg void ppgtt_init(struct i915_ppgtt *ppgtt, struct intel_gt *gt, 5811bb76ff1Sjsg unsigned long lmem_pt_obj_flags); 5821bb76ff1Sjsg void intel_ggtt_bind_vma(struct i915_address_space *vm, 5831bb76ff1Sjsg struct i915_vm_pt_stash *stash, 5841bb76ff1Sjsg struct i915_vma_resource *vma_res, 585f005ef32Sjsg unsigned int pat_index, 5861bb76ff1Sjsg u32 flags); 5871bb76ff1Sjsg void intel_ggtt_unbind_vma(struct i915_address_space *vm, 5881bb76ff1Sjsg struct i915_vma_resource *vma_res); 589c349dbc7Sjsg 590c349dbc7Sjsg int i915_ggtt_probe_hw(struct drm_i915_private *i915); 591c349dbc7Sjsg int i915_ggtt_init_hw(struct drm_i915_private *i915); 592c349dbc7Sjsg int i915_ggtt_enable_hw(struct drm_i915_private *i915); 593c349dbc7Sjsg int i915_init_ggtt(struct drm_i915_private *i915); 594c349dbc7Sjsg void i915_ggtt_driver_release(struct drm_i915_private *i915); 5955ca02815Sjsg void i915_ggtt_driver_late_release(struct drm_i915_private *i915); 596f005ef32Sjsg struct i915_ggtt *i915_ggtt_create(struct drm_i915_private *i915); 597c349dbc7Sjsg 598c349dbc7Sjsg static inline bool i915_ggtt_has_aperture(const struct i915_ggtt *ggtt) 599c349dbc7Sjsg { 600c349dbc7Sjsg return ggtt->mappable_end > 0; 601c349dbc7Sjsg } 602c349dbc7Sjsg 603c349dbc7Sjsg int i915_ppgtt_init_hw(struct intel_gt *gt); 604c349dbc7Sjsg 6051bb76ff1Sjsg struct i915_ppgtt *i915_ppgtt_create(struct intel_gt *gt, 6061bb76ff1Sjsg unsigned long lmem_pt_obj_flags); 607c349dbc7Sjsg 6081bb76ff1Sjsg void i915_ggtt_suspend_vm(struct i915_address_space *vm); 6091bb76ff1Sjsg bool i915_ggtt_resume_vm(struct i915_address_space *vm); 610c349dbc7Sjsg void i915_ggtt_suspend(struct i915_ggtt *gtt); 611c349dbc7Sjsg void i915_ggtt_resume(struct i915_ggtt *ggtt); 612c349dbc7Sjsg 613c349dbc7Sjsg void 614ad8b1aafSjsg fill_page_dma(struct drm_i915_gem_object *p, const u64 val, unsigned int count); 615c349dbc7Sjsg 616c349dbc7Sjsg #define fill_px(px, v) fill_page_dma(px_base(px), (v), PAGE_SIZE / sizeof(u64)) 617c349dbc7Sjsg #define fill32_px(px, v) do { \ 618c349dbc7Sjsg u64 v__ = lower_32_bits(v); \ 619c349dbc7Sjsg fill_px((px), v__ << 32 | v__); \ 620c349dbc7Sjsg } while (0) 621c349dbc7Sjsg 622ad8b1aafSjsg int setup_scratch_page(struct i915_address_space *vm); 623c349dbc7Sjsg void free_scratch(struct i915_address_space *vm); 624c349dbc7Sjsg 625ad8b1aafSjsg struct drm_i915_gem_object *alloc_pt_dma(struct i915_address_space *vm, int sz); 6265ca02815Sjsg struct drm_i915_gem_object *alloc_pt_lmem(struct i915_address_space *vm, int sz); 6271bb76ff1Sjsg struct i915_page_table *alloc_pt(struct i915_address_space *vm, int sz); 628c349dbc7Sjsg struct i915_page_directory *alloc_pd(struct i915_address_space *vm); 629ad8b1aafSjsg struct i915_page_directory *__alloc_pd(int npde); 630c349dbc7Sjsg 6315ca02815Sjsg int map_pt_dma(struct i915_address_space *vm, struct drm_i915_gem_object *obj); 6325ca02815Sjsg int map_pt_dma_locked(struct i915_address_space *vm, struct drm_i915_gem_object *obj); 633c349dbc7Sjsg 634ad8b1aafSjsg void free_px(struct i915_address_space *vm, 635ad8b1aafSjsg struct i915_page_table *pt, int lvl); 636ad8b1aafSjsg #define free_pt(vm, px) free_px(vm, px, 0) 637ad8b1aafSjsg #define free_pd(vm, px) free_px(vm, px_pt(px), 1) 638c349dbc7Sjsg 639c349dbc7Sjsg void 640c349dbc7Sjsg __set_pd_entry(struct i915_page_directory * const pd, 641c349dbc7Sjsg const unsigned short idx, 642ad8b1aafSjsg struct i915_page_table *pt, 643c349dbc7Sjsg u64 (*encode)(const dma_addr_t, const enum i915_cache_level)); 644c349dbc7Sjsg 645c349dbc7Sjsg #define set_pd_entry(pd, idx, to) \ 646ad8b1aafSjsg __set_pd_entry((pd), (idx), px_pt(to), gen8_pde_encode) 647c349dbc7Sjsg 648c349dbc7Sjsg void 649c349dbc7Sjsg clear_pd_entry(struct i915_page_directory * const pd, 650c349dbc7Sjsg const unsigned short idx, 651ad8b1aafSjsg const struct drm_i915_gem_object * const scratch); 652c349dbc7Sjsg 653c349dbc7Sjsg bool 654c349dbc7Sjsg release_pd_entry(struct i915_page_directory * const pd, 655c349dbc7Sjsg const unsigned short idx, 656c349dbc7Sjsg struct i915_page_table * const pt, 657ad8b1aafSjsg const struct drm_i915_gem_object * const scratch); 658c349dbc7Sjsg void gen6_ggtt_invalidate(struct i915_ggtt *ggtt); 659c349dbc7Sjsg 660ad8b1aafSjsg void ppgtt_bind_vma(struct i915_address_space *vm, 661ad8b1aafSjsg struct i915_vm_pt_stash *stash, 6621bb76ff1Sjsg struct i915_vma_resource *vma_res, 663f005ef32Sjsg unsigned int pat_index, 664ad8b1aafSjsg u32 flags); 665ad8b1aafSjsg void ppgtt_unbind_vma(struct i915_address_space *vm, 6661bb76ff1Sjsg struct i915_vma_resource *vma_res); 667ad8b1aafSjsg 668c349dbc7Sjsg void gtt_write_workarounds(struct intel_gt *gt); 669c349dbc7Sjsg 670f005ef32Sjsg void setup_private_pat(struct intel_gt *gt); 671c349dbc7Sjsg 672ad8b1aafSjsg int i915_vm_alloc_pt_stash(struct i915_address_space *vm, 673ad8b1aafSjsg struct i915_vm_pt_stash *stash, 674ad8b1aafSjsg u64 size); 6755ca02815Sjsg int i915_vm_map_pt_stash(struct i915_address_space *vm, 676ad8b1aafSjsg struct i915_vm_pt_stash *stash); 677ad8b1aafSjsg void i915_vm_free_pt_stash(struct i915_address_space *vm, 678ad8b1aafSjsg struct i915_vm_pt_stash *stash); 679ad8b1aafSjsg 6805ca02815Sjsg struct i915_vma * 6815ca02815Sjsg __vm_create_scratch_for_read(struct i915_address_space *vm, unsigned long size); 6825ca02815Sjsg 6835ca02815Sjsg struct i915_vma * 6845ca02815Sjsg __vm_create_scratch_for_read_pinned(struct i915_address_space *vm, unsigned long size); 6855ca02815Sjsg 686c349dbc7Sjsg static inline struct sgt_dma { 687c349dbc7Sjsg struct scatterlist *sg; 688c349dbc7Sjsg dma_addr_t dma, max; 6891bb76ff1Sjsg } sgt_dma(struct i915_vma_resource *vma_res) { 6901bb76ff1Sjsg struct scatterlist *sg = vma_res->bi.pages->sgl; 691c349dbc7Sjsg dma_addr_t addr = sg_dma_address(sg); 692c349dbc7Sjsg 6935ca02815Sjsg return (struct sgt_dma){ sg, addr, addr + sg_dma_len(sg) }; 694c349dbc7Sjsg } 695c349dbc7Sjsg 696*3be56c56Sjsg bool i915_ggtt_require_binder(struct drm_i915_private *i915); 697*3be56c56Sjsg 698c349dbc7Sjsg #endif 699