drivers/accel/ivpu/ivpu_hw.c

Source file repositories/reference/linux-study-clean/drivers/accel/ivpu/ivpu_hw.c

File Facts

System
Linux kernel
Corpus path
drivers/accel/ivpu/ivpu_hw.c
Extension
.c
Size
11310 bytes
Lines
423
Domain
Driver Families
Bucket
drivers/accel
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: GPL-2.0-only
/*
 * Copyright (C) 2020 - 2024 Intel Corporation
 */

#include "ivpu_drv.h"
#include "ivpu_hw.h"
#include "ivpu_hw_btrs.h"
#include "ivpu_hw_ip.h"

#include <asm/msr-index.h>
#include <asm/msr.h>
#include <linux/dmi.h>
#include <linux/fault-inject.h>
#include <linux/pm_runtime.h>

#ifdef CONFIG_FAULT_INJECTION
DECLARE_FAULT_ATTR(ivpu_hw_failure);

static char *ivpu_fail_hw;
module_param_named_unsafe(fail_hw, ivpu_fail_hw, charp, 0444);
MODULE_PARM_DESC(fail_hw, "<interval>,<probability>,<space>,<times>");
#endif

#define FW_SHARED_MEM_ALIGNMENT	SZ_512K /* VPU MTRR limitation */

#define ECC_MCA_SIGNAL_ENABLE_MASK	0xff

static char *platform_to_str(u32 platform)
{
	switch (platform) {
	case IVPU_PLATFORM_SILICON:
		return "SILICON";
	case IVPU_PLATFORM_SIMICS:
		return "SIMICS";
	case IVPU_PLATFORM_FPGA:
		return "FPGA";
	case IVPU_PLATFORM_HSLE:
		return "HSLE";
	default:
		return "Invalid platform";
	}
}

static void platform_init(struct ivpu_device *vdev)
{
	int platform = ivpu_hw_btrs_platform_read(vdev);

	ivpu_dbg(vdev, MISC, "Platform type: %s (%d)\n", platform_to_str(platform), platform);

	switch (platform) {
	case IVPU_PLATFORM_SILICON:
	case IVPU_PLATFORM_SIMICS:
	case IVPU_PLATFORM_FPGA:
	case IVPU_PLATFORM_HSLE:
		vdev->platform = platform;
		break;

	default:
		ivpu_err(vdev, "Invalid platform type: %d\n", platform);
		break;
	}
}

static void wa_init(struct ivpu_device *vdev)
{
	vdev->wa.punit_disabled = false;
	vdev->wa.clear_runtime_mem = false;

	if (ivpu_hw_btrs_gen(vdev) == IVPU_HW_BTRS_MTL)
		vdev->wa.interrupt_clear_with_0 = ivpu_hw_btrs_irqs_clear_with_0_mtl(vdev);

	if ((ivpu_device_id(vdev) == PCI_DEVICE_ID_LNL &&
	     ivpu_revision(vdev) < IVPU_HW_IP_REV_LNL_B0) ||
	    (ivpu_device_id(vdev) == PCI_DEVICE_ID_NVL &&
	     ivpu_revision(vdev) == IVPU_HW_IP_REV_NVL_A0))
		vdev->wa.disable_clock_relinquish = true;

	if (ivpu_test_mode & IVPU_TEST_MODE_CLK_RELINQ_ENABLE)
		vdev->wa.disable_clock_relinquish = false;

	if (ivpu_test_mode & IVPU_TEST_MODE_CLK_RELINQ_DISABLE)
		vdev->wa.disable_clock_relinquish = true;

	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
		vdev->wa.wp0_during_power_up = true;

	if (ivpu_test_mode & IVPU_TEST_MODE_D0I2_DISABLE)
		vdev->wa.disable_d0i2 = true;

Annotation

Implementation Notes