summaryrefslogtreecommitdiff
path: root/tools/testing/selftests/vfio/lib/drivers/nv_falcon/hw.h
blob: edce130fd008fca606be660b4f2cf495cce3faa8 (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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Copyright (c) 2026, NVIDIA CORPORATION & AFFILIATES.  All rights reserved.
 */
#ifndef _NV_FALCON_HW_H_
#define _NV_FALCON_HW_H_

#include <linux/types.h>

/* PMC (Power Management Controller) Registers */
#define NV_PMC_BOOT_0					0x00000000
#define NV_PMC_ENABLE					0x00000200
#define NV_PMC_ENABLE_PWR				0x00002000
#define NV_PMC_ENABLE_HUB				0x20000000

/* Falcon Base Pages for Different Engines */
#define NV_PPWR_FALCON_BASE				0x10a000
#define NV_PGSP_FALCON_BASE				0x110000

/* Falcon Common Register Offsets (relative to base_page) */
#define NV_FALCON_DMACTL_OFFSET				0x010c
#define NV_FALCON_ENGINE_RESET_OFFSET			0x03c0

/* DMEM Control Register Flags */
#define NV_PPWR_FALCON_DMEMC_AINCR_TRUE			0x01000000
#define NV_PPWR_FALCON_DMEMC_AINCW_TRUE			0x02000000

/* Falcon DMEM port offsets (for port 0) */
#define NV_FALCON_DMEMC_OFFSET				0x1c0
#define NV_FALCON_DMEMD_OFFSET				0x1c4

/* DMA Register Offsets (relative to base_page) */
#define NV_FALCON_DMA_ADDR_LOW_OFFSET			0x110
#define NV_FALCON_DMA_MEM_OFFSET			0x114
#define NV_FALCON_DMA_CMD_OFFSET			0x118
#define NV_FALCON_DMA_BLOCK_OFFSET			0x11c
#define NV_FALCON_DMA_ADDR_HIGH_OFFSET			0x128

/* DMA Global Address Top Bits Register */
#define NV_GPU_DMA_ADDR_TOP_BITS_REG			0x100f04

/* DMA Command Register Bit Definitions */
#define NV_FALCON_DMA_CMD_WRITE_BIT			0x20
#define NV_FALCON_DMA_CMD_SIZE_SHIFT			8
#define NV_FALCON_DMA_CMD_DONE_BIT			0x2

/*
 * Falcon DMA is synchronous, so a transfer size and count larger than
 * its per-operation maximum adds no value.
 */

/* DMA block size and alignment */
#define NV_FALCON_DMA_MIN_TRANSFER_SIZE			4
#define NV_FALCON_DMA_MAX_TRANSFER_SIZE			256
#define NV_FALCON_DMA_BLOCK_SIZE			256
#define NV_FALCON_DMA_MAX_TRANSFER_COUNT		1

/* DMACTL register bits */
#define NV_FALCON_DMACTL_DMEM_SCRUBBING			0x1
#define NV_FALCON_DMACTL_READY_MASK			0x6

/* Falcon Core Selection Register */
#define NV_FALCON_CORE_SELECT_OFFSET			0x1668
#define NV_FALCON_CORE_SELECT_MASK			0x30

/* Falcon mailbox register (for Ada+ reset check) */
#define NV_FALCON_MAILBOX_TEST_OFFSET			0x40c
#define NV_FALCON_MAILBOX_RESET_MAGIC			0xbadf5620

/* Falcon Message Queue Register Offsets (relative to base_page) */
#define NV_FALCON_QUEUE_HEAD_BASE_OFFSET		0x2c00
#define NV_FALCON_QUEUE_TAIL_BASE_OFFSET		0x2c04
#define NV_FALCON_QUEUE_STRIDE				0x8
#define NV_FALCON_MSG_QUEUE_HEAD_BASE_OFFSET		0x2c80
#define NV_FALCON_MSG_QUEUE_TAIL_BASE_OFFSET		0x2c84

/* FSP Falcon Base Pages */
#define NV_FSP_FALCON_BASE				0x8f0100
/* base_page = cpuctl & ~0xfff */
#define NV_FSP_FALCON_BASE_PAGE				0x8f0000
#define NV_FSP_EMEM_BASE				0x8f2000

/* FSP EMEM Port Offsets (relative to FSP EMEM base) */
#define NV_FSP_EMEMC_OFFSET				0xac0
#define NV_FSP_EMEMD_OFFSET				0xac4
#define NV_FSP_EMEM_PORT_STRIDE				0x8

/* EMEM Control Register Flags (same as DMEM) */
#define NV_FALCON_EMEMC_AINCR				0x01000000
#define NV_FALCON_EMEMC_AINCW				0x02000000

/* FSP RPC channel configuration */
#define NV_FSP_RPC_CHANNEL_SIZE				1024
#define NV_FSP_RPC_MAX_PACKET_SIZE			1024
#define NV_FSP_RPC_CHANNEL_HOPPER			2
#define NV_FSP_RPC_EMEM_BASE					\
	(NV_FSP_RPC_CHANNEL_HOPPER * NV_FSP_RPC_CHANNEL_SIZE)

/* FSP EMEM port 2 registers (pre-computed for Hopper channel 2) */
#define NV_FSP_EMEM_PORT2_CTRL		(NV_FSP_EMEM_BASE + NV_FSP_EMEMC_OFFSET + \
					 NV_FSP_RPC_CHANNEL_HOPPER * NV_FSP_EMEM_PORT_STRIDE)
#define NV_FSP_EMEM_PORT2_DATA		(NV_FSP_EMEM_BASE + NV_FSP_EMEMD_OFFSET + \
					 NV_FSP_RPC_CHANNEL_HOPPER * NV_FSP_EMEM_PORT_STRIDE)

/* FSP queue register offsets (pre-computed for Hopper channel 2) */
#define NV_FSP_QUEUE_HEAD	\
	(NV_FSP_FALCON_BASE_PAGE + NV_FALCON_QUEUE_HEAD_BASE_OFFSET + \
	 NV_FSP_RPC_CHANNEL_HOPPER * NV_FALCON_QUEUE_STRIDE)
#define NV_FSP_QUEUE_TAIL	\
	(NV_FSP_FALCON_BASE_PAGE + NV_FALCON_QUEUE_TAIL_BASE_OFFSET + \
	 NV_FSP_RPC_CHANNEL_HOPPER * NV_FALCON_QUEUE_STRIDE)
#define NV_FSP_MSG_QUEUE_HEAD	\
	(NV_FSP_FALCON_BASE_PAGE + NV_FALCON_MSG_QUEUE_HEAD_BASE_OFFSET + \
	 NV_FSP_RPC_CHANNEL_HOPPER * NV_FALCON_QUEUE_STRIDE)
#define NV_FSP_MSG_QUEUE_TAIL	\
	(NV_FSP_FALCON_BASE_PAGE + NV_FALCON_MSG_QUEUE_TAIL_BASE_OFFSET + \
	 NV_FSP_RPC_CHANNEL_HOPPER * NV_FALCON_QUEUE_STRIDE)

/* MCTP Header */
#define NV_MCTP_HDR_SEID_SHIFT				16
#define NV_MCTP_HDR_SEID_MASK				0xff
#define NV_MCTP_HDR_SEQ_SHIFT				28
#define NV_MCTP_HDR_SEQ_MASK				0x3
#define NV_MCTP_HDR_EOM_BIT				0x40000000
#define NV_MCTP_HDR_SOM_BIT				0x80000000

/* MCTP Message Header */
#define NV_MCTP_MSG_TYPE_SHIFT				0
#define NV_MCTP_MSG_TYPE_MASK				0x7f
#define NV_MCTP_MSG_TYPE_VENDOR_DEFINED			0x7e
#define NV_MCTP_MSG_VENDOR_ID_SHIFT			8
#define NV_MCTP_MSG_VENDOR_ID_MASK			0xffff
#define NV_MCTP_MSG_VENDOR_ID_NVIDIA			0x10de
#define NV_MCTP_MSG_NVDM_TYPE_SHIFT			24
#define NV_MCTP_MSG_NVDM_TYPE_MASK			0xff

/* NVDM response type */
#define NV_NVDM_TYPE_RESPONSE				0x15

/* Minimum response size: mctp_hdr + msg_hdr + status_hdr + type + status */
#define NV_FSP_RPC_MIN_RESPONSE_WORDS			5

/* FBIF (Frame Buffer Interface) Registers */
/* Legacy PMU FBIF offsets (Kepler, Maxwell Gen1) */
#define NV_PMU_LEGACY_FBIF_CTL_OFFSET			0x624
#define NV_PMU_LEGACY_FBIF_TRANSCFG_OFFSET		0x600

/* PMU FBIF offsets */
#define NV_PMU_FBIF_CTL_OFFSET				0xe24
#define NV_PMU_FBIF_TRANSCFG_OFFSET			0xe00

/* GSP FBIF offsets */
#define NV_GSP_FBIF_CTL_OFFSET				0x624
#define NV_GSP_FBIF_TRANSCFG_OFFSET			0x600

/* OFA Falcon Base Page and FBIF offsets (used for Hopper+ DMA) */
#define NV_OFA_FALCON_BASE				0x844000
#define NV_OFA_FBIF_CTL_OFFSET				0x424
#define NV_OFA_FBIF_TRANSCFG_OFFSET			0x400

/* OFA DMA support check register (Hopper+) */
#define NV_OFA_DMA_SUPPORT_CHECK_REG			0x8443c0

/* FSP NVDM command types */
#define NV_NVDM_TYPE_FBDMA				0x22
#define NV_FBDMA_SUBCMD_ENABLE				0x1

/* FBIF CTL2 offset (relative to fbif_ctl) */
#define NV_FBIF_CTL2_OFFSET				0x60

/* FBIF TRANSCFG register bits */
#define NV_FBIF_TRANSCFG_TARGET_MASK			0x3
#define NV_FBIF_TRANSCFG_SYSMEM_DEFAULT			0x5

/* FBIF CTL register bits */
#define NV_FBIF_CTL_ALLOW_PHYS_MODE			0x10
#define NV_FBIF_CTL_ALLOW_FULL_PHYS_MODE		0x80

/* Memory clear register offsets */
#define NV_MEM_CLEAR_OFFSET				0x100b20
#define NV_BOOT_COMPLETE_OFFSET				0x118234
#define NV_BOOT_COMPLETE_SUCCESS			0x3ff

/* FSP boot complete register (Hopper+) */
#define NV_FSP_BOOT_COMPLETE_OFFSET			0x200bc
#define NV_FSP_BOOT_COMPLETE_SUCCESS			0xff

enum gpu_arch {
	GPU_ARCH_UNKNOWN = -1,
	GPU_ARCH_KEPLER = 0,
	GPU_ARCH_MAXWELL_GEN1,
	GPU_ARCH_MAXWELL_GEN2,
	GPU_ARCH_PASCAL,
	GPU_ARCH_PASCAL_10X,
	GPU_ARCH_VOLTA,
	GPU_ARCH_TURING,
	GPU_ARCH_AMPERE,
	GPU_ARCH_ADA,
	GPU_ARCH_HOPPER,
};

enum falcon_type {
	FALCON_TYPE_PMU_LEGACY = 0,
	FALCON_TYPE_PMU,
	FALCON_TYPE_GSP,
	FALCON_TYPE_OFA,
};

struct falcon {
	u32 base_page;
	u32 dmactl;
	u32 engine_reset;
	u32 fbif_ctl;
	u32 fbif_ctl2;
	u32 fbif_transcfg;
	u32 dmem_control_reg;
	u32 dmem_data_reg;
	bool no_outside_reset;
};

struct gpu_properties {
	u32 pmc_enable_mask;
	bool memory_clear_supported;
	enum falcon_type falcon_type;
};

static const u32 verified_gpu_map[] = {
	0x0e40a0a2,	/* K520 */
	0x0e6000a1,	/* GTX660 */
	0x0e63a0a1,	/* K4000 */
	0x0f22d0a1,	/* K80 */
	0x108000a1,	/* GT635 */
	0x117010a2,	/* GTX750 */
	0x117020a2,	/* GTX745 */
	0x124320a1,	/* M60 */
	0x130000a1,	/* P100 */
	0x134000a1,	/* P4 */
	0x132000a1,	/* P40 */
	0x140000a1,	/* V100 */
	0x164000a1,	/* T4 */
	0xb77000a1,	/* A16 */
	0x170000a1,	/* A100 */
	0xb72000a1,	/* A10 */
	0x180000a1,	/* H100 */
	0x194000a1,	/* L4 */
	0x192000a1,	/* L40S */
};

#define VERIFIED_GPU_MAP_SIZE ARRAY_SIZE(verified_gpu_map)

static const struct gpu_properties gpu_properties_map[] = {
	[GPU_ARCH_KEPLER] = {
		.pmc_enable_mask = NV_PMC_ENABLE_PWR | NV_PMC_ENABLE_HUB,
		.memory_clear_supported = false,
		.falcon_type = FALCON_TYPE_PMU_LEGACY,
	},
	[GPU_ARCH_MAXWELL_GEN1] = {
		.pmc_enable_mask = NV_PMC_ENABLE_PWR | NV_PMC_ENABLE_HUB,
		.memory_clear_supported = false,
		.falcon_type = FALCON_TYPE_PMU_LEGACY,
	},
	[GPU_ARCH_MAXWELL_GEN2] = {
		.pmc_enable_mask = NV_PMC_ENABLE_PWR,
		.memory_clear_supported = false,
		.falcon_type = FALCON_TYPE_PMU,
	},
	[GPU_ARCH_PASCAL] = {
		.pmc_enable_mask = NV_PMC_ENABLE_PWR,
		.memory_clear_supported = false,
		.falcon_type = FALCON_TYPE_PMU,
	},
	[GPU_ARCH_PASCAL_10X] = {
		.pmc_enable_mask = 0,
		.memory_clear_supported = false,
		.falcon_type = FALCON_TYPE_PMU,
	},
	[GPU_ARCH_VOLTA] = {
		.pmc_enable_mask = 0,
		.memory_clear_supported = false,
		.falcon_type = FALCON_TYPE_GSP,
	},
	[GPU_ARCH_TURING] = {
		.pmc_enable_mask = 0,
		.memory_clear_supported = true,
		.falcon_type = FALCON_TYPE_GSP,
	},
	[GPU_ARCH_AMPERE] = {
		.pmc_enable_mask = 0,
		.memory_clear_supported = true,
		.falcon_type = FALCON_TYPE_GSP,
	},
	[GPU_ARCH_ADA] = {
		.pmc_enable_mask = 0,
		.memory_clear_supported = true,
		.falcon_type = FALCON_TYPE_PMU,
	},
	[GPU_ARCH_HOPPER] = {
		.pmc_enable_mask = 0,
		.memory_clear_supported = true,
		.falcon_type = FALCON_TYPE_OFA,
	},
};

static const struct falcon falcon_map[] = {
	[FALCON_TYPE_PMU_LEGACY] = {
		.base_page = NV_PPWR_FALCON_BASE,
		.dmactl = NV_PPWR_FALCON_BASE + NV_FALCON_DMACTL_OFFSET,
		.engine_reset = NV_PPWR_FALCON_BASE + NV_FALCON_ENGINE_RESET_OFFSET,
		.fbif_ctl = NV_PPWR_FALCON_BASE + NV_PMU_LEGACY_FBIF_CTL_OFFSET,
		.fbif_ctl2 = NV_PPWR_FALCON_BASE +
			     NV_PMU_LEGACY_FBIF_CTL_OFFSET + NV_FBIF_CTL2_OFFSET,
		.fbif_transcfg = NV_PPWR_FALCON_BASE + NV_PMU_LEGACY_FBIF_TRANSCFG_OFFSET,
		.dmem_control_reg = NV_PPWR_FALCON_BASE + NV_FALCON_DMEMC_OFFSET,
		.dmem_data_reg = NV_PPWR_FALCON_BASE + NV_FALCON_DMEMD_OFFSET,
		.no_outside_reset = false,
	},
	[FALCON_TYPE_PMU] = {
		.base_page = NV_PPWR_FALCON_BASE,
		.dmactl = NV_PPWR_FALCON_BASE + NV_FALCON_DMACTL_OFFSET,
		.engine_reset = NV_PPWR_FALCON_BASE + NV_FALCON_ENGINE_RESET_OFFSET,
		.fbif_ctl = NV_PPWR_FALCON_BASE + NV_PMU_FBIF_CTL_OFFSET,
		.fbif_ctl2 = NV_PPWR_FALCON_BASE + NV_PMU_FBIF_CTL_OFFSET + NV_FBIF_CTL2_OFFSET,
		.fbif_transcfg = NV_PPWR_FALCON_BASE + NV_PMU_FBIF_TRANSCFG_OFFSET,
		.dmem_control_reg = NV_PPWR_FALCON_BASE + NV_FALCON_DMEMC_OFFSET,
		.dmem_data_reg = NV_PPWR_FALCON_BASE + NV_FALCON_DMEMD_OFFSET,
		.no_outside_reset = false,
	},
	[FALCON_TYPE_GSP] = {
		.base_page = NV_PGSP_FALCON_BASE,
		.dmactl = NV_PGSP_FALCON_BASE + NV_FALCON_DMACTL_OFFSET,
		.engine_reset = NV_PGSP_FALCON_BASE + NV_FALCON_ENGINE_RESET_OFFSET,
		.fbif_ctl = NV_PGSP_FALCON_BASE + NV_GSP_FBIF_CTL_OFFSET,
		.fbif_ctl2 = NV_PGSP_FALCON_BASE + NV_GSP_FBIF_CTL_OFFSET + NV_FBIF_CTL2_OFFSET,
		.fbif_transcfg = NV_PGSP_FALCON_BASE + NV_GSP_FBIF_TRANSCFG_OFFSET,
		.dmem_control_reg = NV_PGSP_FALCON_BASE + NV_FALCON_DMEMC_OFFSET,
		.dmem_data_reg = NV_PGSP_FALCON_BASE + NV_FALCON_DMEMD_OFFSET,
		.no_outside_reset = false,
	},
	[FALCON_TYPE_OFA] = {
		.base_page = NV_OFA_FALCON_BASE,
		.dmactl = NV_OFA_FALCON_BASE + NV_FALCON_DMACTL_OFFSET,
		.engine_reset = NV_OFA_FALCON_BASE + NV_FALCON_ENGINE_RESET_OFFSET,
		.fbif_ctl = NV_OFA_FALCON_BASE + NV_OFA_FBIF_CTL_OFFSET,
		.fbif_ctl2 = NV_OFA_FALCON_BASE + NV_OFA_FBIF_CTL_OFFSET + NV_FBIF_CTL2_OFFSET,
		.fbif_transcfg = NV_OFA_FALCON_BASE + NV_OFA_FBIF_TRANSCFG_OFFSET,
		.dmem_control_reg = NV_OFA_FALCON_BASE + NV_FALCON_DMEMC_OFFSET,
		.dmem_data_reg = NV_OFA_FALCON_BASE + NV_FALCON_DMEMD_OFFSET,
		.no_outside_reset = true,
	},
};

#endif /* _NV_FALCON_HW_H_ */