drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c
Extension
.c
Size
28620 bytes
Lines
1071
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 (task_info) {
			amdgpu_vm_print_task_info(adev, task_info);
			amdgpu_vm_put_task_info(task_info);
		}

		dev_err(adev->dev, "  in page starting at address 0x%016llx from client %d\n",
				addr, entry->client_id);

		/* Only print L2 fault status if the status register could be read and
		 * contains useful information
		 */
		if (status != 0)
			hub->vmhub_funcs->print_l2_protection_fault_status(adev, status);
	}

	return 0;
}

static const struct amdgpu_irq_src_funcs gmc_v11_0_irq_funcs = {
	.set = gmc_v11_0_vm_fault_interrupt_state,
	.process = gmc_v11_0_process_interrupt,
};

static const struct amdgpu_irq_src_funcs gmc_v11_0_ecc_funcs = {
	.set = gmc_v11_0_ecc_interrupt_state,
	.process = amdgpu_umc_process_ecc_irq,
};

static void gmc_v11_0_set_irq_funcs(struct amdgpu_device *adev)
{
	adev->gmc.vm_fault.num_types = 1;
	adev->gmc.vm_fault.funcs = &gmc_v11_0_irq_funcs;

	if (!amdgpu_sriov_vf(adev)) {
		adev->gmc.ecc_irq.num_types = 1;
		adev->gmc.ecc_irq.funcs = &gmc_v11_0_ecc_funcs;
	}
}

/**
 * gmc_v11_0_use_invalidate_semaphore - judge whether to use semaphore
 *
 * @adev: amdgpu_device pointer
 * @vmhub: vmhub type
 *
 */
static bool gmc_v11_0_use_invalidate_semaphore(struct amdgpu_device *adev,
				       uint32_t vmhub)
{
	return ((vmhub == AMDGPU_MMHUB0(0)) &&
		(!amdgpu_sriov_vf(adev)));
}

static bool gmc_v11_0_get_vmid_pasid_mapping_info(
					struct amdgpu_device *adev,
					uint8_t vmid, uint16_t *p_pasid)
{
	*p_pasid = RREG32(SOC15_REG_OFFSET(OSSSYS, 0, regIH_VMID_0_LUT) + vmid) & 0xffff;

	return !!(*p_pasid);
}

/**
 * gmc_v11_0_flush_gpu_tlb - gart tlb flush callback
 *
 * @adev: amdgpu_device pointer
 * @vmid: vm instance to flush
 * @vmhub: which hub to flush
 * @flush_type: the flush type
 *
 * Flush the TLB for the requested page table.
 */
static void gmc_v11_0_flush_gpu_tlb(struct amdgpu_device *adev, uint32_t vmid,
					uint32_t vmhub, uint32_t flush_type)
{
	bool use_semaphore = gmc_v11_0_use_invalidate_semaphore(adev, vmhub);
	struct amdgpu_vmhub *hub = &adev->vmhub[vmhub];
	u32 inv_req = hub->vmhub_funcs->get_invalidate_req(vmid, flush_type);
	/* Use register 17 for GART */
	const unsigned int eng = 17;
	unsigned char hub_ip;
	u32 sem, req, ack;
	unsigned int i;
	u32 tmp;

	if ((vmhub == AMDGPU_GFXHUB(0)) && !adev->gfx.is_poweron)
		return;

	sem = hub->vm_inv_eng0_sem + hub->eng_distance * eng;
	req = hub->vm_inv_eng0_req + hub->eng_distance * eng;

Annotation

Implementation Notes