summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/xe/regs/xe_reg_defs.h
blob: 23f7dc5bbe995bb7968049069c18249833a66789 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
/* SPDX-License-Identifier: MIT */
/*
 * Copyright © 2023 Intel Corporation
 */

#ifndef _XE_REG_DEFS_H_
#define _XE_REG_DEFS_H_

#include <linux/build_bug.h>

#include "compat-i915-headers/i915_reg_defs.h"

/**
 * struct xe_reg - Register definition
 *
 * Register defintion to be used by the individual register. Although the same
 * definition is used for xe_reg and xe_reg_mcr, they use different internal
 * APIs for accesses.
 */
struct xe_reg {
	union {
		struct {
			/** @addr: address */
			u32 addr:28;
			/**
			 * @masked: register is "masked", with upper 16bits used
			 * to identify the bits that are updated on the lower
			 * bits
			 */
			u32 masked:1;
			/**
			 * @mcr: register is multicast/replicated in the
			 * hardware and needs special handling. Any register
			 * with this set should also use a type of xe_reg_mcr_t.
			 * It's only here so the few places that deal with MCR
			 * registers specially (xe_sr.c) and tests using the raw
			 * value can inspect it.
			 */
			u32 mcr:1;
			/**
			 * @vf: register is accessible from the Virtual Function.
			 */
			u32 vf:1;
			/**
			 * @ext: access MMIO extension space for current register.
			 */
			u32 ext:1;
		};
		/** @raw: Raw value with both address and options */
		u32 raw;
	};
};
static_assert(sizeof(struct xe_reg) == sizeof(u32));

/**
 * struct xe_reg_mcr - MCR register definition
 *
 * MCR register is the same as a regular register, but uses another type since
 * the internal API used for accessing them is different: it's never correct to
 * use regular MMIO access.
 */
struct xe_reg_mcr {
	/** @__reg: The register */
	struct xe_reg __reg;
};


/**
 * XE_REG_OPTION_MASKED - Register is "masked", with upper 16 bits marking the
 * written bits on the lower 16 bits.
 *
 * It only applies to registers explicitly marked in bspec with
 * "Access: Masked". Registers with this option can have write operations to
 * specific lower bits by setting the corresponding upper bits. Other bits will
 * not be affected. This allows register writes without needing a RMW cycle and
 * without caching in software the register value.
 *
 * Example: a write with value 0x00010001 will set bit 0 and all other bits
 * retain their previous values.
 *
 * To be used with XE_REG(). XE_REG_MCR() and XE_REG_INITIALIZER()
 */
#define XE_REG_OPTION_MASKED		.masked = 1

/**
 * XE_REG_OPTION_VF - Register is "VF" accessible.
 *
 * To be used with XE_REG() and XE_REG_INITIALIZER().
 */
#define XE_REG_OPTION_VF		.vf = 1

/**
 * XE_REG_INITIALIZER - Initializer for xe_reg_t.
 * @r_: Register offset
 * @...: Additional options like access mode. See struct xe_reg for available
 *       options.
 *
 * Register field is mandatory, and additional options may be passed as
 * arguments. Usually ``XE_REG()`` should be preferred since it creates an
 * object of the right type. However when initializing static const storage,
 * where a compound statement is not allowed, this can be used instead.
 */
#define XE_REG_INITIALIZER(r_, ...)    { .addr = r_, __VA_ARGS__ }


/**
 * XE_REG - Create a struct xe_reg from offset and additional flags
 * @r_: Register offset
 * @...: Additional options like access mode. See struct xe_reg for available
 *       options.
 */
#define XE_REG(r_, ...)		((const struct xe_reg)XE_REG_INITIALIZER(r_, ##__VA_ARGS__))

/**
 * XE_REG_EXT - Create a struct xe_reg from extension offset and additional
 * flags
 * @r_: Register extension offset
 * @...: Additional options like access mode. See struct xe_reg for available
 *       options.
 */
#define XE_REG_EXT(r_, ...)	\
	((const struct xe_reg)XE_REG_INITIALIZER(r_, ##__VA_ARGS__, .ext = 1))

/**
 * XE_REG_MCR - Create a struct xe_reg_mcr from offset and additional flags
 * @r_: Register offset
 * @...: Additional options like access mode. See struct xe_reg for available
 *       options.
 */
#define XE_REG_MCR(r_, ...)	((const struct xe_reg_mcr){					\
				 .__reg = XE_REG_INITIALIZER(r_,  ##__VA_ARGS__, .mcr = 1)	\
				 })

static inline bool xe_reg_is_valid(struct xe_reg r)
{
	return r.addr;
}

#endif