diff options
author | Mark Brown <broonie@kernel.org> | 2015-10-12 13:09:27 -0400 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-10-12 13:09:27 -0400 |
commit | 79828b4fa835f73cdaf4bffa48696abdcbea9d02 (patch) | |
tree | 5e0fa7156acb75ba603022bc807df8f2fedb97a8 /drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | |
parent | 721b51fcf91898299d96f4b72cb9434cda29dce6 (diff) | |
parent | 8c1a9d6323abf0fb1e5dad96cf3f1c783505ea5a (diff) |
Merge remote-tracking branch 'asoc/fix/rt5645' into asoc-fix-rt5645
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c')
-rw-r--r-- | drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c new file mode 100644 index 000000000000..de98fbd2971e --- /dev/null +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sched.c | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * Copyright 2015 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * | ||
23 | */ | ||
24 | #include <linux/kthread.h> | ||
25 | #include <linux/wait.h> | ||
26 | #include <linux/sched.h> | ||
27 | #include <drm/drmP.h> | ||
28 | #include "amdgpu.h" | ||
29 | |||
30 | static struct fence *amdgpu_sched_dependency(struct amd_sched_job *job) | ||
31 | { | ||
32 | struct amdgpu_job *sched_job = (struct amdgpu_job *)job; | ||
33 | return amdgpu_sync_get_fence(&sched_job->ibs->sync); | ||
34 | } | ||
35 | |||
36 | static struct fence *amdgpu_sched_run_job(struct amd_sched_job *job) | ||
37 | { | ||
38 | struct amdgpu_job *sched_job; | ||
39 | struct amdgpu_fence *fence; | ||
40 | int r; | ||
41 | |||
42 | if (!job) { | ||
43 | DRM_ERROR("job is null\n"); | ||
44 | return NULL; | ||
45 | } | ||
46 | sched_job = (struct amdgpu_job *)job; | ||
47 | mutex_lock(&sched_job->job_lock); | ||
48 | r = amdgpu_ib_schedule(sched_job->adev, | ||
49 | sched_job->num_ibs, | ||
50 | sched_job->ibs, | ||
51 | sched_job->base.owner); | ||
52 | if (r) | ||
53 | goto err; | ||
54 | fence = amdgpu_fence_ref(sched_job->ibs[sched_job->num_ibs - 1].fence); | ||
55 | |||
56 | if (sched_job->free_job) | ||
57 | sched_job->free_job(sched_job); | ||
58 | |||
59 | mutex_unlock(&sched_job->job_lock); | ||
60 | return &fence->base; | ||
61 | |||
62 | err: | ||
63 | DRM_ERROR("Run job error\n"); | ||
64 | mutex_unlock(&sched_job->job_lock); | ||
65 | job->sched->ops->process_job(job); | ||
66 | return NULL; | ||
67 | } | ||
68 | |||
69 | static void amdgpu_sched_process_job(struct amd_sched_job *job) | ||
70 | { | ||
71 | struct amdgpu_job *sched_job; | ||
72 | |||
73 | if (!job) { | ||
74 | DRM_ERROR("job is null\n"); | ||
75 | return; | ||
76 | } | ||
77 | sched_job = (struct amdgpu_job *)job; | ||
78 | /* after processing job, free memory */ | ||
79 | fence_put(&sched_job->base.s_fence->base); | ||
80 | kfree(sched_job); | ||
81 | } | ||
82 | |||
83 | struct amd_sched_backend_ops amdgpu_sched_ops = { | ||
84 | .dependency = amdgpu_sched_dependency, | ||
85 | .run_job = amdgpu_sched_run_job, | ||
86 | .process_job = amdgpu_sched_process_job | ||
87 | }; | ||
88 | |||
89 | int amdgpu_sched_ib_submit_kernel_helper(struct amdgpu_device *adev, | ||
90 | struct amdgpu_ring *ring, | ||
91 | struct amdgpu_ib *ibs, | ||
92 | unsigned num_ibs, | ||
93 | int (*free_job)(struct amdgpu_job *), | ||
94 | void *owner, | ||
95 | struct fence **f) | ||
96 | { | ||
97 | int r = 0; | ||
98 | if (amdgpu_enable_scheduler) { | ||
99 | struct amdgpu_job *job = | ||
100 | kzalloc(sizeof(struct amdgpu_job), GFP_KERNEL); | ||
101 | if (!job) | ||
102 | return -ENOMEM; | ||
103 | job->base.sched = ring->scheduler; | ||
104 | job->base.s_entity = &adev->kernel_ctx.rings[ring->idx].entity; | ||
105 | job->adev = adev; | ||
106 | job->ibs = ibs; | ||
107 | job->num_ibs = num_ibs; | ||
108 | job->base.owner = owner; | ||
109 | mutex_init(&job->job_lock); | ||
110 | job->free_job = free_job; | ||
111 | mutex_lock(&job->job_lock); | ||
112 | r = amd_sched_entity_push_job((struct amd_sched_job *)job); | ||
113 | if (r) { | ||
114 | mutex_unlock(&job->job_lock); | ||
115 | kfree(job); | ||
116 | return r; | ||
117 | } | ||
118 | *f = fence_get(&job->base.s_fence->base); | ||
119 | mutex_unlock(&job->job_lock); | ||
120 | } else { | ||
121 | r = amdgpu_ib_schedule(adev, num_ibs, ibs, owner); | ||
122 | if (r) | ||
123 | return r; | ||
124 | *f = fence_get(&ibs[num_ibs - 1].fence->base); | ||
125 | } | ||
126 | |||
127 | return 0; | ||
128 | } | ||