diff options
author | Alex Deucher <alexander.deucher@amd.com> | 2015-07-28 14:24:53 -0400 |
---|---|---|
committer | Alex Deucher <alexander.deucher@amd.com> | 2015-08-17 16:50:09 -0400 |
commit | 0cf3be21782f8d5b74cce98a2b934e14ef418ef3 (patch) | |
tree | b55121cd82416180fb5469e34caa892fdd2e35ae | |
parent | 97cb7f6e6c4d7d78de7e174d8776a95ef7fd1e8a (diff) |
drm/amdgpu: Implement irq interfaces for CGS
This implements the irq src registrar.
Reviewed-by: Jammy Zhou <Jammy.Zhou@amd.com>
Signed-off-by: Chunming Zhou <David1.Zhou@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | 81 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h | 1 |
5 files changed, 84 insertions, 6 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c index 6ac3df856b49..93fbf3551111 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cgs.c | |||
@@ -290,26 +290,95 @@ static int amdgpu_cgs_set_camera_voltages(void *cgs_device, uint32_t mask, | |||
290 | return -EPERM; | 290 | return -EPERM; |
291 | } | 291 | } |
292 | 292 | ||
293 | struct cgs_irq_params { | ||
294 | unsigned src_id; | ||
295 | cgs_irq_source_set_func_t set; | ||
296 | cgs_irq_handler_func_t handler; | ||
297 | void *private_data; | ||
298 | }; | ||
299 | |||
300 | static int cgs_set_irq_state(struct amdgpu_device *adev, | ||
301 | struct amdgpu_irq_src *src, | ||
302 | unsigned type, | ||
303 | enum amdgpu_interrupt_state state) | ||
304 | { | ||
305 | struct cgs_irq_params *irq_params = | ||
306 | (struct cgs_irq_params *)src->data; | ||
307 | if (!irq_params) | ||
308 | return -EINVAL; | ||
309 | if (!irq_params->set) | ||
310 | return -EINVAL; | ||
311 | return irq_params->set(irq_params->private_data, | ||
312 | irq_params->src_id, | ||
313 | type, | ||
314 | (int)state); | ||
315 | } | ||
316 | |||
317 | static int cgs_process_irq(struct amdgpu_device *adev, | ||
318 | struct amdgpu_irq_src *source, | ||
319 | struct amdgpu_iv_entry *entry) | ||
320 | { | ||
321 | struct cgs_irq_params *irq_params = | ||
322 | (struct cgs_irq_params *)source->data; | ||
323 | if (!irq_params) | ||
324 | return -EINVAL; | ||
325 | if (!irq_params->handler) | ||
326 | return -EINVAL; | ||
327 | return irq_params->handler(irq_params->private_data, | ||
328 | irq_params->src_id, | ||
329 | entry->iv_entry); | ||
330 | } | ||
331 | |||
332 | static const struct amdgpu_irq_src_funcs cgs_irq_funcs = { | ||
333 | .set = cgs_set_irq_state, | ||
334 | .process = cgs_process_irq, | ||
335 | }; | ||
336 | |||
293 | static int amdgpu_cgs_add_irq_source(void *cgs_device, unsigned src_id, | 337 | static int amdgpu_cgs_add_irq_source(void *cgs_device, unsigned src_id, |
294 | unsigned num_types, | 338 | unsigned num_types, |
295 | cgs_irq_source_set_func_t set, | 339 | cgs_irq_source_set_func_t set, |
296 | cgs_irq_handler_func_t handler, | 340 | cgs_irq_handler_func_t handler, |
297 | void *private_data) | 341 | void *private_data) |
298 | { | 342 | { |
299 | /* TODO */ | 343 | CGS_FUNC_ADEV; |
300 | return 0; | 344 | int ret = 0; |
345 | struct cgs_irq_params *irq_params; | ||
346 | struct amdgpu_irq_src *source = | ||
347 | kzalloc(sizeof(struct amdgpu_irq_src), GFP_KERNEL); | ||
348 | if (!source) | ||
349 | return -ENOMEM; | ||
350 | irq_params = | ||
351 | kzalloc(sizeof(struct cgs_irq_params), GFP_KERNEL); | ||
352 | if (!irq_params) { | ||
353 | kfree(source); | ||
354 | return -ENOMEM; | ||
355 | } | ||
356 | source->num_types = num_types; | ||
357 | source->funcs = &cgs_irq_funcs; | ||
358 | irq_params->src_id = src_id; | ||
359 | irq_params->set = set; | ||
360 | irq_params->handler = handler; | ||
361 | irq_params->private_data = private_data; | ||
362 | source->data = (void *)irq_params; | ||
363 | ret = amdgpu_irq_add_id(adev, src_id, source); | ||
364 | if (ret) { | ||
365 | kfree(irq_params); | ||
366 | kfree(source); | ||
367 | } | ||
368 | |||
369 | return ret; | ||
301 | } | 370 | } |
302 | 371 | ||
303 | static int amdgpu_cgs_irq_get(void *cgs_device, unsigned src_id, unsigned type) | 372 | static int amdgpu_cgs_irq_get(void *cgs_device, unsigned src_id, unsigned type) |
304 | { | 373 | { |
305 | /* TODO */ | 374 | CGS_FUNC_ADEV; |
306 | return 0; | 375 | return amdgpu_irq_get(adev, adev->irq.sources[src_id], type); |
307 | } | 376 | } |
308 | 377 | ||
309 | static int amdgpu_cgs_irq_put(void *cgs_device, unsigned src_id, unsigned type) | 378 | static int amdgpu_cgs_irq_put(void *cgs_device, unsigned src_id, unsigned type) |
310 | { | 379 | { |
311 | /* TODO */ | 380 | CGS_FUNC_ADEV; |
312 | return 0; | 381 | return amdgpu_irq_put(adev, adev->irq.sources[src_id], type); |
313 | } | 382 | } |
314 | 383 | ||
315 | static const struct cgs_ops amdgpu_cgs_ops = { | 384 | static const struct cgs_ops amdgpu_cgs_ops = { |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c index fb44dd2231b1..90044b254404 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.c | |||
@@ -206,6 +206,8 @@ restart_ih: | |||
206 | amdgpu_amdkfd_interrupt(adev, | 206 | amdgpu_amdkfd_interrupt(adev, |
207 | (const void *) &adev->irq.ih.ring[ring_index]); | 207 | (const void *) &adev->irq.ih.ring[ring_index]); |
208 | 208 | ||
209 | entry.iv_entry = (const uint32_t *) | ||
210 | &adev->irq.ih.ring[ring_index]; | ||
209 | amdgpu_ih_decode_iv(adev, &entry); | 211 | amdgpu_ih_decode_iv(adev, &entry); |
210 | adev->irq.ih.rptr &= adev->irq.ih.ptr_mask; | 212 | adev->irq.ih.rptr &= adev->irq.ih.ptr_mask; |
211 | 213 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h index c62b09e555d6..ba38ae6a1463 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ih.h | |||
@@ -52,6 +52,7 @@ struct amdgpu_iv_entry { | |||
52 | unsigned ring_id; | 52 | unsigned ring_id; |
53 | unsigned vm_id; | 53 | unsigned vm_id; |
54 | unsigned pas_id; | 54 | unsigned pas_id; |
55 | const uint32_t *iv_entry; | ||
55 | }; | 56 | }; |
56 | 57 | ||
57 | int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size, | 58 | int amdgpu_ih_ring_init(struct amdgpu_device *adev, unsigned ring_size, |
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c index b4d36f0f2153..0aba8e9bc8a0 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c | |||
@@ -272,6 +272,11 @@ void amdgpu_irq_fini(struct amdgpu_device *adev) | |||
272 | 272 | ||
273 | kfree(src->enabled_types); | 273 | kfree(src->enabled_types); |
274 | src->enabled_types = NULL; | 274 | src->enabled_types = NULL; |
275 | if (src->data) { | ||
276 | kfree(src->data); | ||
277 | kfree(src); | ||
278 | adev->irq.sources[i] = NULL; | ||
279 | } | ||
275 | } | 280 | } |
276 | } | 281 | } |
277 | 282 | ||
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h index 8299795f2b2d..17b01aef4278 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.h | |||
@@ -40,6 +40,7 @@ struct amdgpu_irq_src { | |||
40 | unsigned num_types; | 40 | unsigned num_types; |
41 | atomic_t *enabled_types; | 41 | atomic_t *enabled_types; |
42 | const struct amdgpu_irq_src_funcs *funcs; | 42 | const struct amdgpu_irq_src_funcs *funcs; |
43 | void *data; | ||
43 | }; | 44 | }; |
44 | 45 | ||
45 | /* provided by interrupt generating IP blocks */ | 46 | /* provided by interrupt generating IP blocks */ |