xref: /linux/drivers/gpu/drm/xe/xe_gt_sriov_vf.c (revision 68a052239fc4b351e961f698b824f7654a346091)
1 // SPDX-License-Identifier: MIT
2 /*
3  * Copyright © 2023-2024 Intel Corporation
4  */
5 
6 #include <linux/bitfield.h>
7 #include <linux/bsearch.h>
8 
9 #include <drm/drm_managed.h>
10 #include <drm/drm_print.h>
11 
12 #include "abi/guc_actions_sriov_abi.h"
13 #include "abi/guc_communication_mmio_abi.h"
14 #include "abi/guc_klvs_abi.h"
15 #include "abi/guc_relay_actions_abi.h"
16 #include "regs/xe_gt_regs.h"
17 #include "regs/xe_gtt_defs.h"
18 
19 #include "xe_assert.h"
20 #include "xe_device.h"
21 #include "xe_ggtt.h"
22 #include "xe_gt_sriov_printk.h"
23 #include "xe_gt_sriov_vf.h"
24 #include "xe_gt_sriov_vf_types.h"
25 #include "xe_guc.h"
26 #include "xe_guc_hxg_helpers.h"
27 #include "xe_guc_relay.h"
28 #include "xe_lrc.h"
29 #include "xe_mmio.h"
30 #include "xe_sriov.h"
31 #include "xe_sriov_vf.h"
32 #include "xe_uc_fw.h"
33 #include "xe_wopcm.h"
34 
35 #define make_u64_from_u32(hi, lo) ((u64)((u64)(u32)(hi) << 32 | (u32)(lo)))
36 
37 static int guc_action_vf_reset(struct xe_guc *guc)
38 {
39 	u32 request[GUC_HXG_REQUEST_MSG_MIN_LEN] = {
40 		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
41 		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
42 		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_VF2GUC_VF_RESET),
43 	};
44 	int ret;
45 
46 	ret = xe_guc_mmio_send(guc, request, ARRAY_SIZE(request));
47 
48 	return ret > 0 ? -EPROTO : ret;
49 }
50 
51 #define GUC_RESET_VF_STATE_RETRY_MAX	10
52 static int vf_reset_guc_state(struct xe_gt *gt)
53 {
54 	unsigned int retry = GUC_RESET_VF_STATE_RETRY_MAX;
55 	struct xe_guc *guc = &gt->uc.guc;
56 	int err;
57 
58 	do {
59 		err = guc_action_vf_reset(guc);
60 		if (!err || err != -ETIMEDOUT)
61 			break;
62 	} while (--retry);
63 
64 	if (unlikely(err))
65 		xe_gt_sriov_err(gt, "Failed to reset GuC state (%pe)\n", ERR_PTR(err));
66 	return err;
67 }
68 
69 /**
70  * xe_gt_sriov_vf_reset - Reset GuC VF internal state.
71  * @gt: the &xe_gt
72  *
73  * It requires functional `GuC MMIO based communication`_.
74  *
75  * Return: 0 on success or a negative error code on failure.
76  */
77 int xe_gt_sriov_vf_reset(struct xe_gt *gt)
78 {
79 	if (!xe_device_uc_enabled(gt_to_xe(gt)))
80 		return -ENODEV;
81 
82 	return vf_reset_guc_state(gt);
83 }
84 
85 static int guc_action_match_version(struct xe_guc *guc,
86 				    struct xe_uc_fw_version *wanted,
87 				    struct xe_uc_fw_version *found)
88 {
89 	u32 request[VF2GUC_MATCH_VERSION_REQUEST_MSG_LEN] = {
90 		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
91 		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
92 		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION,
93 			   GUC_ACTION_VF2GUC_MATCH_VERSION),
94 		FIELD_PREP(VF2GUC_MATCH_VERSION_REQUEST_MSG_1_BRANCH, wanted->branch) |
95 		FIELD_PREP(VF2GUC_MATCH_VERSION_REQUEST_MSG_1_MAJOR, wanted->major) |
96 		FIELD_PREP(VF2GUC_MATCH_VERSION_REQUEST_MSG_1_MINOR, wanted->minor),
97 	};
98 	u32 response[GUC_MAX_MMIO_MSG_LEN];
99 	int ret;
100 
101 	BUILD_BUG_ON(VF2GUC_MATCH_VERSION_RESPONSE_MSG_LEN > GUC_MAX_MMIO_MSG_LEN);
102 
103 	ret = xe_guc_mmio_send_recv(guc, request, ARRAY_SIZE(request), response);
104 	if (unlikely(ret < 0))
105 		return ret;
106 
107 	if (unlikely(FIELD_GET(VF2GUC_MATCH_VERSION_RESPONSE_MSG_0_MBZ, response[0])))
108 		return -EPROTO;
109 
110 	memset(found, 0, sizeof(struct xe_uc_fw_version));
111 	found->branch = FIELD_GET(VF2GUC_MATCH_VERSION_RESPONSE_MSG_1_BRANCH, response[1]);
112 	found->major = FIELD_GET(VF2GUC_MATCH_VERSION_RESPONSE_MSG_1_MAJOR, response[1]);
113 	found->minor = FIELD_GET(VF2GUC_MATCH_VERSION_RESPONSE_MSG_1_MINOR, response[1]);
114 	found->patch = FIELD_GET(VF2GUC_MATCH_VERSION_RESPONSE_MSG_1_PATCH, response[1]);
115 
116 	return 0;
117 }
118 
119 static int guc_action_match_version_any(struct xe_guc *guc,
120 					struct xe_uc_fw_version *found)
121 {
122 	struct xe_uc_fw_version wanted = {
123 		.branch = GUC_VERSION_BRANCH_ANY,
124 		.major = GUC_VERSION_MAJOR_ANY,
125 		.minor = GUC_VERSION_MINOR_ANY,
126 		.patch = 0
127 	};
128 
129 	return guc_action_match_version(guc, &wanted, found);
130 }
131 
132 static void vf_minimum_guc_version(struct xe_gt *gt, struct xe_uc_fw_version *ver)
133 {
134 	struct xe_device *xe = gt_to_xe(gt);
135 
136 	memset(ver, 0, sizeof(struct xe_uc_fw_version));
137 
138 	switch (xe->info.platform) {
139 	case XE_TIGERLAKE ... XE_PVC:
140 		/* 1.1 this is current baseline for Xe driver */
141 		ver->branch = 0;
142 		ver->major = 1;
143 		ver->minor = 1;
144 		break;
145 	default:
146 		/* 1.2 has support for the GMD_ID KLV */
147 		ver->branch = 0;
148 		ver->major = 1;
149 		ver->minor = 2;
150 		break;
151 	}
152 }
153 
154 static void vf_wanted_guc_version(struct xe_gt *gt, struct xe_uc_fw_version *ver)
155 {
156 	/* for now it's the same as minimum */
157 	return vf_minimum_guc_version(gt, ver);
158 }
159 
160 static int vf_handshake_with_guc(struct xe_gt *gt)
161 {
162 	struct xe_uc_fw_version *guc_version = &gt->sriov.vf.guc_version;
163 	struct xe_uc_fw_version wanted = {0};
164 	struct xe_guc *guc = &gt->uc.guc;
165 	bool old = false;
166 	int err;
167 
168 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
169 
170 	/* select wanted version - prefer previous (if any) */
171 	if (guc_version->major || guc_version->minor) {
172 		wanted = *guc_version;
173 		old = true;
174 	} else {
175 		vf_wanted_guc_version(gt, &wanted);
176 		xe_gt_assert(gt, wanted.major != GUC_VERSION_MAJOR_ANY);
177 
178 		/* First time we handshake, so record the minimum wanted */
179 		gt->sriov.vf.wanted_guc_version = wanted;
180 	}
181 
182 	err = guc_action_match_version(guc, &wanted, guc_version);
183 	if (unlikely(err))
184 		goto fail;
185 
186 	if (old) {
187 		/* we don't support interface version change */
188 		if (MAKE_GUC_VER_STRUCT(*guc_version) != MAKE_GUC_VER_STRUCT(wanted)) {
189 			xe_gt_sriov_err(gt, "New GuC interface version detected: %u.%u.%u.%u\n",
190 					guc_version->branch, guc_version->major,
191 					guc_version->minor, guc_version->patch);
192 			xe_gt_sriov_info(gt, "Previously used version was: %u.%u.%u.%u\n",
193 					 wanted.branch, wanted.major,
194 					 wanted.minor, wanted.patch);
195 			err = -EREMCHG;
196 			goto fail;
197 		} else {
198 			/* version is unchanged, no need to re-verify it */
199 			return 0;
200 		}
201 	}
202 
203 	/* illegal */
204 	if (guc_version->major > wanted.major) {
205 		err = -EPROTO;
206 		goto unsupported;
207 	}
208 
209 	/* there's no fallback on major version. */
210 	if (guc_version->major != wanted.major) {
211 		err = -ENOPKG;
212 		goto unsupported;
213 	}
214 
215 	/* check against minimum version supported by us */
216 	vf_minimum_guc_version(gt, &wanted);
217 	xe_gt_assert(gt, wanted.major != GUC_VERSION_MAJOR_ANY);
218 	if (MAKE_GUC_VER_STRUCT(*guc_version) < MAKE_GUC_VER_STRUCT(wanted)) {
219 		err = -ENOKEY;
220 		goto unsupported;
221 	}
222 
223 	xe_gt_sriov_dbg(gt, "using GuC interface version %u.%u.%u.%u\n",
224 			guc_version->branch, guc_version->major,
225 			guc_version->minor, guc_version->patch);
226 
227 	return 0;
228 
229 unsupported:
230 	xe_gt_sriov_err(gt, "Unsupported GuC version %u.%u.%u.%u (%pe)\n",
231 			guc_version->branch, guc_version->major,
232 			guc_version->minor, guc_version->patch,
233 			ERR_PTR(err));
234 fail:
235 	xe_gt_sriov_err(gt, "Unable to confirm GuC version %u.%u (%pe)\n",
236 			wanted.major, wanted.minor, ERR_PTR(err));
237 
238 	/* try again with *any* just to query which version is supported */
239 	if (!guc_action_match_version_any(guc, &wanted))
240 		xe_gt_sriov_notice(gt, "GuC reports interface version %u.%u.%u.%u\n",
241 				   wanted.branch, wanted.major, wanted.minor, wanted.patch);
242 	return err;
243 }
244 
245 /**
246  * xe_gt_sriov_vf_bootstrap - Query and setup GuC ABI interface version.
247  * @gt: the &xe_gt
248  *
249  * This function is for VF use only.
250  * It requires functional `GuC MMIO based communication`_.
251  *
252  * Return: 0 on success or a negative error code on failure.
253  */
254 int xe_gt_sriov_vf_bootstrap(struct xe_gt *gt)
255 {
256 	int err;
257 
258 	if (!xe_device_uc_enabled(gt_to_xe(gt)))
259 		return -ENODEV;
260 
261 	err = vf_reset_guc_state(gt);
262 	if (unlikely(err))
263 		return err;
264 
265 	err = vf_handshake_with_guc(gt);
266 	if (unlikely(err))
267 		return err;
268 
269 	return 0;
270 }
271 
272 /**
273  * xe_gt_sriov_vf_guc_versions - Minimum required and found GuC ABI versions
274  * @gt: the &xe_gt
275  * @wanted: pointer to the xe_uc_fw_version to be filled with the wanted version
276  * @found: pointer to the xe_uc_fw_version to be filled with the found version
277  *
278  * This function is for VF use only and it can only be used after successful
279  * version handshake with the GuC.
280  */
281 void xe_gt_sriov_vf_guc_versions(struct xe_gt *gt,
282 				 struct xe_uc_fw_version *wanted,
283 				 struct xe_uc_fw_version *found)
284 {
285 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
286 	xe_gt_assert(gt, gt->sriov.vf.guc_version.major);
287 
288 	if (wanted)
289 		*wanted = gt->sriov.vf.wanted_guc_version;
290 
291 	if (found)
292 		*found = gt->sriov.vf.guc_version;
293 }
294 
295 static int guc_action_vf_notify_resfix_done(struct xe_guc *guc)
296 {
297 	u32 request[GUC_HXG_REQUEST_MSG_MIN_LEN] = {
298 		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
299 		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
300 		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_ACTION_VF2GUC_NOTIFY_RESFIX_DONE),
301 	};
302 	int ret;
303 
304 	ret = xe_guc_mmio_send(guc, request, ARRAY_SIZE(request));
305 
306 	return ret > 0 ? -EPROTO : ret;
307 }
308 
309 /**
310  * xe_gt_sriov_vf_notify_resfix_done - Notify GuC about resource fixups apply completed.
311  * @gt: the &xe_gt struct instance linked to target GuC
312  *
313  * Returns: 0 if the operation completed successfully, or a negative error
314  * code otherwise.
315  */
316 int xe_gt_sriov_vf_notify_resfix_done(struct xe_gt *gt)
317 {
318 	struct xe_guc *guc = &gt->uc.guc;
319 	int err;
320 
321 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
322 
323 	err = guc_action_vf_notify_resfix_done(guc);
324 	if (unlikely(err))
325 		xe_gt_sriov_err(gt, "Failed to notify GuC about resource fixup done (%pe)\n",
326 				ERR_PTR(err));
327 	else
328 		xe_gt_sriov_dbg_verbose(gt, "sent GuC resource fixup done\n");
329 
330 	return err;
331 }
332 
333 static int guc_action_query_single_klv(struct xe_guc *guc, u32 key,
334 				       u32 *value, u32 value_len)
335 {
336 	u32 request[VF2GUC_QUERY_SINGLE_KLV_REQUEST_MSG_LEN] = {
337 		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
338 		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
339 		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION,
340 			   GUC_ACTION_VF2GUC_QUERY_SINGLE_KLV),
341 		FIELD_PREP(VF2GUC_QUERY_SINGLE_KLV_REQUEST_MSG_1_KEY, key),
342 	};
343 	u32 response[GUC_MAX_MMIO_MSG_LEN];
344 	u32 length;
345 	int ret;
346 
347 	BUILD_BUG_ON(VF2GUC_QUERY_SINGLE_KLV_RESPONSE_MSG_MAX_LEN > GUC_MAX_MMIO_MSG_LEN);
348 	ret = xe_guc_mmio_send_recv(guc, request, ARRAY_SIZE(request), response);
349 	if (unlikely(ret < 0))
350 		return ret;
351 
352 	if (unlikely(FIELD_GET(VF2GUC_QUERY_SINGLE_KLV_RESPONSE_MSG_0_MBZ, response[0])))
353 		return -EPROTO;
354 
355 	length = FIELD_GET(VF2GUC_QUERY_SINGLE_KLV_RESPONSE_MSG_0_LENGTH, response[0]);
356 	if (unlikely(length > value_len))
357 		return -EOVERFLOW;
358 	if (unlikely(length < value_len))
359 		return -ENODATA;
360 
361 	switch (value_len) {
362 	default:
363 		xe_gt_WARN_ON(guc_to_gt(guc), value_len > 3);
364 		fallthrough;
365 	case 3:
366 		value[2] = FIELD_GET(VF2GUC_QUERY_SINGLE_KLV_RESPONSE_MSG_3_VALUE96, response[3]);
367 		fallthrough;
368 	case 2:
369 		value[1] = FIELD_GET(VF2GUC_QUERY_SINGLE_KLV_RESPONSE_MSG_2_VALUE64, response[2]);
370 		fallthrough;
371 	case 1:
372 		value[0] = FIELD_GET(VF2GUC_QUERY_SINGLE_KLV_RESPONSE_MSG_1_VALUE32, response[1]);
373 		fallthrough;
374 	case 0:
375 		break;
376 	}
377 
378 	return 0;
379 }
380 
381 static int guc_action_query_single_klv32(struct xe_guc *guc, u32 key, u32 *value32)
382 {
383 	return guc_action_query_single_klv(guc, key, value32, hxg_sizeof(u32));
384 }
385 
386 static int guc_action_query_single_klv64(struct xe_guc *guc, u32 key, u64 *value64)
387 {
388 	u32 value[2];
389 	int err;
390 
391 	err = guc_action_query_single_klv(guc, key, value, hxg_sizeof(value));
392 	if (unlikely(err))
393 		return err;
394 
395 	*value64 = make_u64_from_u32(value[1], value[0]);
396 	return 0;
397 }
398 
399 static bool has_gmdid(struct xe_device *xe)
400 {
401 	return GRAPHICS_VERx100(xe) >= 1270;
402 }
403 
404 /**
405  * xe_gt_sriov_vf_gmdid - Query GMDID over MMIO.
406  * @gt: the &xe_gt
407  *
408  * This function is for VF use only.
409  *
410  * Return: value of GMDID KLV on success or 0 on failure.
411  */
412 u32 xe_gt_sriov_vf_gmdid(struct xe_gt *gt)
413 {
414 	const char *type = xe_gt_is_media_type(gt) ? "media" : "graphics";
415 	struct xe_guc *guc = &gt->uc.guc;
416 	u32 value;
417 	int err;
418 
419 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
420 	xe_gt_assert(gt, !GRAPHICS_VERx100(gt_to_xe(gt)) || has_gmdid(gt_to_xe(gt)));
421 	xe_gt_assert(gt, gt->sriov.vf.guc_version.major > 1 || gt->sriov.vf.guc_version.minor >= 2);
422 
423 	err = guc_action_query_single_klv32(guc, GUC_KLV_GLOBAL_CFG_GMD_ID_KEY, &value);
424 	if (unlikely(err)) {
425 		xe_gt_sriov_err(gt, "Failed to obtain %s GMDID (%pe)\n",
426 				type, ERR_PTR(err));
427 		return 0;
428 	}
429 
430 	xe_gt_sriov_dbg(gt, "%s GMDID = %#x\n", type, value);
431 	return value;
432 }
433 
434 static int vf_get_ggtt_info(struct xe_gt *gt)
435 {
436 	struct xe_gt_sriov_vf_selfconfig *config = &gt->sriov.vf.self_config;
437 	struct xe_guc *guc = &gt->uc.guc;
438 	u64 start, size;
439 	int err;
440 
441 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
442 
443 	err = guc_action_query_single_klv64(guc, GUC_KLV_VF_CFG_GGTT_START_KEY, &start);
444 	if (unlikely(err))
445 		return err;
446 
447 	err = guc_action_query_single_klv64(guc, GUC_KLV_VF_CFG_GGTT_SIZE_KEY, &size);
448 	if (unlikely(err))
449 		return err;
450 
451 	if (config->ggtt_size && config->ggtt_size != size) {
452 		xe_gt_sriov_err(gt, "Unexpected GGTT reassignment: %lluK != %lluK\n",
453 				size / SZ_1K, config->ggtt_size / SZ_1K);
454 		return -EREMCHG;
455 	}
456 
457 	xe_gt_sriov_dbg_verbose(gt, "GGTT %#llx-%#llx = %lluK\n",
458 				start, start + size - 1, size / SZ_1K);
459 
460 	config->ggtt_shift = start - (s64)config->ggtt_base;
461 	config->ggtt_base = start;
462 	config->ggtt_size = size;
463 
464 	return config->ggtt_size ? 0 : -ENODATA;
465 }
466 
467 static int vf_get_lmem_info(struct xe_gt *gt)
468 {
469 	struct xe_gt_sriov_vf_selfconfig *config = &gt->sriov.vf.self_config;
470 	struct xe_guc *guc = &gt->uc.guc;
471 	char size_str[10];
472 	u64 size;
473 	int err;
474 
475 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
476 
477 	err = guc_action_query_single_klv64(guc, GUC_KLV_VF_CFG_LMEM_SIZE_KEY, &size);
478 	if (unlikely(err))
479 		return err;
480 
481 	if (config->lmem_size && config->lmem_size != size) {
482 		xe_gt_sriov_err(gt, "Unexpected LMEM reassignment: %lluM != %lluM\n",
483 				size / SZ_1M, config->lmem_size / SZ_1M);
484 		return -EREMCHG;
485 	}
486 
487 	string_get_size(size, 1, STRING_UNITS_2, size_str, sizeof(size_str));
488 	xe_gt_sriov_dbg_verbose(gt, "LMEM %lluM %s\n", size / SZ_1M, size_str);
489 
490 	config->lmem_size = size;
491 
492 	return config->lmem_size ? 0 : -ENODATA;
493 }
494 
495 static int vf_get_submission_cfg(struct xe_gt *gt)
496 {
497 	struct xe_gt_sriov_vf_selfconfig *config = &gt->sriov.vf.self_config;
498 	struct xe_guc *guc = &gt->uc.guc;
499 	u32 num_ctxs, num_dbs;
500 	int err;
501 
502 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
503 
504 	err = guc_action_query_single_klv32(guc, GUC_KLV_VF_CFG_NUM_CONTEXTS_KEY, &num_ctxs);
505 	if (unlikely(err))
506 		return err;
507 
508 	err = guc_action_query_single_klv32(guc, GUC_KLV_VF_CFG_NUM_DOORBELLS_KEY, &num_dbs);
509 	if (unlikely(err))
510 		return err;
511 
512 	if (config->num_ctxs && config->num_ctxs != num_ctxs) {
513 		xe_gt_sriov_err(gt, "Unexpected CTXs reassignment: %u != %u\n",
514 				num_ctxs, config->num_ctxs);
515 		return -EREMCHG;
516 	}
517 	if (config->num_dbs && config->num_dbs != num_dbs) {
518 		xe_gt_sriov_err(gt, "Unexpected DBs reassignment: %u != %u\n",
519 				num_dbs, config->num_dbs);
520 		return -EREMCHG;
521 	}
522 
523 	xe_gt_sriov_dbg_verbose(gt, "CTXs %u DBs %u\n", num_ctxs, num_dbs);
524 
525 	config->num_ctxs = num_ctxs;
526 	config->num_dbs = num_dbs;
527 
528 	return config->num_ctxs ? 0 : -ENODATA;
529 }
530 
531 static void vf_cache_gmdid(struct xe_gt *gt)
532 {
533 	xe_gt_assert(gt, has_gmdid(gt_to_xe(gt)));
534 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
535 
536 	gt->sriov.vf.runtime.gmdid = xe_gt_sriov_vf_gmdid(gt);
537 }
538 
539 /**
540  * xe_gt_sriov_vf_query_config - Query SR-IOV config data over MMIO.
541  * @gt: the &xe_gt
542  *
543  * This function is for VF use only.
544  *
545  * Return: 0 on success or a negative error code on failure.
546  */
547 int xe_gt_sriov_vf_query_config(struct xe_gt *gt)
548 {
549 	struct xe_device *xe = gt_to_xe(gt);
550 	int err;
551 
552 	err = vf_get_ggtt_info(gt);
553 	if (unlikely(err))
554 		return err;
555 
556 	if (IS_DGFX(xe) && xe_gt_is_main_type(gt)) {
557 		err = vf_get_lmem_info(gt);
558 		if (unlikely(err))
559 			return err;
560 	}
561 
562 	err = vf_get_submission_cfg(gt);
563 	if (unlikely(err))
564 		return err;
565 
566 	if (has_gmdid(xe))
567 		vf_cache_gmdid(gt);
568 
569 	return 0;
570 }
571 
572 /**
573  * xe_gt_sriov_vf_guc_ids - VF GuC context IDs configuration.
574  * @gt: the &xe_gt
575  *
576  * This function is for VF use only.
577  *
578  * Return: number of GuC context IDs assigned to VF.
579  */
580 u16 xe_gt_sriov_vf_guc_ids(struct xe_gt *gt)
581 {
582 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
583 	xe_gt_assert(gt, gt->sriov.vf.guc_version.major);
584 	xe_gt_assert(gt, gt->sriov.vf.self_config.num_ctxs);
585 
586 	return gt->sriov.vf.self_config.num_ctxs;
587 }
588 
589 /**
590  * xe_gt_sriov_vf_lmem - VF LMEM configuration.
591  * @gt: the &xe_gt
592  *
593  * This function is for VF use only.
594  *
595  * Return: size of the LMEM assigned to VF.
596  */
597 u64 xe_gt_sriov_vf_lmem(struct xe_gt *gt)
598 {
599 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
600 	xe_gt_assert(gt, gt->sriov.vf.guc_version.major);
601 	xe_gt_assert(gt, gt->sriov.vf.self_config.lmem_size);
602 
603 	return gt->sriov.vf.self_config.lmem_size;
604 }
605 
606 /**
607  * xe_gt_sriov_vf_ggtt - VF GGTT configuration.
608  * @gt: the &xe_gt
609  *
610  * This function is for VF use only.
611  *
612  * Return: size of the GGTT assigned to VF.
613  */
614 u64 xe_gt_sriov_vf_ggtt(struct xe_gt *gt)
615 {
616 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
617 	xe_gt_assert(gt, gt->sriov.vf.guc_version.major);
618 	xe_gt_assert(gt, gt->sriov.vf.self_config.ggtt_size);
619 
620 	return gt->sriov.vf.self_config.ggtt_size;
621 }
622 
623 /**
624  * xe_gt_sriov_vf_ggtt_base - VF GGTT base offset.
625  * @gt: the &xe_gt
626  *
627  * This function is for VF use only.
628  *
629  * Return: base offset of the GGTT assigned to VF.
630  */
631 u64 xe_gt_sriov_vf_ggtt_base(struct xe_gt *gt)
632 {
633 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
634 	xe_gt_assert(gt, gt->sriov.vf.guc_version.major);
635 	xe_gt_assert(gt, gt->sriov.vf.self_config.ggtt_size);
636 
637 	return gt->sriov.vf.self_config.ggtt_base;
638 }
639 
640 /**
641  * xe_gt_sriov_vf_ggtt_shift - Return shift in GGTT range due to VF migration
642  * @gt: the &xe_gt struct instance
643  *
644  * This function is for VF use only.
645  *
646  * Return: The shift value; could be negative
647  */
648 s64 xe_gt_sriov_vf_ggtt_shift(struct xe_gt *gt)
649 {
650 	struct xe_gt_sriov_vf_selfconfig *config = &gt->sriov.vf.self_config;
651 
652 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
653 	xe_gt_assert(gt, xe_gt_is_main_type(gt));
654 
655 	return config->ggtt_shift;
656 }
657 
658 static int relay_action_handshake(struct xe_gt *gt, u32 *major, u32 *minor)
659 {
660 	u32 request[VF2PF_HANDSHAKE_REQUEST_MSG_LEN] = {
661 		FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
662 		FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
663 		FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION, GUC_RELAY_ACTION_VF2PF_HANDSHAKE),
664 		FIELD_PREP(VF2PF_HANDSHAKE_REQUEST_MSG_1_MAJOR, *major) |
665 		FIELD_PREP(VF2PF_HANDSHAKE_REQUEST_MSG_1_MINOR, *minor),
666 	};
667 	u32 response[VF2PF_HANDSHAKE_RESPONSE_MSG_LEN];
668 	int ret;
669 
670 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
671 
672 	ret = xe_guc_relay_send_to_pf(&gt->uc.guc.relay,
673 				      request, ARRAY_SIZE(request),
674 				      response, ARRAY_SIZE(response));
675 	if (unlikely(ret < 0))
676 		return ret;
677 
678 	if (unlikely(ret != VF2PF_HANDSHAKE_RESPONSE_MSG_LEN))
679 		return -EPROTO;
680 
681 	if (unlikely(FIELD_GET(VF2PF_HANDSHAKE_RESPONSE_MSG_0_MBZ, response[0])))
682 		return -EPROTO;
683 
684 	*major = FIELD_GET(VF2PF_HANDSHAKE_RESPONSE_MSG_1_MAJOR, response[1]);
685 	*minor = FIELD_GET(VF2PF_HANDSHAKE_RESPONSE_MSG_1_MINOR, response[1]);
686 
687 	return 0;
688 }
689 
690 static void vf_connect_pf(struct xe_device *xe, u16 major, u16 minor)
691 {
692 	xe_assert(xe, IS_SRIOV_VF(xe));
693 
694 	xe->sriov.vf.pf_version.major = major;
695 	xe->sriov.vf.pf_version.minor = minor;
696 }
697 
698 static void vf_disconnect_pf(struct xe_device *xe)
699 {
700 	vf_connect_pf(xe, 0, 0);
701 }
702 
703 static int vf_handshake_with_pf(struct xe_gt *gt)
704 {
705 	struct xe_device *xe = gt_to_xe(gt);
706 	u32 major_wanted = GUC_RELAY_VERSION_LATEST_MAJOR;
707 	u32 minor_wanted = GUC_RELAY_VERSION_LATEST_MINOR;
708 	u32 major = major_wanted, minor = minor_wanted;
709 	int err;
710 
711 	err = relay_action_handshake(gt, &major, &minor);
712 	if (unlikely(err))
713 		goto failed;
714 
715 	if (!major && !minor) {
716 		err = -ENODATA;
717 		goto failed;
718 	}
719 
720 	xe_gt_sriov_dbg(gt, "using VF/PF ABI %u.%u\n", major, minor);
721 	vf_connect_pf(xe, major, minor);
722 	return 0;
723 
724 failed:
725 	xe_gt_sriov_err(gt, "Unable to confirm VF/PF ABI version %u.%u (%pe)\n",
726 			major, minor, ERR_PTR(err));
727 	vf_disconnect_pf(xe);
728 	return err;
729 }
730 
731 /**
732  * xe_gt_sriov_vf_connect - Establish connection with the PF driver.
733  * @gt: the &xe_gt
734  *
735  * This function is for VF use only.
736  *
737  * Return: 0 on success or a negative error code on failure.
738  */
739 int xe_gt_sriov_vf_connect(struct xe_gt *gt)
740 {
741 	int err;
742 
743 	err = vf_handshake_with_pf(gt);
744 	if (unlikely(err))
745 		goto failed;
746 
747 	return 0;
748 
749 failed:
750 	xe_gt_sriov_err(gt, "Failed to get version info (%pe)\n", ERR_PTR(err));
751 	return err;
752 }
753 
754 /**
755  * xe_gt_sriov_vf_default_lrcs_hwsp_rebase - Update GGTT references in HWSP of default LRCs.
756  * @gt: the &xe_gt struct instance
757  */
758 void xe_gt_sriov_vf_default_lrcs_hwsp_rebase(struct xe_gt *gt)
759 {
760 	struct xe_hw_engine *hwe;
761 	enum xe_hw_engine_id id;
762 
763 	for_each_hw_engine(hwe, gt, id)
764 		xe_default_lrc_update_memirq_regs_with_address(hwe);
765 }
766 
767 /**
768  * xe_gt_sriov_vf_migrated_event_handler - Start a VF migration recovery,
769  *   or just mark that a GuC is ready for it.
770  * @gt: the &xe_gt struct instance linked to target GuC
771  *
772  * This function shall be called only by VF.
773  */
774 void xe_gt_sriov_vf_migrated_event_handler(struct xe_gt *gt)
775 {
776 	struct xe_device *xe = gt_to_xe(gt);
777 
778 	xe_gt_assert(gt, IS_SRIOV_VF(xe));
779 
780 	set_bit(gt->info.id, &xe->sriov.vf.migration.gt_flags);
781 	/*
782 	 * We need to be certain that if all flags were set, at least one
783 	 * thread will notice that and schedule the recovery.
784 	 */
785 	smp_mb__after_atomic();
786 
787 	xe_gt_sriov_info(gt, "ready for recovery after migration\n");
788 	xe_sriov_vf_start_migration_recovery(xe);
789 }
790 
791 static bool vf_is_negotiated(struct xe_gt *gt, u16 major, u16 minor)
792 {
793 	struct xe_device *xe = gt_to_xe(gt);
794 
795 	xe_gt_assert(gt, IS_SRIOV_VF(xe));
796 
797 	return major == xe->sriov.vf.pf_version.major &&
798 	       minor <= xe->sriov.vf.pf_version.minor;
799 }
800 
801 static int vf_prepare_runtime_info(struct xe_gt *gt, unsigned int num_regs)
802 {
803 	struct vf_runtime_reg *regs = gt->sriov.vf.runtime.regs;
804 	unsigned int regs_size = round_up(num_regs, 4);
805 	struct xe_device *xe = gt_to_xe(gt);
806 
807 	xe_gt_assert(gt, IS_SRIOV_VF(xe));
808 
809 	if (regs) {
810 		if (num_regs <= gt->sriov.vf.runtime.regs_size) {
811 			memset(regs, 0, num_regs * sizeof(*regs));
812 			gt->sriov.vf.runtime.num_regs = num_regs;
813 			return 0;
814 		}
815 
816 		drmm_kfree(&xe->drm, regs);
817 		gt->sriov.vf.runtime.regs = NULL;
818 		gt->sriov.vf.runtime.num_regs = 0;
819 		gt->sriov.vf.runtime.regs_size = 0;
820 	}
821 
822 	regs = drmm_kcalloc(&xe->drm, regs_size, sizeof(*regs), GFP_KERNEL);
823 	if (unlikely(!regs))
824 		return -ENOMEM;
825 
826 	gt->sriov.vf.runtime.regs = regs;
827 	gt->sriov.vf.runtime.num_regs = num_regs;
828 	gt->sriov.vf.runtime.regs_size = regs_size;
829 	return 0;
830 }
831 
832 static int vf_query_runtime_info(struct xe_gt *gt)
833 {
834 	u32 request[VF2PF_QUERY_RUNTIME_REQUEST_MSG_LEN];
835 	u32 response[VF2PF_QUERY_RUNTIME_RESPONSE_MSG_MIN_LEN + 32]; /* up to 16 regs */
836 	u32 limit = (ARRAY_SIZE(response) - VF2PF_QUERY_RUNTIME_RESPONSE_MSG_MIN_LEN) / 2;
837 	u32 count, remaining, num, i;
838 	u32 start = 0;
839 	int ret;
840 
841 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
842 	xe_gt_assert(gt, limit);
843 
844 	/* this is part of the 1.0 PF/VF ABI */
845 	if (!vf_is_negotiated(gt, 1, 0))
846 		return -ENOPKG;
847 
848 	request[0] = FIELD_PREP(GUC_HXG_MSG_0_ORIGIN, GUC_HXG_ORIGIN_HOST) |
849 		     FIELD_PREP(GUC_HXG_MSG_0_TYPE, GUC_HXG_TYPE_REQUEST) |
850 		     FIELD_PREP(GUC_HXG_REQUEST_MSG_0_ACTION,
851 				GUC_RELAY_ACTION_VF2PF_QUERY_RUNTIME) |
852 		     FIELD_PREP(VF2PF_QUERY_RUNTIME_REQUEST_MSG_0_LIMIT, limit);
853 
854 repeat:
855 	request[1] = FIELD_PREP(VF2PF_QUERY_RUNTIME_REQUEST_MSG_1_START, start);
856 	ret = xe_guc_relay_send_to_pf(&gt->uc.guc.relay,
857 				      request, ARRAY_SIZE(request),
858 				      response, ARRAY_SIZE(response));
859 	if (unlikely(ret < 0))
860 		goto failed;
861 
862 	if (unlikely(ret < VF2PF_QUERY_RUNTIME_RESPONSE_MSG_MIN_LEN)) {
863 		ret = -EPROTO;
864 		goto failed;
865 	}
866 	if (unlikely((ret - VF2PF_QUERY_RUNTIME_RESPONSE_MSG_MIN_LEN) % 2)) {
867 		ret = -EPROTO;
868 		goto failed;
869 	}
870 
871 	num = (ret - VF2PF_QUERY_RUNTIME_RESPONSE_MSG_MIN_LEN) / 2;
872 	count = FIELD_GET(VF2PF_QUERY_RUNTIME_RESPONSE_MSG_0_COUNT, response[0]);
873 	remaining = FIELD_GET(VF2PF_QUERY_RUNTIME_RESPONSE_MSG_1_REMAINING, response[1]);
874 
875 	xe_gt_sriov_dbg_verbose(gt, "count=%u num=%u ret=%d start=%u remaining=%u\n",
876 				count, num, ret, start, remaining);
877 
878 	if (unlikely(count != num)) {
879 		ret = -EPROTO;
880 		goto failed;
881 	}
882 
883 	if (start == 0) {
884 		ret = vf_prepare_runtime_info(gt, num + remaining);
885 		if (unlikely(ret < 0))
886 			goto failed;
887 	} else if (unlikely(start + num > gt->sriov.vf.runtime.num_regs)) {
888 		ret = -EPROTO;
889 		goto failed;
890 	}
891 
892 	for (i = 0; i < num; ++i) {
893 		struct vf_runtime_reg *reg = &gt->sriov.vf.runtime.regs[start + i];
894 
895 		reg->offset = response[VF2PF_QUERY_RUNTIME_RESPONSE_MSG_MIN_LEN + 2 * i];
896 		reg->value = response[VF2PF_QUERY_RUNTIME_RESPONSE_MSG_MIN_LEN + 2 * i + 1];
897 	}
898 
899 	if (remaining) {
900 		start += num;
901 		goto repeat;
902 	}
903 
904 	return 0;
905 
906 failed:
907 	vf_prepare_runtime_info(gt, 0);
908 	return ret;
909 }
910 
911 static void vf_show_runtime_info(struct xe_gt *gt)
912 {
913 	struct vf_runtime_reg *vf_regs = gt->sriov.vf.runtime.regs;
914 	unsigned int size = gt->sriov.vf.runtime.num_regs;
915 
916 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
917 
918 	for (; size--; vf_regs++)
919 		xe_gt_sriov_dbg(gt, "runtime(%#x) = %#x\n",
920 				vf_regs->offset, vf_regs->value);
921 }
922 
923 /**
924  * xe_gt_sriov_vf_query_runtime - Query SR-IOV runtime data.
925  * @gt: the &xe_gt
926  *
927  * This function is for VF use only.
928  *
929  * Return: 0 on success or a negative error code on failure.
930  */
931 int xe_gt_sriov_vf_query_runtime(struct xe_gt *gt)
932 {
933 	int err;
934 
935 	err = vf_query_runtime_info(gt);
936 	if (unlikely(err))
937 		goto failed;
938 
939 	if (IS_ENABLED(CONFIG_DRM_XE_DEBUG))
940 		vf_show_runtime_info(gt);
941 
942 	return 0;
943 
944 failed:
945 	xe_gt_sriov_err(gt, "Failed to get runtime info (%pe)\n",
946 			ERR_PTR(err));
947 	return err;
948 }
949 
950 static int vf_runtime_reg_cmp(const void *a, const void *b)
951 {
952 	const struct vf_runtime_reg *ra = a;
953 	const struct vf_runtime_reg *rb = b;
954 
955 	return (int)ra->offset - (int)rb->offset;
956 }
957 
958 static struct vf_runtime_reg *vf_lookup_reg(struct xe_gt *gt, u32 addr)
959 {
960 	struct xe_gt_sriov_vf_runtime *runtime = &gt->sriov.vf.runtime;
961 	struct vf_runtime_reg key = { .offset = addr };
962 
963 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
964 
965 	return bsearch(&key, runtime->regs, runtime->num_regs, sizeof(key),
966 		       vf_runtime_reg_cmp);
967 }
968 
969 /**
970  * xe_gt_sriov_vf_read32 - Get a register value from the runtime data.
971  * @gt: the &xe_gt
972  * @reg: the register to read
973  *
974  * This function is for VF use only.
975  * This function shall be called after VF has connected to PF.
976  * This function is dedicated for registers that VFs can't read directly.
977  *
978  * Return: register value obtained from the PF or 0 if not found.
979  */
980 u32 xe_gt_sriov_vf_read32(struct xe_gt *gt, struct xe_reg reg)
981 {
982 	u32 addr = xe_mmio_adjusted_addr(&gt->mmio, reg.addr);
983 	struct vf_runtime_reg *rr;
984 
985 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
986 	xe_gt_assert(gt, !reg.vf);
987 
988 	if (reg.addr == GMD_ID.addr) {
989 		xe_gt_sriov_dbg_verbose(gt, "gmdid(%#x) = %#x\n",
990 					addr, gt->sriov.vf.runtime.gmdid);
991 		return gt->sriov.vf.runtime.gmdid;
992 	}
993 
994 	rr = vf_lookup_reg(gt, addr);
995 	if (!rr) {
996 		xe_gt_WARN(gt, IS_ENABLED(CONFIG_DRM_XE_DEBUG),
997 			   "VF is trying to read an inaccessible register %#x+%#x\n",
998 			   reg.addr, addr - reg.addr);
999 		return 0;
1000 	}
1001 
1002 	xe_gt_sriov_dbg_verbose(gt, "runtime[%#x] = %#x\n", addr, rr->value);
1003 	return rr->value;
1004 }
1005 
1006 /**
1007  * xe_gt_sriov_vf_write32 - Handle a write to an inaccessible register.
1008  * @gt: the &xe_gt
1009  * @reg: the register to write
1010  * @val: value to write
1011  *
1012  * This function is for VF use only.
1013  * Currently it will trigger a WARN if running on debug build.
1014  */
1015 void xe_gt_sriov_vf_write32(struct xe_gt *gt, struct xe_reg reg, u32 val)
1016 {
1017 	u32 addr = xe_mmio_adjusted_addr(&gt->mmio, reg.addr);
1018 
1019 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
1020 	xe_gt_assert(gt, !reg.vf);
1021 
1022 	/*
1023 	 * In the future, we may want to handle selected writes to inaccessible
1024 	 * registers in some custom way, but for now let's just log a warning
1025 	 * about such attempt, as likely we might be doing something wrong.
1026 	 */
1027 	xe_gt_WARN(gt, IS_ENABLED(CONFIG_DRM_XE_DEBUG),
1028 		   "VF is trying to write %#x to an inaccessible register %#x+%#x\n",
1029 		   val, reg.addr, addr - reg.addr);
1030 }
1031 
1032 /**
1033  * xe_gt_sriov_vf_print_config - Print VF self config.
1034  * @gt: the &xe_gt
1035  * @p: the &drm_printer
1036  *
1037  * This function is for VF use only.
1038  */
1039 void xe_gt_sriov_vf_print_config(struct xe_gt *gt, struct drm_printer *p)
1040 {
1041 	struct xe_gt_sriov_vf_selfconfig *config = &gt->sriov.vf.self_config;
1042 	struct xe_device *xe = gt_to_xe(gt);
1043 	char buf[10];
1044 
1045 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
1046 
1047 	drm_printf(p, "GGTT range:\t%#llx-%#llx\n",
1048 		   config->ggtt_base,
1049 		   config->ggtt_base + config->ggtt_size - 1);
1050 
1051 	string_get_size(config->ggtt_size, 1, STRING_UNITS_2, buf, sizeof(buf));
1052 	drm_printf(p, "GGTT size:\t%llu (%s)\n", config->ggtt_size, buf);
1053 
1054 	drm_printf(p, "GGTT shift on last restore:\t%lld\n", config->ggtt_shift);
1055 
1056 	if (IS_DGFX(xe) && xe_gt_is_main_type(gt)) {
1057 		string_get_size(config->lmem_size, 1, STRING_UNITS_2, buf, sizeof(buf));
1058 		drm_printf(p, "LMEM size:\t%llu (%s)\n", config->lmem_size, buf);
1059 	}
1060 
1061 	drm_printf(p, "GuC contexts:\t%u\n", config->num_ctxs);
1062 	drm_printf(p, "GuC doorbells:\t%u\n", config->num_dbs);
1063 }
1064 
1065 /**
1066  * xe_gt_sriov_vf_print_runtime - Print VF's runtime regs received from PF.
1067  * @gt: the &xe_gt
1068  * @p: the &drm_printer
1069  *
1070  * This function is for VF use only.
1071  */
1072 void xe_gt_sriov_vf_print_runtime(struct xe_gt *gt, struct drm_printer *p)
1073 {
1074 	struct vf_runtime_reg *vf_regs = gt->sriov.vf.runtime.regs;
1075 	unsigned int size = gt->sriov.vf.runtime.num_regs;
1076 
1077 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
1078 
1079 	for (; size--; vf_regs++)
1080 		drm_printf(p, "%#x = %#x\n", vf_regs->offset, vf_regs->value);
1081 }
1082 
1083 /**
1084  * xe_gt_sriov_vf_print_version - Print VF ABI versions.
1085  * @gt: the &xe_gt
1086  * @p: the &drm_printer
1087  *
1088  * This function is for VF use only.
1089  */
1090 void xe_gt_sriov_vf_print_version(struct xe_gt *gt, struct drm_printer *p)
1091 {
1092 	struct xe_device *xe = gt_to_xe(gt);
1093 	struct xe_uc_fw_version *guc_version = &gt->sriov.vf.guc_version;
1094 	struct xe_uc_fw_version *wanted = &gt->sriov.vf.wanted_guc_version;
1095 	struct xe_sriov_vf_relay_version *pf_version = &xe->sriov.vf.pf_version;
1096 	struct xe_uc_fw_version ver;
1097 
1098 	xe_gt_assert(gt, IS_SRIOV_VF(gt_to_xe(gt)));
1099 
1100 	drm_printf(p, "GuC ABI:\n");
1101 
1102 	vf_minimum_guc_version(gt, &ver);
1103 	drm_printf(p, "\tbase:\t%u.%u.%u.*\n", ver.branch, ver.major, ver.minor);
1104 
1105 	drm_printf(p, "\twanted:\t%u.%u.%u.*\n",
1106 		   wanted->branch, wanted->major, wanted->minor);
1107 
1108 	drm_printf(p, "\thandshake:\t%u.%u.%u.%u\n",
1109 		   guc_version->branch, guc_version->major,
1110 		   guc_version->minor, guc_version->patch);
1111 
1112 	drm_printf(p, "PF ABI:\n");
1113 
1114 	drm_printf(p, "\tbase:\t%u.%u\n",
1115 		   GUC_RELAY_VERSION_BASE_MAJOR, GUC_RELAY_VERSION_BASE_MINOR);
1116 	drm_printf(p, "\twanted:\t%u.%u\n",
1117 		   GUC_RELAY_VERSION_LATEST_MAJOR, GUC_RELAY_VERSION_LATEST_MINOR);
1118 	drm_printf(p, "\thandshake:\t%u.%u\n",
1119 		   pf_version->major, pf_version->minor);
1120 }
1121