drivers/gpu/drm/nouveau/nvkm/subdev/fault/tu102.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nvkm/subdev/fault/tu102.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/subdev/fault/tu102.c
Extension
.c
Size
5658 bytes
Lines
191
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

#include "priv.h"

#include <core/memory.h>
#include <subdev/gsp.h>
#include <subdev/mc.h>
#include <subdev/mmu.h>
#include <subdev/vfn.h>
#include <engine/fifo.h>

#include <nvif/class.h>

static irqreturn_t
tu102_fault_buffer_notify(struct nvkm_inth *inth)
{
	struct nvkm_fault_buffer *buffer = container_of(inth, typeof(*buffer), inth);

	nvkm_event_ntfy(&buffer->fault->event, buffer->id, NVKM_FAULT_BUFFER_EVENT_PENDING);
	return IRQ_HANDLED;
}

static void
tu102_fault_buffer_intr(struct nvkm_fault_buffer *buffer, bool enable)
{
	if (enable)
		nvkm_inth_allow(&buffer->inth);
	else
		nvkm_inth_block(&buffer->inth);
}

static void
tu102_fault_buffer_fini(struct nvkm_fault_buffer *buffer)
{
	struct nvkm_device *device = buffer->fault->subdev.device;
	const u32 foff = buffer->id * 0x20;

	nvkm_mask(device, 0xb83010 + foff, 0x80000000, 0x00000000);
}

static void
tu102_fault_buffer_init(struct nvkm_fault_buffer *buffer)
{
	struct nvkm_device *device = buffer->fault->subdev.device;
	const u32 foff = buffer->id * 0x20;

	nvkm_mask(device, 0xb83010 + foff, 0xc0000000, 0x40000000);
	nvkm_wr32(device, 0xb83004 + foff, upper_32_bits(buffer->addr));
	nvkm_wr32(device, 0xb83000 + foff, lower_32_bits(buffer->addr));
	nvkm_mask(device, 0xb83010 + foff, 0x80000000, 0x80000000);
}

static void
tu102_fault_buffer_info(struct nvkm_fault_buffer *buffer)
{
	struct nvkm_device *device = buffer->fault->subdev.device;
	const u32 foff = buffer->id * 0x20;

	nvkm_mask(device, 0xb83010 + foff, 0x40000000, 0x40000000);

	buffer->entries = nvkm_rd32(device, 0xb83010 + foff) & 0x000fffff;
	buffer->get = 0xb83008 + foff;
	buffer->put = 0xb8300c + foff;
}

static irqreturn_t
tu102_fault_info_fault(struct nvkm_inth *inth)
{
	struct nvkm_fault *fault = container_of(inth, typeof(*fault), info_fault);
	struct nvkm_subdev *subdev = &fault->subdev;
	struct nvkm_device *device = subdev->device;
	struct nvkm_fault_data info;
	const u32 addrlo = nvkm_rd32(device, 0xb83080);
	const u32 addrhi = nvkm_rd32(device, 0xb83084);
	const u32  info0 = nvkm_rd32(device, 0xb83088);
	const u32 insthi = nvkm_rd32(device, 0xb8308c);
	const u32  info1 = nvkm_rd32(device, 0xb83090);

	info.addr = ((u64)addrhi << 32) | addrlo;
	info.inst = ((u64)insthi << 32) | (info0 & 0xfffff000);
	info.time = 0;
	info.engine = (info0 & 0x000000ff);
	info.valid  = (info1 & 0x80000000) >> 31;
	info.gpc    = (info1 & 0x1f000000) >> 24;
	info.hub    = (info1 & 0x00100000) >> 20;
	info.access = (info1 & 0x000f0000) >> 16;
	info.client = (info1 & 0x00007f00) >> 8;
	info.reason = (info1 & 0x0000001f);

	nvkm_fifo_fault(device->fifo, &info);

	nvkm_wr32(device, 0xb83094, 0x80000000);

Annotation

Implementation Notes