162306a36Sopenharmony_ci/* SPDX-License-Identifier: MIT */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright © 2020 Intel Corporation 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Please try to maintain the following order within this file unless it makes 662306a36Sopenharmony_ci * sense to do otherwise. From top to bottom: 762306a36Sopenharmony_ci * 1. typedefs 862306a36Sopenharmony_ci * 2. #defines, and macros 962306a36Sopenharmony_ci * 3. structure definitions 1062306a36Sopenharmony_ci * 4. function prototypes 1162306a36Sopenharmony_ci * 1262306a36Sopenharmony_ci * Within each section, please try to order by generation in ascending order, 1362306a36Sopenharmony_ci * from top to bottom (ie. gen6 on the top, gen8 on the bottom). 1462306a36Sopenharmony_ci */ 1562306a36Sopenharmony_ci 1662306a36Sopenharmony_ci#ifndef __INTEL_GTT_H__ 1762306a36Sopenharmony_ci#define __INTEL_GTT_H__ 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include <linux/io-mapping.h> 2062306a36Sopenharmony_ci#include <linux/kref.h> 2162306a36Sopenharmony_ci#include <linux/mm.h> 2262306a36Sopenharmony_ci#include <linux/pagevec.h> 2362306a36Sopenharmony_ci#include <linux/scatterlist.h> 2462306a36Sopenharmony_ci#include <linux/workqueue.h> 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci#include <drm/drm_mm.h> 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci#include "gt/intel_reset.h" 2962306a36Sopenharmony_ci#include "i915_selftest.h" 3062306a36Sopenharmony_ci#include "i915_vma_resource.h" 3162306a36Sopenharmony_ci#include "i915_vma_types.h" 3262306a36Sopenharmony_ci#include "i915_params.h" 3362306a36Sopenharmony_ci#include "intel_memory_region.h" 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci#define I915_GFP_ALLOW_FAIL (GFP_KERNEL | __GFP_RETRY_MAYFAIL | __GFP_NOWARN) 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci#if IS_ENABLED(CONFIG_DRM_I915_TRACE_GTT) 3862306a36Sopenharmony_ci#define DBG(...) trace_printk(__VA_ARGS__) 3962306a36Sopenharmony_ci#else 4062306a36Sopenharmony_ci#define DBG(...) 4162306a36Sopenharmony_ci#endif 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci#define NALLOC 3 /* 1 normal, 1 for concurrent threads, 1 for preallocation */ 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci#define I915_GTT_PAGE_SIZE_4K BIT_ULL(12) 4662306a36Sopenharmony_ci#define I915_GTT_PAGE_SIZE_64K BIT_ULL(16) 4762306a36Sopenharmony_ci#define I915_GTT_PAGE_SIZE_2M BIT_ULL(21) 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci#define I915_GTT_PAGE_SIZE I915_GTT_PAGE_SIZE_4K 5062306a36Sopenharmony_ci#define I915_GTT_MAX_PAGE_SIZE I915_GTT_PAGE_SIZE_2M 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci#define I915_GTT_PAGE_MASK -I915_GTT_PAGE_SIZE 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci#define I915_GTT_MIN_ALIGNMENT I915_GTT_PAGE_SIZE 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci#define I915_FENCE_REG_NONE -1 5762306a36Sopenharmony_ci#define I915_MAX_NUM_FENCES 32 5862306a36Sopenharmony_ci/* 32 fences + sign bit for FENCE_REG_NONE */ 5962306a36Sopenharmony_ci#define I915_MAX_NUM_FENCE_BITS 6 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_citypedef u32 gen6_pte_t; 6262306a36Sopenharmony_citypedef u64 gen8_pte_t; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci#define ggtt_total_entries(ggtt) ((ggtt)->vm.total >> PAGE_SHIFT) 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci#define I915_PTES(pte_len) ((unsigned int)(PAGE_SIZE / (pte_len))) 6762306a36Sopenharmony_ci#define I915_PTE_MASK(pte_len) (I915_PTES(pte_len) - 1) 6862306a36Sopenharmony_ci#define I915_PDES 512 6962306a36Sopenharmony_ci#define I915_PDE_MASK (I915_PDES - 1) 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci/* gen6-hsw has bit 11-4 for physical addr bit 39-32 */ 7262306a36Sopenharmony_ci#define GEN6_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0xff0)) 7362306a36Sopenharmony_ci#define GEN6_PTE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) 7462306a36Sopenharmony_ci#define GEN6_PDE_ADDR_ENCODE(addr) GEN6_GTT_ADDR_ENCODE(addr) 7562306a36Sopenharmony_ci#define GEN6_PTE_CACHE_LLC (2 << 1) 7662306a36Sopenharmony_ci#define GEN6_PTE_UNCACHED (1 << 1) 7762306a36Sopenharmony_ci#define GEN6_PTE_VALID REG_BIT(0) 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci#define GEN6_PTES I915_PTES(sizeof(gen6_pte_t)) 8062306a36Sopenharmony_ci#define GEN6_PD_SIZE (I915_PDES * PAGE_SIZE) 8162306a36Sopenharmony_ci#define GEN6_PD_ALIGN (PAGE_SIZE * 16) 8262306a36Sopenharmony_ci#define GEN6_PDE_SHIFT 22 8362306a36Sopenharmony_ci#define GEN6_PDE_VALID REG_BIT(0) 8462306a36Sopenharmony_ci#define NUM_PTE(pde_shift) (1 << (pde_shift - PAGE_SHIFT)) 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci#define GEN7_PTE_CACHE_L3_LLC (3 << 1) 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci#define BYT_PTE_SNOOPED_BY_CPU_CACHES REG_BIT(2) 8962306a36Sopenharmony_ci#define BYT_PTE_WRITEABLE REG_BIT(1) 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci#define MTL_PPGTT_PTE_PAT3 BIT_ULL(62) 9262306a36Sopenharmony_ci#define GEN12_PPGTT_PTE_LM BIT_ULL(11) 9362306a36Sopenharmony_ci#define GEN12_PPGTT_PTE_PAT2 BIT_ULL(7) 9462306a36Sopenharmony_ci#define GEN12_PPGTT_PTE_PAT1 BIT_ULL(4) 9562306a36Sopenharmony_ci#define GEN12_PPGTT_PTE_PAT0 BIT_ULL(3) 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci#define GEN12_GGTT_PTE_LM BIT_ULL(1) 9862306a36Sopenharmony_ci#define MTL_GGTT_PTE_PAT0 BIT_ULL(52) 9962306a36Sopenharmony_ci#define MTL_GGTT_PTE_PAT1 BIT_ULL(53) 10062306a36Sopenharmony_ci#define GEN12_GGTT_PTE_ADDR_MASK GENMASK_ULL(45, 12) 10162306a36Sopenharmony_ci#define MTL_GGTT_PTE_PAT_MASK GENMASK_ULL(53, 52) 10262306a36Sopenharmony_ci 10362306a36Sopenharmony_ci#define GEN12_PDE_64K BIT(6) 10462306a36Sopenharmony_ci#define GEN12_PTE_PS64 BIT(8) 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci/* 10762306a36Sopenharmony_ci * Cacheability Control is a 4-bit value. The low three bits are stored in bits 10862306a36Sopenharmony_ci * 3:1 of the PTE, while the fourth bit is stored in bit 11 of the PTE. 10962306a36Sopenharmony_ci */ 11062306a36Sopenharmony_ci#define HSW_CACHEABILITY_CONTROL(bits) ((((bits) & 0x7) << 1) | \ 11162306a36Sopenharmony_ci (((bits) & 0x8) << (11 - 3))) 11262306a36Sopenharmony_ci#define HSW_WB_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x2) 11362306a36Sopenharmony_ci#define HSW_WB_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x3) 11462306a36Sopenharmony_ci#define HSW_WB_ELLC_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x8) 11562306a36Sopenharmony_ci#define HSW_WB_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0xb) 11662306a36Sopenharmony_ci#define HSW_WT_ELLC_LLC_AGE3 HSW_CACHEABILITY_CONTROL(0x7) 11762306a36Sopenharmony_ci#define HSW_WT_ELLC_LLC_AGE0 HSW_CACHEABILITY_CONTROL(0x6) 11862306a36Sopenharmony_ci#define HSW_PTE_UNCACHED (0) 11962306a36Sopenharmony_ci#define HSW_GTT_ADDR_ENCODE(addr) ((addr) | (((addr) >> 28) & 0x7f0)) 12062306a36Sopenharmony_ci#define HSW_PTE_ADDR_ENCODE(addr) HSW_GTT_ADDR_ENCODE(addr) 12162306a36Sopenharmony_ci 12262306a36Sopenharmony_ci/* 12362306a36Sopenharmony_ci * GEN8 32b style address is defined as a 3 level page table: 12462306a36Sopenharmony_ci * 31:30 | 29:21 | 20:12 | 11:0 12562306a36Sopenharmony_ci * PDPE | PDE | PTE | offset 12662306a36Sopenharmony_ci * The difference as compared to normal x86 3 level page table is the PDPEs are 12762306a36Sopenharmony_ci * programmed via register. 12862306a36Sopenharmony_ci * 12962306a36Sopenharmony_ci * GEN8 48b style address is defined as a 4 level page table: 13062306a36Sopenharmony_ci * 47:39 | 38:30 | 29:21 | 20:12 | 11:0 13162306a36Sopenharmony_ci * PML4E | PDPE | PDE | PTE | offset 13262306a36Sopenharmony_ci */ 13362306a36Sopenharmony_ci#define GEN8_3LVL_PDPES 4 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci#define PPAT_UNCACHED (_PAGE_PWT | _PAGE_PCD) 13662306a36Sopenharmony_ci#define PPAT_CACHED_PDE 0 /* WB LLC */ 13762306a36Sopenharmony_ci#define PPAT_CACHED _PAGE_PAT /* WB LLCeLLC */ 13862306a36Sopenharmony_ci#define PPAT_DISPLAY_ELLC _PAGE_PCD /* WT eLLC */ 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci#define CHV_PPAT_SNOOP REG_BIT(6) 14162306a36Sopenharmony_ci#define GEN8_PPAT_AGE(x) ((x)<<4) 14262306a36Sopenharmony_ci#define GEN8_PPAT_LLCeLLC (3<<2) 14362306a36Sopenharmony_ci#define GEN8_PPAT_LLCELLC (2<<2) 14462306a36Sopenharmony_ci#define GEN8_PPAT_LLC (1<<2) 14562306a36Sopenharmony_ci#define GEN8_PPAT_WB (3<<0) 14662306a36Sopenharmony_ci#define GEN8_PPAT_WT (2<<0) 14762306a36Sopenharmony_ci#define GEN8_PPAT_WC (1<<0) 14862306a36Sopenharmony_ci#define GEN8_PPAT_UC (0<<0) 14962306a36Sopenharmony_ci#define GEN8_PPAT_ELLC_OVERRIDE (0<<2) 15062306a36Sopenharmony_ci#define GEN8_PPAT(i, x) ((u64)(x) << ((i) * 8)) 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci#define GEN8_PAGE_PRESENT BIT_ULL(0) 15362306a36Sopenharmony_ci#define GEN8_PAGE_RW BIT_ULL(1) 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci#define GEN8_PDE_IPS_64K BIT(11) 15662306a36Sopenharmony_ci#define GEN8_PDE_PS_2M BIT(7) 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci#define MTL_PPAT_L4_CACHE_POLICY_MASK REG_GENMASK(3, 2) 15962306a36Sopenharmony_ci#define MTL_PAT_INDEX_COH_MODE_MASK REG_GENMASK(1, 0) 16062306a36Sopenharmony_ci#define MTL_PPAT_L4_3_UC REG_FIELD_PREP(MTL_PPAT_L4_CACHE_POLICY_MASK, 3) 16162306a36Sopenharmony_ci#define MTL_PPAT_L4_1_WT REG_FIELD_PREP(MTL_PPAT_L4_CACHE_POLICY_MASK, 1) 16262306a36Sopenharmony_ci#define MTL_PPAT_L4_0_WB REG_FIELD_PREP(MTL_PPAT_L4_CACHE_POLICY_MASK, 0) 16362306a36Sopenharmony_ci#define MTL_3_COH_2W REG_FIELD_PREP(MTL_PAT_INDEX_COH_MODE_MASK, 3) 16462306a36Sopenharmony_ci#define MTL_2_COH_1W REG_FIELD_PREP(MTL_PAT_INDEX_COH_MODE_MASK, 2) 16562306a36Sopenharmony_ci 16662306a36Sopenharmony_cistruct drm_i915_gem_object; 16762306a36Sopenharmony_cistruct i915_fence_reg; 16862306a36Sopenharmony_cistruct i915_vma; 16962306a36Sopenharmony_cistruct intel_gt; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci#define for_each_sgt_daddr(__dp, __iter, __sgt) \ 17262306a36Sopenharmony_ci __for_each_sgt_daddr(__dp, __iter, __sgt, I915_GTT_PAGE_SIZE) 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_cistruct i915_page_table { 17562306a36Sopenharmony_ci struct drm_i915_gem_object *base; 17662306a36Sopenharmony_ci union { 17762306a36Sopenharmony_ci atomic_t used; 17862306a36Sopenharmony_ci struct i915_page_table *stash; 17962306a36Sopenharmony_ci }; 18062306a36Sopenharmony_ci bool is_compact; 18162306a36Sopenharmony_ci}; 18262306a36Sopenharmony_ci 18362306a36Sopenharmony_cistruct i915_page_directory { 18462306a36Sopenharmony_ci struct i915_page_table pt; 18562306a36Sopenharmony_ci spinlock_t lock; 18662306a36Sopenharmony_ci void **entry; 18762306a36Sopenharmony_ci}; 18862306a36Sopenharmony_ci 18962306a36Sopenharmony_ci#define __px_choose_expr(x, type, expr, other) \ 19062306a36Sopenharmony_ci __builtin_choose_expr( \ 19162306a36Sopenharmony_ci __builtin_types_compatible_p(typeof(x), type) || \ 19262306a36Sopenharmony_ci __builtin_types_compatible_p(typeof(x), const type), \ 19362306a36Sopenharmony_ci ({ type __x = (type)(x); expr; }), \ 19462306a36Sopenharmony_ci other) 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci#define px_base(px) \ 19762306a36Sopenharmony_ci __px_choose_expr(px, struct drm_i915_gem_object *, __x, \ 19862306a36Sopenharmony_ci __px_choose_expr(px, struct i915_page_table *, __x->base, \ 19962306a36Sopenharmony_ci __px_choose_expr(px, struct i915_page_directory *, __x->pt.base, \ 20062306a36Sopenharmony_ci (void)0))) 20162306a36Sopenharmony_ci 20262306a36Sopenharmony_cistruct page *__px_page(struct drm_i915_gem_object *p); 20362306a36Sopenharmony_cidma_addr_t __px_dma(struct drm_i915_gem_object *p); 20462306a36Sopenharmony_ci#define px_dma(px) (__px_dma(px_base(px))) 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_civoid *__px_vaddr(struct drm_i915_gem_object *p); 20762306a36Sopenharmony_ci#define px_vaddr(px) (__px_vaddr(px_base(px))) 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci#define px_pt(px) \ 21062306a36Sopenharmony_ci __px_choose_expr(px, struct i915_page_table *, __x, \ 21162306a36Sopenharmony_ci __px_choose_expr(px, struct i915_page_directory *, &__x->pt, \ 21262306a36Sopenharmony_ci (void)0)) 21362306a36Sopenharmony_ci#define px_used(px) (&px_pt(px)->used) 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_cistruct i915_vm_pt_stash { 21662306a36Sopenharmony_ci /* preallocated chains of page tables/directories */ 21762306a36Sopenharmony_ci struct i915_page_table *pt[2]; 21862306a36Sopenharmony_ci /* 21962306a36Sopenharmony_ci * Optionally override the alignment/size of the physical page that 22062306a36Sopenharmony_ci * contains each PT. If not set defaults back to the usual 22162306a36Sopenharmony_ci * I915_GTT_PAGE_SIZE_4K. This does not influence the other paging 22262306a36Sopenharmony_ci * structures. MUST be a power-of-two. ONLY applicable on discrete 22362306a36Sopenharmony_ci * platforms. 22462306a36Sopenharmony_ci */ 22562306a36Sopenharmony_ci int pt_sz; 22662306a36Sopenharmony_ci}; 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_cistruct i915_vma_ops { 22962306a36Sopenharmony_ci /* Map an object into an address space with the given cache flags. */ 23062306a36Sopenharmony_ci void (*bind_vma)(struct i915_address_space *vm, 23162306a36Sopenharmony_ci struct i915_vm_pt_stash *stash, 23262306a36Sopenharmony_ci struct i915_vma_resource *vma_res, 23362306a36Sopenharmony_ci unsigned int pat_index, 23462306a36Sopenharmony_ci u32 flags); 23562306a36Sopenharmony_ci /* 23662306a36Sopenharmony_ci * Unmap an object from an address space. This usually consists of 23762306a36Sopenharmony_ci * setting the valid PTE entries to a reserved scratch page. 23862306a36Sopenharmony_ci */ 23962306a36Sopenharmony_ci void (*unbind_vma)(struct i915_address_space *vm, 24062306a36Sopenharmony_ci struct i915_vma_resource *vma_res); 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci}; 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_cistruct i915_address_space { 24562306a36Sopenharmony_ci struct kref ref; 24662306a36Sopenharmony_ci struct work_struct release_work; 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci struct drm_mm mm; 24962306a36Sopenharmony_ci struct intel_gt *gt; 25062306a36Sopenharmony_ci struct drm_i915_private *i915; 25162306a36Sopenharmony_ci struct device *dma; 25262306a36Sopenharmony_ci u64 total; /* size addr space maps (ex. 2GB for ggtt) */ 25362306a36Sopenharmony_ci u64 reserved; /* size addr space reserved */ 25462306a36Sopenharmony_ci u64 min_alignment[INTEL_MEMORY_STOLEN_LOCAL + 1]; 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_ci unsigned int bind_async_flags; 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci struct mutex mutex; /* protects vma and our lists */ 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci struct kref resv_ref; /* kref to keep the reservation lock alive. */ 26162306a36Sopenharmony_ci struct dma_resv _resv; /* reservation lock for all pd objects, and buffer pool */ 26262306a36Sopenharmony_ci#define VM_CLASS_GGTT 0 26362306a36Sopenharmony_ci#define VM_CLASS_PPGTT 1 26462306a36Sopenharmony_ci#define VM_CLASS_DPT 2 26562306a36Sopenharmony_ci 26662306a36Sopenharmony_ci struct drm_i915_gem_object *scratch[4]; 26762306a36Sopenharmony_ci /** 26862306a36Sopenharmony_ci * List of vma currently bound. 26962306a36Sopenharmony_ci */ 27062306a36Sopenharmony_ci struct list_head bound_list; 27162306a36Sopenharmony_ci 27262306a36Sopenharmony_ci /** 27362306a36Sopenharmony_ci * List of vmas not yet bound or evicted. 27462306a36Sopenharmony_ci */ 27562306a36Sopenharmony_ci struct list_head unbound_list; 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_ci /* Global GTT */ 27862306a36Sopenharmony_ci bool is_ggtt:1; 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci /* Display page table */ 28162306a36Sopenharmony_ci bool is_dpt:1; 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci /* Some systems support read-only mappings for GGTT and/or PPGTT */ 28462306a36Sopenharmony_ci bool has_read_only:1; 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ci /* Skip pte rewrite on unbind for suspend. Protected by @mutex */ 28762306a36Sopenharmony_ci bool skip_pte_rewrite:1; 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_ci u8 top; 29062306a36Sopenharmony_ci u8 pd_shift; 29162306a36Sopenharmony_ci u8 scratch_order; 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci /* Flags used when creating page-table objects for this vm */ 29462306a36Sopenharmony_ci unsigned long lmem_pt_obj_flags; 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci /* Interval tree for pending unbind vma resources */ 29762306a36Sopenharmony_ci struct rb_root_cached pending_unbind; 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci struct drm_i915_gem_object * 30062306a36Sopenharmony_ci (*alloc_pt_dma)(struct i915_address_space *vm, int sz); 30162306a36Sopenharmony_ci struct drm_i915_gem_object * 30262306a36Sopenharmony_ci (*alloc_scratch_dma)(struct i915_address_space *vm, int sz); 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci u64 (*pte_encode)(dma_addr_t addr, 30562306a36Sopenharmony_ci unsigned int pat_index, 30662306a36Sopenharmony_ci u32 flags); /* Create a valid PTE */ 30762306a36Sopenharmony_ci#define PTE_READ_ONLY BIT(0) 30862306a36Sopenharmony_ci#define PTE_LM BIT(1) 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_ci void (*allocate_va_range)(struct i915_address_space *vm, 31162306a36Sopenharmony_ci struct i915_vm_pt_stash *stash, 31262306a36Sopenharmony_ci u64 start, u64 length); 31362306a36Sopenharmony_ci void (*clear_range)(struct i915_address_space *vm, 31462306a36Sopenharmony_ci u64 start, u64 length); 31562306a36Sopenharmony_ci void (*scratch_range)(struct i915_address_space *vm, 31662306a36Sopenharmony_ci u64 start, u64 length); 31762306a36Sopenharmony_ci void (*insert_page)(struct i915_address_space *vm, 31862306a36Sopenharmony_ci dma_addr_t addr, 31962306a36Sopenharmony_ci u64 offset, 32062306a36Sopenharmony_ci unsigned int pat_index, 32162306a36Sopenharmony_ci u32 flags); 32262306a36Sopenharmony_ci void (*insert_entries)(struct i915_address_space *vm, 32362306a36Sopenharmony_ci struct i915_vma_resource *vma_res, 32462306a36Sopenharmony_ci unsigned int pat_index, 32562306a36Sopenharmony_ci u32 flags); 32662306a36Sopenharmony_ci void (*raw_insert_page)(struct i915_address_space *vm, 32762306a36Sopenharmony_ci dma_addr_t addr, 32862306a36Sopenharmony_ci u64 offset, 32962306a36Sopenharmony_ci unsigned int pat_index, 33062306a36Sopenharmony_ci u32 flags); 33162306a36Sopenharmony_ci void (*raw_insert_entries)(struct i915_address_space *vm, 33262306a36Sopenharmony_ci struct i915_vma_resource *vma_res, 33362306a36Sopenharmony_ci unsigned int pat_index, 33462306a36Sopenharmony_ci u32 flags); 33562306a36Sopenharmony_ci void (*cleanup)(struct i915_address_space *vm); 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci void (*foreach)(struct i915_address_space *vm, 33862306a36Sopenharmony_ci u64 start, u64 length, 33962306a36Sopenharmony_ci void (*fn)(struct i915_address_space *vm, 34062306a36Sopenharmony_ci struct i915_page_table *pt, 34162306a36Sopenharmony_ci void *data), 34262306a36Sopenharmony_ci void *data); 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci struct i915_vma_ops vma_ops; 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ci I915_SELFTEST_DECLARE(struct fault_attr fault_attr); 34762306a36Sopenharmony_ci I915_SELFTEST_DECLARE(bool scrub_64K); 34862306a36Sopenharmony_ci}; 34962306a36Sopenharmony_ci 35062306a36Sopenharmony_ci/* 35162306a36Sopenharmony_ci * The Graphics Translation Table is the way in which GEN hardware translates a 35262306a36Sopenharmony_ci * Graphics Virtual Address into a Physical Address. In addition to the normal 35362306a36Sopenharmony_ci * collateral associated with any va->pa translations GEN hardware also has a 35462306a36Sopenharmony_ci * portion of the GTT which can be mapped by the CPU and remain both coherent 35562306a36Sopenharmony_ci * and correct (in cases like swizzling). That region is referred to as GMADR in 35662306a36Sopenharmony_ci * the spec. 35762306a36Sopenharmony_ci */ 35862306a36Sopenharmony_cistruct i915_ggtt { 35962306a36Sopenharmony_ci struct i915_address_space vm; 36062306a36Sopenharmony_ci 36162306a36Sopenharmony_ci struct io_mapping iomap; /* Mapping to our CPU mappable region */ 36262306a36Sopenharmony_ci struct resource gmadr; /* GMADR resource */ 36362306a36Sopenharmony_ci resource_size_t mappable_end; /* End offset that we can CPU map */ 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci /** "Graphics Stolen Memory" holds the global PTEs */ 36662306a36Sopenharmony_ci void __iomem *gsm; 36762306a36Sopenharmony_ci void (*invalidate)(struct i915_ggtt *ggtt); 36862306a36Sopenharmony_ci 36962306a36Sopenharmony_ci /** PPGTT used for aliasing the PPGTT with the GTT */ 37062306a36Sopenharmony_ci struct i915_ppgtt *alias; 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci bool do_idle_maps; 37362306a36Sopenharmony_ci 37462306a36Sopenharmony_ci int mtrr; 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci /** Bit 6 swizzling required for X tiling */ 37762306a36Sopenharmony_ci u32 bit_6_swizzle_x; 37862306a36Sopenharmony_ci /** Bit 6 swizzling required for Y tiling */ 37962306a36Sopenharmony_ci u32 bit_6_swizzle_y; 38062306a36Sopenharmony_ci 38162306a36Sopenharmony_ci u32 pin_bias; 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci unsigned int num_fences; 38462306a36Sopenharmony_ci struct i915_fence_reg *fence_regs; 38562306a36Sopenharmony_ci struct list_head fence_list; 38662306a36Sopenharmony_ci 38762306a36Sopenharmony_ci /** 38862306a36Sopenharmony_ci * List of all objects in gtt_space, currently mmaped by userspace. 38962306a36Sopenharmony_ci * All objects within this list must also be on bound_list. 39062306a36Sopenharmony_ci */ 39162306a36Sopenharmony_ci struct list_head userfault_list; 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci struct mutex error_mutex; 39462306a36Sopenharmony_ci struct drm_mm_node error_capture; 39562306a36Sopenharmony_ci struct drm_mm_node uc_fw; 39662306a36Sopenharmony_ci 39762306a36Sopenharmony_ci /** List of GTs mapping this GGTT */ 39862306a36Sopenharmony_ci struct list_head gt_list; 39962306a36Sopenharmony_ci}; 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_cistruct i915_ppgtt { 40262306a36Sopenharmony_ci struct i915_address_space vm; 40362306a36Sopenharmony_ci 40462306a36Sopenharmony_ci struct i915_page_directory *pd; 40562306a36Sopenharmony_ci}; 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci#define i915_is_ggtt(vm) ((vm)->is_ggtt) 40862306a36Sopenharmony_ci#define i915_is_dpt(vm) ((vm)->is_dpt) 40962306a36Sopenharmony_ci#define i915_is_ggtt_or_dpt(vm) (i915_is_ggtt(vm) || i915_is_dpt(vm)) 41062306a36Sopenharmony_ci 41162306a36Sopenharmony_cibool intel_vm_no_concurrent_access_wa(struct drm_i915_private *i915); 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ciint __must_check 41462306a36Sopenharmony_cii915_vm_lock_objects(struct i915_address_space *vm, struct i915_gem_ww_ctx *ww); 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_cistatic inline bool 41762306a36Sopenharmony_cii915_vm_is_4lvl(const struct i915_address_space *vm) 41862306a36Sopenharmony_ci{ 41962306a36Sopenharmony_ci return (vm->total - 1) >> 32; 42062306a36Sopenharmony_ci} 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_cistatic inline bool 42362306a36Sopenharmony_cii915_vm_has_scratch_64K(struct i915_address_space *vm) 42462306a36Sopenharmony_ci{ 42562306a36Sopenharmony_ci return vm->scratch_order == get_order(I915_GTT_PAGE_SIZE_64K); 42662306a36Sopenharmony_ci} 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_cistatic inline u64 i915_vm_min_alignment(struct i915_address_space *vm, 42962306a36Sopenharmony_ci enum intel_memory_type type) 43062306a36Sopenharmony_ci{ 43162306a36Sopenharmony_ci /* avoid INTEL_MEMORY_MOCK overflow */ 43262306a36Sopenharmony_ci if ((int)type >= ARRAY_SIZE(vm->min_alignment)) 43362306a36Sopenharmony_ci type = INTEL_MEMORY_SYSTEM; 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_ci return vm->min_alignment[type]; 43662306a36Sopenharmony_ci} 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_cistatic inline u64 i915_vm_obj_min_alignment(struct i915_address_space *vm, 43962306a36Sopenharmony_ci struct drm_i915_gem_object *obj) 44062306a36Sopenharmony_ci{ 44162306a36Sopenharmony_ci struct intel_memory_region *mr = READ_ONCE(obj->mm.region); 44262306a36Sopenharmony_ci enum intel_memory_type type = mr ? mr->type : INTEL_MEMORY_SYSTEM; 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_ci return i915_vm_min_alignment(vm, type); 44562306a36Sopenharmony_ci} 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_cistatic inline bool 44862306a36Sopenharmony_cii915_vm_has_cache_coloring(struct i915_address_space *vm) 44962306a36Sopenharmony_ci{ 45062306a36Sopenharmony_ci return i915_is_ggtt(vm) && vm->mm.color_adjust; 45162306a36Sopenharmony_ci} 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_cistatic inline struct i915_ggtt * 45462306a36Sopenharmony_cii915_vm_to_ggtt(struct i915_address_space *vm) 45562306a36Sopenharmony_ci{ 45662306a36Sopenharmony_ci BUILD_BUG_ON(offsetof(struct i915_ggtt, vm)); 45762306a36Sopenharmony_ci GEM_BUG_ON(!i915_is_ggtt(vm)); 45862306a36Sopenharmony_ci return container_of(vm, struct i915_ggtt, vm); 45962306a36Sopenharmony_ci} 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_cistatic inline struct i915_ppgtt * 46262306a36Sopenharmony_cii915_vm_to_ppgtt(struct i915_address_space *vm) 46362306a36Sopenharmony_ci{ 46462306a36Sopenharmony_ci BUILD_BUG_ON(offsetof(struct i915_ppgtt, vm)); 46562306a36Sopenharmony_ci GEM_BUG_ON(i915_is_ggtt_or_dpt(vm)); 46662306a36Sopenharmony_ci return container_of(vm, struct i915_ppgtt, vm); 46762306a36Sopenharmony_ci} 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_cistatic inline struct i915_address_space * 47062306a36Sopenharmony_cii915_vm_get(struct i915_address_space *vm) 47162306a36Sopenharmony_ci{ 47262306a36Sopenharmony_ci kref_get(&vm->ref); 47362306a36Sopenharmony_ci return vm; 47462306a36Sopenharmony_ci} 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_cistatic inline struct i915_address_space * 47762306a36Sopenharmony_cii915_vm_tryget(struct i915_address_space *vm) 47862306a36Sopenharmony_ci{ 47962306a36Sopenharmony_ci return kref_get_unless_zero(&vm->ref) ? vm : NULL; 48062306a36Sopenharmony_ci} 48162306a36Sopenharmony_ci 48262306a36Sopenharmony_cistatic inline void assert_vm_alive(struct i915_address_space *vm) 48362306a36Sopenharmony_ci{ 48462306a36Sopenharmony_ci GEM_BUG_ON(!kref_read(&vm->ref)); 48562306a36Sopenharmony_ci} 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci/** 48862306a36Sopenharmony_ci * i915_vm_resv_get - Obtain a reference on the vm's reservation lock 48962306a36Sopenharmony_ci * @vm: The vm whose reservation lock we want to share. 49062306a36Sopenharmony_ci * 49162306a36Sopenharmony_ci * Return: A pointer to the vm's reservation lock. 49262306a36Sopenharmony_ci */ 49362306a36Sopenharmony_cistatic inline struct dma_resv *i915_vm_resv_get(struct i915_address_space *vm) 49462306a36Sopenharmony_ci{ 49562306a36Sopenharmony_ci kref_get(&vm->resv_ref); 49662306a36Sopenharmony_ci return &vm->_resv; 49762306a36Sopenharmony_ci} 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_civoid i915_vm_release(struct kref *kref); 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_civoid i915_vm_resv_release(struct kref *kref); 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_cistatic inline void i915_vm_put(struct i915_address_space *vm) 50462306a36Sopenharmony_ci{ 50562306a36Sopenharmony_ci kref_put(&vm->ref, i915_vm_release); 50662306a36Sopenharmony_ci} 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci/** 50962306a36Sopenharmony_ci * i915_vm_resv_put - Release a reference on the vm's reservation lock 51062306a36Sopenharmony_ci * @vm: The vm whose reservation lock reference we want to release 51162306a36Sopenharmony_ci */ 51262306a36Sopenharmony_cistatic inline void i915_vm_resv_put(struct i915_address_space *vm) 51362306a36Sopenharmony_ci{ 51462306a36Sopenharmony_ci kref_put(&vm->resv_ref, i915_vm_resv_release); 51562306a36Sopenharmony_ci} 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_civoid i915_address_space_init(struct i915_address_space *vm, int subclass); 51862306a36Sopenharmony_civoid i915_address_space_fini(struct i915_address_space *vm); 51962306a36Sopenharmony_ci 52062306a36Sopenharmony_cistatic inline u32 i915_pte_index(u64 address, unsigned int pde_shift) 52162306a36Sopenharmony_ci{ 52262306a36Sopenharmony_ci const u32 mask = NUM_PTE(pde_shift) - 1; 52362306a36Sopenharmony_ci 52462306a36Sopenharmony_ci return (address >> PAGE_SHIFT) & mask; 52562306a36Sopenharmony_ci} 52662306a36Sopenharmony_ci 52762306a36Sopenharmony_ci/* 52862306a36Sopenharmony_ci * Helper to counts the number of PTEs within the given length. This count 52962306a36Sopenharmony_ci * does not cross a page table boundary, so the max value would be 53062306a36Sopenharmony_ci * GEN6_PTES for GEN6, and GEN8_PTES for GEN8. 53162306a36Sopenharmony_ci */ 53262306a36Sopenharmony_cistatic inline u32 i915_pte_count(u64 addr, u64 length, unsigned int pde_shift) 53362306a36Sopenharmony_ci{ 53462306a36Sopenharmony_ci const u64 mask = ~((1ULL << pde_shift) - 1); 53562306a36Sopenharmony_ci u64 end; 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ci GEM_BUG_ON(length == 0); 53862306a36Sopenharmony_ci GEM_BUG_ON(offset_in_page(addr | length)); 53962306a36Sopenharmony_ci 54062306a36Sopenharmony_ci end = addr + length; 54162306a36Sopenharmony_ci 54262306a36Sopenharmony_ci if ((addr & mask) != (end & mask)) 54362306a36Sopenharmony_ci return NUM_PTE(pde_shift) - i915_pte_index(addr, pde_shift); 54462306a36Sopenharmony_ci 54562306a36Sopenharmony_ci return i915_pte_index(end, pde_shift) - i915_pte_index(addr, pde_shift); 54662306a36Sopenharmony_ci} 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_cistatic inline u32 i915_pde_index(u64 addr, u32 shift) 54962306a36Sopenharmony_ci{ 55062306a36Sopenharmony_ci return (addr >> shift) & I915_PDE_MASK; 55162306a36Sopenharmony_ci} 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_cistatic inline struct i915_page_table * 55462306a36Sopenharmony_cii915_pt_entry(const struct i915_page_directory * const pd, 55562306a36Sopenharmony_ci const unsigned short n) 55662306a36Sopenharmony_ci{ 55762306a36Sopenharmony_ci return pd->entry[n]; 55862306a36Sopenharmony_ci} 55962306a36Sopenharmony_ci 56062306a36Sopenharmony_cistatic inline struct i915_page_directory * 56162306a36Sopenharmony_cii915_pd_entry(const struct i915_page_directory * const pdp, 56262306a36Sopenharmony_ci const unsigned short n) 56362306a36Sopenharmony_ci{ 56462306a36Sopenharmony_ci return pdp->entry[n]; 56562306a36Sopenharmony_ci} 56662306a36Sopenharmony_ci 56762306a36Sopenharmony_cistatic inline dma_addr_t 56862306a36Sopenharmony_cii915_page_dir_dma_addr(const struct i915_ppgtt *ppgtt, const unsigned int n) 56962306a36Sopenharmony_ci{ 57062306a36Sopenharmony_ci struct i915_page_table *pt = ppgtt->pd->entry[n]; 57162306a36Sopenharmony_ci 57262306a36Sopenharmony_ci return __px_dma(pt ? px_base(pt) : ppgtt->vm.scratch[ppgtt->vm.top]); 57362306a36Sopenharmony_ci} 57462306a36Sopenharmony_ci 57562306a36Sopenharmony_civoid ppgtt_init(struct i915_ppgtt *ppgtt, struct intel_gt *gt, 57662306a36Sopenharmony_ci unsigned long lmem_pt_obj_flags); 57762306a36Sopenharmony_civoid intel_ggtt_bind_vma(struct i915_address_space *vm, 57862306a36Sopenharmony_ci struct i915_vm_pt_stash *stash, 57962306a36Sopenharmony_ci struct i915_vma_resource *vma_res, 58062306a36Sopenharmony_ci unsigned int pat_index, 58162306a36Sopenharmony_ci u32 flags); 58262306a36Sopenharmony_civoid intel_ggtt_unbind_vma(struct i915_address_space *vm, 58362306a36Sopenharmony_ci struct i915_vma_resource *vma_res); 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_ciint i915_ggtt_probe_hw(struct drm_i915_private *i915); 58662306a36Sopenharmony_ciint i915_ggtt_init_hw(struct drm_i915_private *i915); 58762306a36Sopenharmony_ciint i915_ggtt_enable_hw(struct drm_i915_private *i915); 58862306a36Sopenharmony_ciint i915_init_ggtt(struct drm_i915_private *i915); 58962306a36Sopenharmony_civoid i915_ggtt_driver_release(struct drm_i915_private *i915); 59062306a36Sopenharmony_civoid i915_ggtt_driver_late_release(struct drm_i915_private *i915); 59162306a36Sopenharmony_cistruct i915_ggtt *i915_ggtt_create(struct drm_i915_private *i915); 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_cistatic inline bool i915_ggtt_has_aperture(const struct i915_ggtt *ggtt) 59462306a36Sopenharmony_ci{ 59562306a36Sopenharmony_ci return ggtt->mappable_end > 0; 59662306a36Sopenharmony_ci} 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_ciint i915_ppgtt_init_hw(struct intel_gt *gt); 59962306a36Sopenharmony_ci 60062306a36Sopenharmony_cistruct i915_ppgtt *i915_ppgtt_create(struct intel_gt *gt, 60162306a36Sopenharmony_ci unsigned long lmem_pt_obj_flags); 60262306a36Sopenharmony_ci 60362306a36Sopenharmony_civoid i915_ggtt_suspend_vm(struct i915_address_space *vm); 60462306a36Sopenharmony_cibool i915_ggtt_resume_vm(struct i915_address_space *vm); 60562306a36Sopenharmony_civoid i915_ggtt_suspend(struct i915_ggtt *gtt); 60662306a36Sopenharmony_civoid i915_ggtt_resume(struct i915_ggtt *ggtt); 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_civoid 60962306a36Sopenharmony_cifill_page_dma(struct drm_i915_gem_object *p, const u64 val, unsigned int count); 61062306a36Sopenharmony_ci 61162306a36Sopenharmony_ci#define fill_px(px, v) fill_page_dma(px_base(px), (v), PAGE_SIZE / sizeof(u64)) 61262306a36Sopenharmony_ci#define fill32_px(px, v) do { \ 61362306a36Sopenharmony_ci u64 v__ = lower_32_bits(v); \ 61462306a36Sopenharmony_ci fill_px((px), v__ << 32 | v__); \ 61562306a36Sopenharmony_ci} while (0) 61662306a36Sopenharmony_ci 61762306a36Sopenharmony_ciint setup_scratch_page(struct i915_address_space *vm); 61862306a36Sopenharmony_civoid free_scratch(struct i915_address_space *vm); 61962306a36Sopenharmony_ci 62062306a36Sopenharmony_cistruct drm_i915_gem_object *alloc_pt_dma(struct i915_address_space *vm, int sz); 62162306a36Sopenharmony_cistruct drm_i915_gem_object *alloc_pt_lmem(struct i915_address_space *vm, int sz); 62262306a36Sopenharmony_cistruct i915_page_table *alloc_pt(struct i915_address_space *vm, int sz); 62362306a36Sopenharmony_cistruct i915_page_directory *alloc_pd(struct i915_address_space *vm); 62462306a36Sopenharmony_cistruct i915_page_directory *__alloc_pd(int npde); 62562306a36Sopenharmony_ci 62662306a36Sopenharmony_ciint map_pt_dma(struct i915_address_space *vm, struct drm_i915_gem_object *obj); 62762306a36Sopenharmony_ciint map_pt_dma_locked(struct i915_address_space *vm, struct drm_i915_gem_object *obj); 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_civoid free_px(struct i915_address_space *vm, 63062306a36Sopenharmony_ci struct i915_page_table *pt, int lvl); 63162306a36Sopenharmony_ci#define free_pt(vm, px) free_px(vm, px, 0) 63262306a36Sopenharmony_ci#define free_pd(vm, px) free_px(vm, px_pt(px), 1) 63362306a36Sopenharmony_ci 63462306a36Sopenharmony_civoid 63562306a36Sopenharmony_ci__set_pd_entry(struct i915_page_directory * const pd, 63662306a36Sopenharmony_ci const unsigned short idx, 63762306a36Sopenharmony_ci struct i915_page_table *pt, 63862306a36Sopenharmony_ci u64 (*encode)(const dma_addr_t, const enum i915_cache_level)); 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_ci#define set_pd_entry(pd, idx, to) \ 64162306a36Sopenharmony_ci __set_pd_entry((pd), (idx), px_pt(to), gen8_pde_encode) 64262306a36Sopenharmony_ci 64362306a36Sopenharmony_civoid 64462306a36Sopenharmony_ciclear_pd_entry(struct i915_page_directory * const pd, 64562306a36Sopenharmony_ci const unsigned short idx, 64662306a36Sopenharmony_ci const struct drm_i915_gem_object * const scratch); 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_cibool 64962306a36Sopenharmony_cirelease_pd_entry(struct i915_page_directory * const pd, 65062306a36Sopenharmony_ci const unsigned short idx, 65162306a36Sopenharmony_ci struct i915_page_table * const pt, 65262306a36Sopenharmony_ci const struct drm_i915_gem_object * const scratch); 65362306a36Sopenharmony_civoid gen6_ggtt_invalidate(struct i915_ggtt *ggtt); 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_civoid ppgtt_bind_vma(struct i915_address_space *vm, 65662306a36Sopenharmony_ci struct i915_vm_pt_stash *stash, 65762306a36Sopenharmony_ci struct i915_vma_resource *vma_res, 65862306a36Sopenharmony_ci unsigned int pat_index, 65962306a36Sopenharmony_ci u32 flags); 66062306a36Sopenharmony_civoid ppgtt_unbind_vma(struct i915_address_space *vm, 66162306a36Sopenharmony_ci struct i915_vma_resource *vma_res); 66262306a36Sopenharmony_ci 66362306a36Sopenharmony_civoid gtt_write_workarounds(struct intel_gt *gt); 66462306a36Sopenharmony_ci 66562306a36Sopenharmony_civoid setup_private_pat(struct intel_gt *gt); 66662306a36Sopenharmony_ci 66762306a36Sopenharmony_ciint i915_vm_alloc_pt_stash(struct i915_address_space *vm, 66862306a36Sopenharmony_ci struct i915_vm_pt_stash *stash, 66962306a36Sopenharmony_ci u64 size); 67062306a36Sopenharmony_ciint i915_vm_map_pt_stash(struct i915_address_space *vm, 67162306a36Sopenharmony_ci struct i915_vm_pt_stash *stash); 67262306a36Sopenharmony_civoid i915_vm_free_pt_stash(struct i915_address_space *vm, 67362306a36Sopenharmony_ci struct i915_vm_pt_stash *stash); 67462306a36Sopenharmony_ci 67562306a36Sopenharmony_cistruct i915_vma * 67662306a36Sopenharmony_ci__vm_create_scratch_for_read(struct i915_address_space *vm, unsigned long size); 67762306a36Sopenharmony_ci 67862306a36Sopenharmony_cistruct i915_vma * 67962306a36Sopenharmony_ci__vm_create_scratch_for_read_pinned(struct i915_address_space *vm, unsigned long size); 68062306a36Sopenharmony_ci 68162306a36Sopenharmony_cistatic inline struct sgt_dma { 68262306a36Sopenharmony_ci struct scatterlist *sg; 68362306a36Sopenharmony_ci dma_addr_t dma, max; 68462306a36Sopenharmony_ci} sgt_dma(struct i915_vma_resource *vma_res) { 68562306a36Sopenharmony_ci struct scatterlist *sg = vma_res->bi.pages->sgl; 68662306a36Sopenharmony_ci dma_addr_t addr = sg_dma_address(sg); 68762306a36Sopenharmony_ci 68862306a36Sopenharmony_ci return (struct sgt_dma){ sg, addr, addr + sg_dma_len(sg) }; 68962306a36Sopenharmony_ci} 69062306a36Sopenharmony_ci 69162306a36Sopenharmony_ci#endif 692