drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/fbsr.c
Extension
.c
Size
8689 bytes
Lines
328
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

struct fbsr_item {
	const char *type;
	u64 addr;
	u64 size;

	struct list_head head;
};

struct fbsr {
	struct list_head items;

	u64 size;
	int regions;

	struct nvkm_gsp_client client;
	struct nvkm_gsp_device device;

	u64 hmemory;
	u64 sys_offset;
};

int
r535_fbsr_memlist(struct nvkm_gsp_device *device, u32 handle, enum nvkm_memory_target aper,
		  u64 phys, u64 size, struct sg_table *sgt, struct nvkm_gsp_object *object)
{
	struct nvkm_gsp_client *client = device->object.client;
	struct nvkm_gsp *gsp = client->gsp;
	const u32 pages = size / GSP_PAGE_SIZE;
	rpc_alloc_memory_v13_01 *rpc;
	int ret;

	rpc = nvkm_gsp_rpc_get(gsp, NV_VGPU_MSG_FUNCTION_ALLOC_MEMORY,
			       sizeof(*rpc) + pages * sizeof(rpc->pteDesc.pte_pde[0]));
	if (IS_ERR(rpc))
		return PTR_ERR(rpc);

	rpc->hClient = client->object.handle;
	rpc->hDevice = device->object.handle;
	rpc->hMemory = handle;
	if (aper == NVKM_MEM_TARGET_HOST) {
		rpc->hClass = NV01_MEMORY_LIST_SYSTEM;
		rpc->flags = NVDEF(NVOS02, FLAGS, PHYSICALITY, NONCONTIGUOUS) |
			     NVDEF(NVOS02, FLAGS, LOCATION, PCI) |
			     NVDEF(NVOS02, FLAGS, MAPPING, NO_MAP);
	} else {
		rpc->hClass = NV01_MEMORY_LIST_FBMEM;
		rpc->flags = NVDEF(NVOS02, FLAGS, PHYSICALITY, CONTIGUOUS) |
			     NVDEF(NVOS02, FLAGS, LOCATION, VIDMEM) |
			     NVDEF(NVOS02, FLAGS, MAPPING, NO_MAP);
		rpc->format = 6; /* NV_MMU_PTE_KIND_GENERIC_MEMORY */
	}
	rpc->pteAdjust = 0;
	rpc->length = size;
	rpc->pageCount = pages;
	rpc->pteDesc.idr = 0;
	rpc->pteDesc.reserved1 = 0;
	rpc->pteDesc.length = pages;

	if (sgt) {
		struct scatterlist *sgl;
		int pte = 0, idx;

		for_each_sgtable_dma_sg(sgt, sgl, idx) {
			for (int i = 0; i < sg_dma_len(sgl) / GSP_PAGE_SIZE; i++)
				rpc->pteDesc.pte_pde[pte++].pte = (sg_dma_address(sgl) >> 12) + i;

		}
	} else {
		for (int i = 0; i < pages; i++)
			rpc->pteDesc.pte_pde[i].pte = (phys >> 12) + i;
	}

	ret = nvkm_gsp_rpc_wr(gsp, rpc, NVKM_GSP_RPC_REPLY_POLL);
	if (ret)
		return ret;

	object->client = device->object.client;
	object->parent = &device->object;
	object->handle = handle;
	return 0;
}

static int
fbsr_send(struct fbsr *fbsr, struct fbsr_item *item)
{
	NV2080_CTRL_INTERNAL_FBSR_SEND_REGION_INFO_PARAMS *ctrl;
	struct nvkm_gsp *gsp = fbsr->client.gsp;
	struct nvkm_gsp_object memlist;
	int ret;

Annotation

Implementation Notes