Linux Audio

Check our new training course

Loading...
Note: File does not exist in v5.9.
  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
 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#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
 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};