diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_fence.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_fence.c | 66 |
1 files changed, 17 insertions, 49 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 3beb26d74719..d90f95b405c5 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/wait.h> | 33 | #include <linux/wait.h> |
34 | #include <linux/list.h> | 34 | #include <linux/list.h> |
35 | #include <linux/kref.h> | 35 | #include <linux/kref.h> |
36 | #include <linux/slab.h> | ||
36 | #include "drmP.h" | 37 | #include "drmP.h" |
37 | #include "drm.h" | 38 | #include "drm.h" |
38 | #include "radeon_reg.h" | 39 | #include "radeon_reg.h" |
@@ -140,16 +141,15 @@ int radeon_fence_create(struct radeon_device *rdev, struct radeon_fence **fence) | |||
140 | 141 | ||
141 | bool radeon_fence_signaled(struct radeon_fence *fence) | 142 | bool radeon_fence_signaled(struct radeon_fence *fence) |
142 | { | 143 | { |
143 | struct radeon_device *rdev = fence->rdev; | ||
144 | unsigned long irq_flags; | 144 | unsigned long irq_flags; |
145 | bool signaled = false; | 145 | bool signaled = false; |
146 | 146 | ||
147 | if (rdev->gpu_lockup) { | 147 | if (!fence) |
148 | return true; | 148 | return true; |
149 | } | 149 | |
150 | if (fence == NULL) { | 150 | if (fence->rdev->gpu_lockup) |
151 | return true; | 151 | return true; |
152 | } | 152 | |
153 | write_lock_irqsave(&fence->rdev->fence_drv.lock, irq_flags); | 153 | write_lock_irqsave(&fence->rdev->fence_drv.lock, irq_flags); |
154 | signaled = fence->signaled; | 154 | signaled = fence->signaled; |
155 | /* if we are shuting down report all fence as signaled */ | 155 | /* if we are shuting down report all fence as signaled */ |
@@ -168,37 +168,6 @@ bool radeon_fence_signaled(struct radeon_fence *fence) | |||
168 | return signaled; | 168 | return signaled; |
169 | } | 169 | } |
170 | 170 | ||
171 | int r600_fence_wait(struct radeon_fence *fence, bool intr, bool lazy) | ||
172 | { | ||
173 | struct radeon_device *rdev; | ||
174 | int ret = 0; | ||
175 | |||
176 | rdev = fence->rdev; | ||
177 | |||
178 | __set_current_state(intr ? TASK_INTERRUPTIBLE : TASK_UNINTERRUPTIBLE); | ||
179 | |||
180 | while (1) { | ||
181 | if (radeon_fence_signaled(fence)) | ||
182 | break; | ||
183 | |||
184 | if (time_after_eq(jiffies, fence->timeout)) { | ||
185 | ret = -EBUSY; | ||
186 | break; | ||
187 | } | ||
188 | |||
189 | if (lazy) | ||
190 | schedule_timeout(1); | ||
191 | |||
192 | if (intr && signal_pending(current)) { | ||
193 | ret = -ERESTARTSYS; | ||
194 | break; | ||
195 | } | ||
196 | } | ||
197 | __set_current_state(TASK_RUNNING); | ||
198 | return ret; | ||
199 | } | ||
200 | |||
201 | |||
202 | int radeon_fence_wait(struct radeon_fence *fence, bool intr) | 171 | int radeon_fence_wait(struct radeon_fence *fence, bool intr) |
203 | { | 172 | { |
204 | struct radeon_device *rdev; | 173 | struct radeon_device *rdev; |
@@ -216,13 +185,6 @@ int radeon_fence_wait(struct radeon_fence *fence, bool intr) | |||
216 | return 0; | 185 | return 0; |
217 | } | 186 | } |
218 | 187 | ||
219 | if (rdev->family >= CHIP_R600) { | ||
220 | r = r600_fence_wait(fence, intr, 0); | ||
221 | if (r == -ERESTARTSYS) | ||
222 | return -EBUSY; | ||
223 | return r; | ||
224 | } | ||
225 | |||
226 | retry: | 188 | retry: |
227 | cur_jiffies = jiffies; | 189 | cur_jiffies = jiffies; |
228 | timeout = HZ / 100; | 190 | timeout = HZ / 100; |
@@ -231,14 +193,17 @@ retry: | |||
231 | } | 193 | } |
232 | 194 | ||
233 | if (intr) { | 195 | if (intr) { |
196 | radeon_irq_kms_sw_irq_get(rdev); | ||
234 | r = wait_event_interruptible_timeout(rdev->fence_drv.queue, | 197 | r = wait_event_interruptible_timeout(rdev->fence_drv.queue, |
235 | radeon_fence_signaled(fence), timeout); | 198 | radeon_fence_signaled(fence), timeout); |
236 | if (unlikely(r == -ERESTARTSYS)) { | 199 | radeon_irq_kms_sw_irq_put(rdev); |
237 | return -EBUSY; | 200 | if (unlikely(r < 0)) |
238 | } | 201 | return r; |
239 | } else { | 202 | } else { |
203 | radeon_irq_kms_sw_irq_get(rdev); | ||
240 | r = wait_event_timeout(rdev->fence_drv.queue, | 204 | r = wait_event_timeout(rdev->fence_drv.queue, |
241 | radeon_fence_signaled(fence), timeout); | 205 | radeon_fence_signaled(fence), timeout); |
206 | radeon_irq_kms_sw_irq_put(rdev); | ||
242 | } | 207 | } |
243 | if (unlikely(!radeon_fence_signaled(fence))) { | 208 | if (unlikely(!radeon_fence_signaled(fence))) { |
244 | if (unlikely(r == 0)) { | 209 | if (unlikely(r == 0)) { |
@@ -359,7 +324,7 @@ int radeon_fence_driver_init(struct radeon_device *rdev) | |||
359 | write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); | 324 | write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); |
360 | r = radeon_scratch_get(rdev, &rdev->fence_drv.scratch_reg); | 325 | r = radeon_scratch_get(rdev, &rdev->fence_drv.scratch_reg); |
361 | if (r) { | 326 | if (r) { |
362 | DRM_ERROR("Fence failed to get a scratch register."); | 327 | dev_err(rdev->dev, "fence failed to get scratch register\n"); |
363 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); | 328 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
364 | return r; | 329 | return r; |
365 | } | 330 | } |
@@ -370,9 +335,10 @@ int radeon_fence_driver_init(struct radeon_device *rdev) | |||
370 | INIT_LIST_HEAD(&rdev->fence_drv.signaled); | 335 | INIT_LIST_HEAD(&rdev->fence_drv.signaled); |
371 | rdev->fence_drv.count_timeout = 0; | 336 | rdev->fence_drv.count_timeout = 0; |
372 | init_waitqueue_head(&rdev->fence_drv.queue); | 337 | init_waitqueue_head(&rdev->fence_drv.queue); |
338 | rdev->fence_drv.initialized = true; | ||
373 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); | 339 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
374 | if (radeon_debugfs_fence_init(rdev)) { | 340 | if (radeon_debugfs_fence_init(rdev)) { |
375 | DRM_ERROR("Failed to register debugfs file for fence !\n"); | 341 | dev_err(rdev->dev, "fence debugfs file creation failed\n"); |
376 | } | 342 | } |
377 | return 0; | 343 | return 0; |
378 | } | 344 | } |
@@ -381,11 +347,13 @@ void radeon_fence_driver_fini(struct radeon_device *rdev) | |||
381 | { | 347 | { |
382 | unsigned long irq_flags; | 348 | unsigned long irq_flags; |
383 | 349 | ||
350 | if (!rdev->fence_drv.initialized) | ||
351 | return; | ||
384 | wake_up_all(&rdev->fence_drv.queue); | 352 | wake_up_all(&rdev->fence_drv.queue); |
385 | write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); | 353 | write_lock_irqsave(&rdev->fence_drv.lock, irq_flags); |
386 | radeon_scratch_free(rdev, rdev->fence_drv.scratch_reg); | 354 | radeon_scratch_free(rdev, rdev->fence_drv.scratch_reg); |
387 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); | 355 | write_unlock_irqrestore(&rdev->fence_drv.lock, irq_flags); |
388 | DRM_INFO("radeon: fence finalized\n"); | 356 | rdev->fence_drv.initialized = false; |
389 | } | 357 | } |
390 | 358 | ||
391 | 359 | ||