1 // SPDX-License-Identifier: MIT 2 /* 3 * Copyright © 2023 Intel Corporation 4 */ 5 6 #include <linux/align.h> 7 #include <linux/bitfield.h> 8 #include <linux/log2.h> 9 #include <linux/sizes.h> 10 11 #include "xe_lmtt_types.h" 12 #include "xe_macros.h" 13 14 /** 15 * DOC: Two-Level LMTT Structure 16 * 17 * LMHAW (Local Memory Host Address Width) is 37 bit (128GB) 18 * 19 * LMGAW (Local Memory Guest Address Width) is 37 bit (128GB) 20 * 21 * The following figure illustrates the structure and function of the 2L LMTT:: 22 * 23 * LMTT Directory 24 * (1 Entry per VF) 25 * +-----------+ LMTT (per VF) 26 * | | +-----------+ 27 * | | | | 28 * | | index: | | 29 * | | LMEM VF +===========+ 30 * | | offset --> | PTE | ==> LMEM PF offset 31 * | | +===========+ 32 * index: +===========+ | | 33 * VFID --> | PDE | -----------------> +-----------+ 34 * +===========+ / \. 35 * | | / \. 36 * | | / \. 37 * | | / \. 38 * +-----------+ <== [LMTT Directory Ptr] \. 39 * / \ / \. 40 * / \ +-----------+-----------------+------+---+ 41 * / \ | 31:HAW-16 | HAW-17:5 | 4:1 | 0 | 42 * / \ +===========+=================+======+===+ 43 * / \ | Reserved | LMEM Page (2MB) | Rsvd | V | 44 * / \ +-----------+-----------------+------+---+ 45 * / \. 46 * +-----------+-----------------+------+---+ 47 * | 31:HAW-12 | HAW-13:4 | 3:1 | 0 | 48 * +===========+=================+======+===+ 49 * | Reserved | LMTT Ptr (64KB) | Rsvd | V | 50 * +-----------+-----------------+------+---+ 51 * 52 */ 53 54 typedef u32 lmtt_2l_pde_t; 55 typedef u32 lmtt_2l_pte_t; 56 57 #if IS_ENABLED(CONFIG_DRM_XE_LMTT_2L_128GB) 58 #define LMTT_2L_HAW 37 /* 128 GiB */ 59 #else 60 #define LMTT_2L_HAW 35 /* 32 GiB */ 61 #endif 62 63 #define LMTT_2L_PDE_MAX_NUM 64 /* SRIOV with PF and 63 VFs, index 0 (PF) is unused */ 64 #define LMTT_2L_PDE_LMTT_PTR GENMASK(LMTT_2L_HAW - 13, 4) 65 #define LMTT_2L_PDE_VALID BIT(0) 66 67 #define LMTT_2L_PTE_MAX_NUM BIT(LMTT_2L_HAW - ilog2(SZ_2M)) 68 #define LMTT_2L_PTE_LMEM_PAGE GENMASK(LMTT_2L_HAW - 17, 5) 69 #define LMTT_2L_PTE_VALID BIT(0) 70 71 static unsigned int lmtt_2l_root_pd_level(void) 72 { 73 return 1; /* implementation is 0-based */ 74 } 75 76 static unsigned int lmtt_2l_pte_num(unsigned int level) 77 { 78 switch (level) { 79 case 1: 80 return LMTT_2L_PDE_MAX_NUM; 81 case 0: 82 BUILD_BUG_ON(LMTT_2L_HAW == 37 && LMTT_2L_PTE_MAX_NUM != SZ_64K); 83 BUILD_BUG_ON(LMTT_2L_HAW == 35 && LMTT_2L_PTE_MAX_NUM != SZ_16K); 84 return LMTT_2L_PTE_MAX_NUM; 85 default: 86 return 0; 87 } 88 } 89 90 static unsigned int lmtt_2l_pte_size(unsigned int level) 91 { 92 switch (level) { 93 case 1: 94 return sizeof(lmtt_2l_pde_t); 95 case 0: 96 return sizeof(lmtt_2l_pte_t); 97 default: 98 return 0; 99 } 100 } 101 102 static unsigned int lmtt_2l_pte_shift(unsigned int level) 103 { 104 switch (level) { 105 case 0: 106 return ilog2(SZ_2M); 107 default: 108 return 0; 109 } 110 } 111 112 static unsigned int lmtt_2l_pte_index(u64 addr, unsigned int level) 113 { 114 addr >>= lmtt_2l_pte_shift(level); 115 116 switch (level) { 117 case 0: 118 /* SZ_2M increments */ 119 BUILD_BUG_ON_NOT_POWER_OF_2(LMTT_2L_PTE_MAX_NUM); 120 return addr & (LMTT_2L_PTE_MAX_NUM - 1); 121 default: 122 return 0; 123 } 124 } 125 126 static u64 lmtt_2l_pte_encode(unsigned long offset, unsigned int level) 127 { 128 switch (level) { 129 case 0: 130 XE_WARN_ON(!IS_ALIGNED(offset, SZ_2M)); 131 XE_WARN_ON(!FIELD_FIT(LMTT_2L_PTE_LMEM_PAGE, offset / SZ_2M)); 132 return FIELD_PREP(LMTT_2L_PTE_LMEM_PAGE, offset / SZ_2M) | LMTT_2L_PTE_VALID; 133 case 1: 134 XE_WARN_ON(!IS_ALIGNED(offset, SZ_64K)); 135 XE_WARN_ON(!FIELD_FIT(LMTT_2L_PDE_LMTT_PTR, offset / SZ_64K)); 136 return FIELD_PREP(LMTT_2L_PDE_LMTT_PTR, offset / SZ_64K) | LMTT_2L_PDE_VALID; 137 default: 138 XE_WARN_ON(true); 139 return 0; 140 } 141 } 142 143 const struct xe_lmtt_ops lmtt_2l_ops = { 144 .lmtt_root_pd_level = lmtt_2l_root_pd_level, 145 .lmtt_pte_num = lmtt_2l_pte_num, 146 .lmtt_pte_size = lmtt_2l_pte_size, 147 .lmtt_pte_shift = lmtt_2l_pte_shift, 148 .lmtt_pte_index = lmtt_2l_pte_index, 149 .lmtt_pte_encode = lmtt_2l_pte_encode, 150 }; 151