drivers/gpu/drm/xe/xe_sriov.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/xe/xe_sriov.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xe/xe_sriov.c
Extension
.c
Size
4493 bytes
Lines
177
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: MIT
/*
 * Copyright © 2023 Intel Corporation
 */

#include <linux/fault-inject.h>

#include <drm/drm_managed.h>

#include "regs/xe_regs.h"

#include "xe_assert.h"
#include "xe_device.h"
#include "xe_mmio.h"
#include "xe_sriov.h"
#include "xe_sriov_pf.h"
#include "xe_sriov_vf.h"
#include "xe_sriov_vf_ccs.h"

/**
 * xe_sriov_mode_to_string - Convert enum value to string.
 * @mode: the &xe_sriov_mode to convert
 *
 * Returns: SR-IOV mode as a user friendly string.
 */
const char *xe_sriov_mode_to_string(enum xe_sriov_mode mode)
{
	switch (mode) {
	case XE_SRIOV_MODE_NONE:
		return "none";
	case XE_SRIOV_MODE_PF:
		return "SR-IOV PF";
	case XE_SRIOV_MODE_VF:
		return "SR-IOV VF";
	default:
		return "<invalid>";
	}
}

static bool test_is_vf(struct xe_device *xe)
{
	u32 value = xe_mmio_read32(xe_root_tile_mmio(xe), VF_CAP_REG);

	return value & VF_CAP;
}

/**
 * xe_sriov_probe_early - Probe a SR-IOV mode.
 * @xe: the &xe_device to probe mode on
 *
 * This function should be called only once and as soon as possible during
 * driver probe to detect whether we are running a SR-IOV Physical Function
 * (PF) or a Virtual Function (VF) device.
 *
 * SR-IOV PF mode detection is based on PCI @dev_is_pf() function.
 * SR-IOV VF mode detection is based on dedicated MMIO register read.
 */
void xe_sriov_probe_early(struct xe_device *xe)
{
	struct pci_dev *pdev = to_pci_dev(xe->drm.dev);
	enum xe_sriov_mode mode = XE_SRIOV_MODE_NONE;
	bool has_sriov = xe->info.has_sriov;

	if (has_sriov) {
		if (test_is_vf(xe))
			mode = XE_SRIOV_MODE_VF;
		else if (xe_sriov_pf_readiness(xe))
			mode = XE_SRIOV_MODE_PF;
	} else if (pci_sriov_get_totalvfs(pdev)) {
		/*
		 * Even if we have not enabled SR-IOV support using the
		 * platform specific has_sriov flag, the hardware may still
		 * report SR-IOV capability and the PCI layer may wrongly
		 * advertise driver support to enable VFs. Explicitly reset
		 * the number of supported VFs to zero to avoid confusion.
		 */
		drm_info(&xe->drm, "Support for SR-IOV is not available\n");
		pci_sriov_set_totalvfs(pdev, 0);
	}

	xe_assert(xe, !xe->sriov.__mode);
	xe->sriov.__mode = mode;
	xe_assert(xe, xe->sriov.__mode);

	if (IS_SRIOV(xe))
		drm_info(&xe->drm, "Running in %s mode\n",
			 xe_sriov_mode_to_string(xe_device_sriov_mode(xe)));
}

static void fini_sriov(struct drm_device *drm, void *arg)

Annotation

Implementation Notes