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

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/amd/amdgpu/aldebaran.c
Extension
.c
Size
13446 bytes
Lines
474
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_handler(i, handler, reset_ctl) {
			if (handler->reset_method == reset_context->method)
				return handler;
		}
	}

	dev_dbg(adev->dev, "Reset handler not found!\n");

	return NULL;
}

static inline uint32_t aldebaran_get_ip_block_mask(struct amdgpu_device *adev)
{
	uint32_t ip_block_mask = BIT(AMD_IP_BLOCK_TYPE_GFX) |
				 BIT(AMD_IP_BLOCK_TYPE_SDMA);

	if (adev->aid_mask)
		ip_block_mask |= BIT(AMD_IP_BLOCK_TYPE_IH);

	return ip_block_mask;
}

static int aldebaran_mode2_suspend_ip(struct amdgpu_device *adev)
{
	uint32_t ip_block_mask = aldebaran_get_ip_block_mask(adev);
	uint32_t ip_block;
	int r, i;

	/* Skip suspend of SDMA IP versions >= 4.4.2. They are multi-aid */
	if (adev->aid_mask)
		ip_block_mask &= ~BIT(AMD_IP_BLOCK_TYPE_SDMA);

	amdgpu_device_set_pg_state(adev, AMD_PG_STATE_UNGATE);
	amdgpu_device_set_cg_state(adev, AMD_CG_STATE_UNGATE);

	for (i = adev->num_ip_blocks - 1; i >= 0; i--) {
		ip_block = BIT(adev->ip_blocks[i].version->type);
		if (!(ip_block_mask & ip_block))
			continue;

		r = amdgpu_ip_block_suspend(&adev->ip_blocks[i]);
		if (r)
			return r;
	}

	return 0;
}

static int
aldebaran_mode2_prepare_hwcontext(struct amdgpu_reset_control *reset_ctl,
				  struct amdgpu_reset_context *reset_context)
{
	int r = 0;
	struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;

	dev_dbg(adev->dev, "Aldebaran prepare hw context\n");
	/* Don't suspend on bare metal if we are not going to HW reset the ASIC */
	if (!amdgpu_sriov_vf(adev))
		r = aldebaran_mode2_suspend_ip(adev);

	return r;
}

static void aldebaran_async_reset(struct work_struct *work)
{
	struct amdgpu_reset_handler *handler;
	struct amdgpu_reset_control *reset_ctl =
		container_of(work, struct amdgpu_reset_control, reset_work);
	struct amdgpu_device *adev = (struct amdgpu_device *)reset_ctl->handle;
	int i;

	for_each_handler(i, handler, reset_ctl)	{
		if (handler->reset_method == reset_ctl->active_reset) {
			dev_dbg(adev->dev, "Resetting device\n");
			handler->do_reset(adev);
			break;
		}
	}
}

static int aldebaran_mode2_reset(struct amdgpu_device *adev)
{
	/* disable BM */
	pci_clear_master(adev->pdev);
	adev->asic_reset_res = amdgpu_dpm_mode2_reset(adev);
	return adev->asic_reset_res;
}

static int
aldebaran_mode2_perform_reset(struct amdgpu_reset_control *reset_ctl,

Annotation

Implementation Notes