drivers/gpu/drm/radeon/radeon_vm.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/radeon/radeon_vm.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/radeon/radeon_vm.c
Extension
.c
Size
32478 bytes
Lines
1268
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

if (fence == NULL) {
			/* found a free one */
			vm_id->id = i;
			trace_radeon_vm_grab_id(i, ring);
			return NULL;
		}

		if (radeon_fence_is_earlier(fence, best[fence->ring])) {
			best[fence->ring] = fence;
			choices[fence->ring == ring ? 0 : 1] = i;
		}
	}

	for (i = 0; i < 2; ++i) {
		if (choices[i]) {
			vm_id->id = choices[i];
			trace_radeon_vm_grab_id(choices[i], ring);
			return rdev->vm_manager.active[choices[i]];
		}
	}

	/* should never happen */
	BUG();
	return NULL;
}

/**
 * radeon_vm_flush - hardware flush the vm
 *
 * @rdev: radeon_device pointer
 * @vm: vm we want to flush
 * @ring: ring to use for flush
 * @updates: last vm update that is waited for
 *
 * Flush the vm (cayman+).
 *
 * Global and local mutex must be locked!
 */
void radeon_vm_flush(struct radeon_device *rdev,
		     struct radeon_vm *vm,
		     int ring, struct radeon_fence *updates)
{
	uint64_t pd_addr = radeon_bo_gpu_offset(vm->page_directory);
	struct radeon_vm_id *vm_id = &vm->ids[ring];

	if (pd_addr != vm_id->pd_gpu_addr || !vm_id->flushed_updates ||
	    radeon_fence_is_earlier(vm_id->flushed_updates, updates)) {

		trace_radeon_vm_flush(pd_addr, ring, vm->ids[ring].id);
		radeon_fence_unref(&vm_id->flushed_updates);
		vm_id->flushed_updates = radeon_fence_ref(updates);
		vm_id->pd_gpu_addr = pd_addr;
		radeon_ring_vm_flush(rdev, &rdev->ring[ring],
				     vm_id->id, vm_id->pd_gpu_addr);

	}
}

/**
 * radeon_vm_fence - remember fence for vm
 *
 * @rdev: radeon_device pointer
 * @vm: vm we want to fence
 * @fence: fence to remember
 *
 * Fence the vm (cayman+).
 * Set the fence used to protect page table and id.
 *
 * Global and local mutex must be locked!
 */
void radeon_vm_fence(struct radeon_device *rdev,
		     struct radeon_vm *vm,
		     struct radeon_fence *fence)
{
	unsigned vm_id = vm->ids[fence->ring].id;

	radeon_fence_unref(&rdev->vm_manager.active[vm_id]);
	rdev->vm_manager.active[vm_id] = radeon_fence_ref(fence);

	radeon_fence_unref(&vm->ids[fence->ring].last_id_use);
	vm->ids[fence->ring].last_id_use = radeon_fence_ref(fence);
}

/**
 * radeon_vm_bo_find - find the bo_va for a specific vm & bo
 *
 * @vm: requested vm
 * @bo: requested buffer object
 *
 * Find @bo inside the requested vm (cayman+).

Annotation

Implementation Notes