Commit 4d614ce8 authored by Tao Zhou's avatar Tao Zhou Committed by Alex Deucher
Browse files

drm/amdgpu: add RAS CPER ring buffer



And initialize it, this is a pure software ring to store RAS CPER data.

v2: change ring size to 0x100000
v2: update the initialization of count_dw of cper ring, it's dword
variable
v3: skip VM inv eng for cper
v3: init/fini when aca enabled

Signed-off-by: default avatarTao Zhou <tao.zhou1@amd.com>
Signed-off-by: default avatarXiang Liu <xiang.liu@amd.com>
Reviewed-by: default avatarHawking Zhang <Hawking.Zhang@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent b3060f5b
Loading
Loading
Loading
Loading
+35 −4
Original line number Diff line number Diff line
@@ -382,6 +382,39 @@ int amdgpu_cper_generate_ce_records(struct amdgpu_device *adev,
	return 0;
}

static u64 amdgpu_cper_ring_get_rptr(struct amdgpu_ring *ring)
{
	return *(ring->rptr_cpu_addr);
}

static u64 amdgpu_cper_ring_get_wptr(struct amdgpu_ring *ring)
{
	return ring->wptr;
}

static const struct amdgpu_ring_funcs cper_ring_funcs = {
	.type = AMDGPU_RING_TYPE_CPER,
	.align_mask = 0xff,
	.support_64bit_ptrs = false,
	.get_rptr = amdgpu_cper_ring_get_rptr,
	.get_wptr = amdgpu_cper_ring_get_wptr,
};

static int amdgpu_cper_ring_init(struct amdgpu_device *adev)
{
	struct amdgpu_ring *ring = &(adev->cper.ring_buf);

	ring->adev = NULL;
	ring->ring_obj = NULL;
	ring->use_doorbell = false;
	ring->no_scheduler = true;
	ring->funcs = &cper_ring_funcs;

	sprintf(ring->name, "cper");
	return amdgpu_ring_init(adev, ring, CPER_MAX_RING_SIZE, NULL, 0,
				AMDGPU_RING_PRIO_DEFAULT, NULL);
}

int amdgpu_cper_init(struct amdgpu_device *adev)
{
	mutex_init(&adev->cper.cper_lock);
@@ -389,16 +422,14 @@ int amdgpu_cper_init(struct amdgpu_device *adev)
	adev->cper.enabled = true;
	adev->cper.max_count = CPER_MAX_ALLOWED_COUNT;

	/*TODO: initialize cper ring*/

	return 0;
	return amdgpu_cper_ring_init(adev);
}

int amdgpu_cper_fini(struct amdgpu_device *adev)
{
	adev->cper.enabled = false;

	/*TODO: free cper ring */
	amdgpu_ring_fini(&(adev->cper.ring_buf));
	adev->cper.count = 0;
	adev->cper.wptr = 0;

+2 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include "amdgpu_aca.h"

#define CPER_MAX_ALLOWED_COUNT		0x1000
#define CPER_MAX_RING_SIZE		0X100000
#define HDR_LEN				(sizeof(struct cper_hdr))
#define SEC_DESC_LEN			(sizeof(struct cper_sec_desc))

@@ -62,6 +63,7 @@ struct amdgpu_cper {
	uint32_t wptr;

	void *ring[CPER_MAX_ALLOWED_COUNT];
	struct amdgpu_ring ring_buf;
};

void amdgpu_cper_entry_fill_hdr(struct amdgpu_device *adev,
+4 −2
Original line number Diff line number Diff line
@@ -3091,6 +3091,7 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev)

	amdgpu_fru_get_product_info(adev);

	if (amdgpu_aca_is_enabled(adev))
		r = amdgpu_cper_init(adev);

init_failed:
@@ -3453,6 +3454,7 @@ static int amdgpu_device_ip_fini(struct amdgpu_device *adev)
{
	int i, r;

	if (amdgpu_aca_is_enabled(adev))
		amdgpu_cper_fini(adev);

	if (amdgpu_sriov_vf(adev) && adev->virt.ras_init_done)
+2 −1
Original line number Diff line number Diff line
@@ -591,7 +591,8 @@ int amdgpu_gmc_allocate_vm_inv_eng(struct amdgpu_device *adev)

		if (ring == &adev->mes.ring[0] ||
		    ring == &adev->mes.ring[1] ||
		    ring == &adev->umsch_mm.ring)
		    ring == &adev->umsch_mm.ring ||
		    ring == &adev->cper.ring_buf)
			continue;

		inv_eng = ffs(vm_inv_engs[vmhub]);
+18 −11
Original line number Diff line number Diff line
@@ -324,6 +324,7 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
	/* always set cond_exec_polling to CONTINUE */
	*ring->cond_exe_cpu_addr = 1;

	if (ring->funcs->type != AMDGPU_RING_TYPE_CPER) {
		r = amdgpu_fence_driver_start_ring(ring, irq_src, irq_type);
		if (r) {
			dev_err(adev->dev, "failed initializing fences (%d).\n", r);
@@ -338,6 +339,12 @@ int amdgpu_ring_init(struct amdgpu_device *adev, struct amdgpu_ring *ring,
			max_dw = max_ibs_dw;

		ring->ring_size = roundup_pow_of_two(max_dw * 4 * sched_hw_submission);
	} else {
		ring->ring_size = roundup_pow_of_two(max_dw * 4);
		ring->count_dw = (ring->ring_size - 4) >> 2;
		/* ring buffer is empty now */
		ring->wptr = *ring->rptr_cpu_addr = 0;
	}

	ring->buf_mask = (ring->ring_size / 4) - 1;
	ring->ptr_mask = ring->funcs->support_64bit_ptrs ?
Loading