1 /* SPDX-License-Identifier: MIT */
2 /*
3 * Copyright © 2023 Intel Corporation
4 */
5
6 #ifndef _XE_REG_DEFS_H_
7 #define _XE_REG_DEFS_H_
8
9 #include <linux/build_bug.h>
10 #include <linux/log2.h>
11 #include <linux/sizes.h>
12
13 #include "compat-i915-headers/i915_reg_defs.h"
14
15 /**
16 * XE_REG_ADDR_MAX - The upper limit on MMIO register address
17 *
18 * This macro specifies the upper limit (not inclusive) on MMIO register offset
19 * supported by struct xe_reg and functions based on struct xe_mmio.
20 *
21 * Currently this is defined as 4 MiB.
22 */
23 #define XE_REG_ADDR_MAX SZ_4M
24
25 /**
26 * struct xe_reg - Register definition
27 *
28 * Register definition to be used by the individual register. Although the same
29 * definition is used for xe_reg and xe_reg_mcr, they use different internal
30 * APIs for accesses.
31 */
32 struct xe_reg {
33 union {
34 struct {
35 /** @addr: address */
36 u32 addr:const_ilog2(XE_REG_ADDR_MAX);
37 /**
38 * @masked: register is "masked", with upper 16bits used
39 * to identify the bits that are updated on the lower
40 * bits
41 */
42 u32 masked:1;
43 /**
44 * @mcr: register is multicast/replicated in the
45 * hardware and needs special handling. Any register
46 * with this set should also use a type of xe_reg_mcr_t.
47 * It's only here so the few places that deal with MCR
48 * registers specially (xe_sr.c) and tests using the raw
49 * value can inspect it.
50 */
51 u32 mcr:1;
52 /**
53 * @vf: register is accessible from the Virtual Function.
54 */
55 u32 vf:1;
56 };
57 /** @raw: Raw value with both address and options */
58 u32 raw;
59 };
60 };
61 static_assert(sizeof(struct xe_reg) == sizeof(u32));
62
63 /**
64 * struct xe_reg_mcr - MCR register definition
65 *
66 * MCR register is the same as a regular register, but uses another type since
67 * the internal API used for accessing them is different: it's never correct to
68 * use regular MMIO access.
69 */
70 struct xe_reg_mcr {
71 /** @__reg: The register */
72 struct xe_reg __reg;
73 };
74
75
76 /**
77 * XE_REG_OPTION_MASKED - Register is "masked", with upper 16 bits marking the
78 * written bits on the lower 16 bits.
79 *
80 * It only applies to registers explicitly marked in bspec with
81 * "Access: Masked". Registers with this option can have write operations to
82 * specific lower bits by setting the corresponding upper bits. Other bits will
83 * not be affected. This allows register writes without needing a RMW cycle and
84 * without caching in software the register value.
85 *
86 * Example: a write with value 0x00010001 will set bit 0 and all other bits
87 * retain their previous values.
88 *
89 * To be used with XE_REG(). XE_REG_MCR() and XE_REG_INITIALIZER()
90 */
91 #define XE_REG_OPTION_MASKED .masked = 1
92
93 /**
94 * XE_REG_OPTION_VF - Register is "VF" accessible.
95 *
96 * To be used with XE_REG() and XE_REG_INITIALIZER().
97 */
98 #define XE_REG_OPTION_VF .vf = 1
99
100 /**
101 * XE_REG_INITIALIZER - Initializer for xe_reg_t.
102 * @r_: Register offset
103 * @...: Additional options like access mode. See struct xe_reg for available
104 * options.
105 *
106 * Register field is mandatory, and additional options may be passed as
107 * arguments. Usually ``XE_REG()`` should be preferred since it creates an
108 * object of the right type. However when initializing static const storage,
109 * where a compound statement is not allowed, this can be used instead.
110 */
111 #define XE_REG_INITIALIZER(r_, ...) { .addr = r_, __VA_ARGS__ }
112
113
114 /**
115 * XE_REG - Create a struct xe_reg from offset and additional flags
116 * @r_: Register offset
117 * @...: Additional options like access mode. See struct xe_reg for available
118 * options.
119 */
120 #define XE_REG(r_, ...) ((const struct xe_reg)XE_REG_INITIALIZER(r_, ##__VA_ARGS__))
121
122 /**
123 * XE_REG_MCR - Create a struct xe_reg_mcr from offset and additional flags
124 * @r_: Register offset
125 * @...: Additional options like access mode. See struct xe_reg for available
126 * options.
127 */
128 #define XE_REG_MCR(r_, ...) ((const struct xe_reg_mcr){ \
129 .__reg = XE_REG_INITIALIZER(r_, ##__VA_ARGS__, .mcr = 1) \
130 })
131
xe_reg_is_valid(struct xe_reg r)132 static inline bool xe_reg_is_valid(struct xe_reg r)
133 {
134 return r.addr;
135 }
136
137 #endif
138