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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/amdgpu/aqua_vanjaram.c
Extension
.c
Size
27616 bytes
Lines
965
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 aqua_reg_list {
	uint64_t start_addr;
	uint32_t num_regs;
	uint32_t incrx;
};

#define DW_ADDR_INCR	4

static void aqua_read_smn_ext(struct amdgpu_device *adev,
			      struct amdgpu_smn_reg_data *regdata,
			      uint64_t smn_addr, int i)
{
	regdata->addr =
		smn_addr + amdgpu_reg_get_smn_base64(adev, XGMI_HWIP, i);
	regdata->value = RREG32_PCIE_EXT(regdata->addr);
}

#define smnreg_0x1A340218	0x1A340218
#define smnreg_0x1A3402E4	0x1A3402E4
#define smnreg_0x1A340294	0x1A340294
#define smreg_0x1A380088	0x1A380088

#define NUM_PCIE_SMN_REGS	14

static struct aqua_reg_list pcie_reg_addrs[] = {
	{ smnreg_0x1A340218, 1, 0 },
	{ smnreg_0x1A3402E4, 1, 0 },
	{ smnreg_0x1A340294, 6, DW_ADDR_INCR },
	{ smreg_0x1A380088, 6, DW_ADDR_INCR },
};

static ssize_t aqua_vanjaram_read_pcie_state(struct amdgpu_device *adev,
					     void *buf, size_t max_size)
{
	struct amdgpu_reg_state_pcie_v1_0 *pcie_reg_state;
	uint32_t start_addr, incrx, num_regs, szbuf;
	struct amdgpu_regs_pcie_v1_0 *pcie_regs;
	struct amdgpu_smn_reg_data *reg_data;
	struct pci_dev *us_pdev, *ds_pdev;
	int aer_cap, r, n;

	if (!buf || !max_size)
		return -EINVAL;

	pcie_reg_state = (struct amdgpu_reg_state_pcie_v1_0 *)buf;

	szbuf = sizeof(*pcie_reg_state) +
		amdgpu_reginst_size(1, sizeof(*pcie_regs), NUM_PCIE_SMN_REGS);
	/* Only one instance of pcie regs */
	if (max_size < szbuf)
		return -EOVERFLOW;

	pcie_regs = (struct amdgpu_regs_pcie_v1_0 *)((uint8_t *)buf +
						     sizeof(*pcie_reg_state));
	pcie_regs->inst_header.instance = 0;
	pcie_regs->inst_header.state = AMDGPU_INST_S_OK;
	pcie_regs->inst_header.num_smn_regs = NUM_PCIE_SMN_REGS;

	reg_data = pcie_regs->smn_reg_values;

	for (r = 0; r < ARRAY_SIZE(pcie_reg_addrs); r++) {
		start_addr = pcie_reg_addrs[r].start_addr;
		incrx = pcie_reg_addrs[r].incrx;
		num_regs = pcie_reg_addrs[r].num_regs;
		for (n = 0; n < num_regs; n++) {
			aqua_read_smn(adev, reg_data, start_addr + n * incrx);
			++reg_data;
		}
	}

	ds_pdev = pci_upstream_bridge(adev->pdev);
	us_pdev = pci_upstream_bridge(ds_pdev);

	pcie_capability_read_word(us_pdev, PCI_EXP_DEVSTA,
				  &pcie_regs->device_status);
	pcie_capability_read_word(us_pdev, PCI_EXP_LNKSTA,
				  &pcie_regs->link_status);

	aer_cap = pci_find_ext_capability(us_pdev, PCI_EXT_CAP_ID_ERR);
	if (aer_cap) {
		pci_read_config_dword(us_pdev, aer_cap + PCI_ERR_COR_STATUS,
				      &pcie_regs->pcie_corr_err_status);
		pci_read_config_dword(us_pdev, aer_cap + PCI_ERR_UNCOR_STATUS,
				      &pcie_regs->pcie_uncorr_err_status);
	}

	pci_read_config_dword(us_pdev, PCI_PRIMARY_BUS,
			      &pcie_regs->sub_bus_number_latency);

	pcie_reg_state->common_header.structure_size = szbuf;

Annotation

Implementation Notes