| 1 | /* SPDX-License-Identifier: MIT */ |
| 2 | /* |
| 3 | * Copyright © 2020 Intel Corporation |
| 4 | */ |
| 5 | |
| 6 | #ifndef __GEN6_PPGTT_H__ |
| 7 | #define __GEN6_PPGTT_H__ |
| 8 | |
| 9 | #include "intel_gtt.h" |
| 10 | |
| 11 | struct i915_gem_ww_ctx; |
| 12 | |
| 13 | struct gen6_ppgtt { |
| 14 | struct i915_ppgtt base; |
| 15 | |
| 16 | struct mutex flush; |
| 17 | struct i915_vma *vma; |
| 18 | gen6_pte_t __iomem *pd_addr; |
| 19 | u32 pp_dir; |
| 20 | |
| 21 | atomic_t pin_count; |
| 22 | |
| 23 | bool scan_for_unused_pt; |
| 24 | }; |
| 25 | |
| 26 | static inline u32 gen6_pte_index(u32 addr) |
| 27 | { |
| 28 | return i915_pte_index(address: addr, GEN6_PDE_SHIFT); |
| 29 | } |
| 30 | |
| 31 | static inline u32 gen6_pte_count(u32 addr, u32 length) |
| 32 | { |
| 33 | return i915_pte_count(addr, length, GEN6_PDE_SHIFT); |
| 34 | } |
| 35 | |
| 36 | static inline u32 gen6_pde_index(u32 addr) |
| 37 | { |
| 38 | return i915_pde_index(addr, GEN6_PDE_SHIFT); |
| 39 | } |
| 40 | |
| 41 | #define __to_gen6_ppgtt(base) container_of(base, struct gen6_ppgtt, base) |
| 42 | |
| 43 | static inline struct gen6_ppgtt *to_gen6_ppgtt(struct i915_ppgtt *base) |
| 44 | { |
| 45 | BUILD_BUG_ON(offsetof(struct gen6_ppgtt, base)); |
| 46 | return __to_gen6_ppgtt(base); |
| 47 | } |
| 48 | |
| 49 | /* |
| 50 | * gen6_for_each_pde() iterates over every pde from start until start+length. |
| 51 | * If start and start+length are not perfectly divisible, the macro will round |
| 52 | * down and up as needed. Start=0 and length=2G effectively iterates over |
| 53 | * every PDE in the system. The macro modifies ALL its parameters except 'pd', |
| 54 | * so each of the other parameters should preferably be a simple variable, or |
| 55 | * at most an lvalue with no side-effects! |
| 56 | */ |
| 57 | #define gen6_for_each_pde(pt, pd, start, length, iter) \ |
| 58 | for (iter = gen6_pde_index(start); \ |
| 59 | length > 0 && iter < I915_PDES && \ |
| 60 | (pt = i915_pt_entry(pd, iter), true); \ |
| 61 | ({ u32 temp = ALIGN(start + 1, 1 << GEN6_PDE_SHIFT); \ |
| 62 | temp = min(temp - start, length); \ |
| 63 | start += temp; length -= temp; }), ++iter) |
| 64 | |
| 65 | #define gen6_for_all_pdes(pt, pd, iter) \ |
| 66 | for (iter = 0; \ |
| 67 | iter < I915_PDES && \ |
| 68 | (pt = i915_pt_entry(pd, iter), true); \ |
| 69 | ++iter) |
| 70 | |
| 71 | int gen6_ppgtt_pin(struct i915_ppgtt *base, struct i915_gem_ww_ctx *ww); |
| 72 | void gen6_ppgtt_unpin(struct i915_ppgtt *base); |
| 73 | void gen6_ppgtt_enable(struct intel_gt *gt); |
| 74 | void gen7_ppgtt_enable(struct intel_gt *gt); |
| 75 | struct i915_ppgtt *gen6_ppgtt_create(struct intel_gt *gt); |
| 76 | |
| 77 | #endif |
| 78 | |