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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c
Extension
.c
Size
65757 bytes
Lines
2369
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

for_each_set_bit(j, adev->vmhubs_mask, AMDGPU_MAX_VMHUBS) {
			hub = &adev->vmhub[j];
			for (i = 0; i < 16; i++) {
				reg = hub->vm_context0_cntl + i;

				/* This works because this interrupt is only
				 * enabled at init/resume and disabled in
				 * fini/suspend, so the overall state doesn't
				 * change over the course of suspend/resume.
				 */
				if (adev->in_s0ix && (j == AMDGPU_GFXHUB(0)))
					continue;

				if (j >= AMDGPU_MMHUB0(0))
					tmp = RREG32_SOC15_IP(MMHUB, reg);
				else
					tmp = RREG32_XCC(reg, j);

				tmp &= ~bits;

				if (j >= AMDGPU_MMHUB0(0))
					WREG32_SOC15_IP(MMHUB, reg, tmp);
				else
					WREG32_XCC(reg, tmp, j);
			}
		}
		break;
	case AMDGPU_IRQ_STATE_ENABLE:
		for_each_set_bit(j, adev->vmhubs_mask, AMDGPU_MAX_VMHUBS) {
			hub = &adev->vmhub[j];
			for (i = 0; i < 16; i++) {
				reg = hub->vm_context0_cntl + i;

				/* This works because this interrupt is only
				 * enabled at init/resume and disabled in
				 * fini/suspend, so the overall state doesn't
				 * change over the course of suspend/resume.
				 */
				if (adev->in_s0ix && (j == AMDGPU_GFXHUB(0)))
					continue;

				if (j >= AMDGPU_MMHUB0(0))
					tmp = RREG32_SOC15_IP(MMHUB, reg);
				else
					tmp = RREG32_XCC(reg, j);

				tmp |= bits;

				if (j >= AMDGPU_MMHUB0(0))
					WREG32_SOC15_IP(MMHUB, reg, tmp);
				else
					WREG32_XCC(reg, tmp, j);
			}
		}
		break;
	default:
		break;
	}

	return 0;
}

static int gmc_v9_0_process_interrupt(struct amdgpu_device *adev,
				      struct amdgpu_irq_src *source,
				      struct amdgpu_iv_entry *entry)
{
	bool retry_fault = !!(entry->src_data[1] &
			      AMDGPU_GMC9_FAULT_SOURCE_DATA_RETRY);
	bool write_fault = !!(entry->src_data[1] &
			      AMDGPU_GMC9_FAULT_SOURCE_DATA_WRITE);
	uint32_t status = 0, cid = 0, rw = 0, fed = 0;
	struct amdgpu_task_info *task_info;
	struct amdgpu_vmhub *hub;
	const char *mmhub_cid;
	const char *hub_name;
	unsigned int vmhub;
	u64 addr;
	uint32_t cam_index = 0;
	int ret, xcc_id = 0;
	uint32_t node_id;

	node_id = entry->node_id;

	addr = (u64)entry->src_data[0] << 12;
	addr |= ((u64)entry->src_data[1] & 0xf) << 44;

	if (entry->client_id == SOC15_IH_CLIENTID_VMC) {
		hub_name = "mmhub0";
		vmhub = AMDGPU_MMHUB0(node_id / 4);
	} else if (entry->client_id == SOC15_IH_CLIENTID_VMC1) {

Annotation

Implementation Notes