Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0cf3be21 authored by Alex Deucher's avatar Alex Deucher
Browse files

drm/amdgpu: Implement irq interfaces for CGS



This implements the irq src registrar.

Reviewed-by: default avatarJammy Zhou <Jammy.Zhou@amd.com>
Signed-off-by: default avatarChunming Zhou <David1.Zhou@amd.com>
Signed-off-by: default avatarAlex Deucher <alexander.deucher@amd.com>
parent 97cb7f6e
Loading
Loading
Loading
Loading
+75 −6
Original line number Original line Diff line number Diff line
@@ -290,26 +290,95 @@ static int amdgpu_cgs_set_camera_voltages(void *cgs_device, uint32_t mask,
	return -EPERM;
	return -EPERM;
}
}


struct cgs_irq_params {
	unsigned src_id;
	cgs_irq_source_set_func_t set;
	cgs_irq_handler_func_t handler;
	void *private_data;
};

static int cgs_set_irq_state(struct amdgpu_device *adev,
			     struct amdgpu_irq_src *src,
			     unsigned type,
			     enum amdgpu_interrupt_state state)
{
	struct cgs_irq_params *irq_params =
		(struct cgs_irq_params *)src->data;
	if (!irq_params)
		return -EINVAL;
	if (!irq_params->set)
		return -EINVAL;
	return irq_params->set(irq_params->private_data,
			       irq_params->src_id,
			       type,
			       (int)state);
}

static int cgs_process_irq(struct amdgpu_device *adev,
			   struct amdgpu_irq_src *source,
			   struct amdgpu_iv_entry *entry)
{
	struct cgs_irq_params *irq_params =
		(struct cgs_irq_params *)source->data;
	if (!irq_params)
		return -EINVAL;
	if (!irq_params->handler)
		return -EINVAL;
	return irq_params->handler(irq_params->private_data,
				   irq_params->src_id,
				   entry->iv_entry);
}

static const struct amdgpu_irq_src_funcs cgs_irq_funcs = {
	.set = cgs_set_irq_state,
	.process = cgs_process_irq,
};

static int amdgpu_cgs_add_irq_source(void *cgs_device, unsigned src_id,
static int amdgpu_cgs_add_irq_source(void *cgs_device, unsigned src_id,
				     unsigned num_types,
				     unsigned num_types,
				     cgs_irq_source_set_func_t set,
				     cgs_irq_source_set_func_t set,
				     cgs_irq_handler_func_t handler,
				     cgs_irq_handler_func_t handler,
				     void *private_data)
				     void *private_data)
{
{
	/* TODO */
	CGS_FUNC_ADEV;
	return 0;
	int ret = 0;
	struct cgs_irq_params *irq_params;
	struct amdgpu_irq_src *source =
		kzalloc(sizeof(struct amdgpu_irq_src), GFP_KERNEL);
	if (!source)
		return -ENOMEM;
	irq_params =
		kzalloc(sizeof(struct cgs_irq_params), GFP_KERNEL);
	if (!irq_params) {
		kfree(source);
		return -ENOMEM;
	}
	source->num_types = num_types;
	source->funcs = &cgs_irq_funcs;
	irq_params->src_id = src_id;
	irq_params->set = set;
	irq_params->handler = handler;
	irq_params->private_data = private_data;
	source->data = (void *)irq_params;
	ret = amdgpu_irq_add_id(adev, src_id, source);
	if (ret) {
		kfree(irq_params);
		kfree(source);
	}

	return ret;
}
}


static int amdgpu_cgs_irq_get(void *cgs_device, unsigned src_id, unsigned type)
static int amdgpu_cgs_irq_get(void *cgs_device, unsigned src_id, unsigned type)
{
{
	/* TODO */
	CGS_FUNC_ADEV;
	return 0;
	return amdgpu_irq_get(adev, adev->irq.sources[src_id], type);
}
}


static int amdgpu_cgs_irq_put(void *cgs_device, unsigned src_id, unsigned type)
static int amdgpu_cgs_irq_put(void *cgs_device, unsigned src_id, unsigned type)
{
{
	/* TODO */
	CGS_FUNC_ADEV;
	return 0;
	return amdgpu_irq_put(adev, adev->irq.sources[src_id], type);
}
}


static const struct cgs_ops amdgpu_cgs_ops = {
static const struct cgs_ops amdgpu_cgs_ops = {
+2 −0
Original line number Original line Diff line number Diff line
@@ -206,6 +206,8 @@ int amdgpu_ih_process(struct amdgpu_device *adev)
		amdgpu_amdkfd_interrupt(adev,
		amdgpu_amdkfd_interrupt(adev,
				(const void *) &adev->irq.ih.ring[ring_index]);
				(const void *) &adev->irq.ih.ring[ring_index]);


		entry.iv_entry = (const uint32_t *)
			&adev->irq.ih.ring[ring_index];
		amdgpu_ih_decode_iv(adev, &entry);
		amdgpu_ih_decode_iv(adev, &entry);
		adev->irq.ih.rptr &= adev->irq.ih.ptr_mask;
		adev->irq.ih.rptr &= adev->irq.ih.ptr_mask;


+1 −0
Original line number Original line Diff line number Diff line
@@ -52,6 +52,7 @@ struct amdgpu_iv_entry {
	unsigned ring_id;
	unsigned ring_id;
	unsigned vm_id;
	unsigned vm_id;
	unsigned pas_id;
	unsigned pas_id;
	const uint32_t *iv_entry;
};
};


int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size,
int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size,
+5 −0
Original line number Original line Diff line number Diff line
@@ -272,6 +272,11 @@ void amdgpu_irq_fini(struct amdgpu_device *adev)


		kfree(src->enabled_types);
		kfree(src->enabled_types);
		src->enabled_types = NULL;
		src->enabled_types = NULL;
		if (src->data) {
			kfree(src->data);
			kfree(src);
			adev->irq.sources[i] = NULL;
		}
	}
	}
}
}


+1 −0
Original line number Original line Diff line number Diff line
@@ -40,6 +40,7 @@ struct amdgpu_irq_src {
	unsigned				num_types;
	unsigned				num_types;
	atomic_t				*enabled_types;
	atomic_t				*enabled_types;
	const struct amdgpu_irq_src_funcs	*funcs;
	const struct amdgpu_irq_src_funcs	*funcs;
	void *data;
};
};


/* provided by interrupt generating IP blocks */
/* provided by interrupt generating IP blocks */