151 lines · c
1// SPDX-License-Identifier: MIT2/*3 * Copyright © 2023 Intel Corporation4 */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 Structure16 *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 Directory24 * (1 Entry per VF)25 * +-----------+ LMTT (per VF)26 * | | +-----------+27 * | | | |28 * | | index: | |29 * | | LMEM VF +===========+30 * | | offset --> | PTE | ==> LMEM PF offset31 * | | +===========+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 54typedef u32 lmtt_2l_pde_t;55typedef 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#else60#define LMTT_2L_HAW 35 /* 32 GiB */61#endif62 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 71static unsigned int lmtt_2l_root_pd_level(void)72{73 return 1; /* implementation is 0-based */74}75 76static 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 90static 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 102static 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 112static 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 126static 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 143const 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