History

Merge branch 'drm-fixes-3.8' of git://people.freedesktop.org/~agd5f/linux into drm-next

Misc fixes for reset and new packets for userspace usage. * 'drm-fixes-3.8' of git://people.freedesktop.org/~agd5f/linux: drm/radeon: add WAIT_UNTIL to evergreen VM safe reg list drm/radeon: add support for MEM_WRITE packet drm/radeon: restore modeset late in GPU reset path drm/radeon: avoid deadlock in pm path when waiting for fence drm/radeon: don't leave fence blocked process on failed GPU reset

Dave Airlie committed 13 years ago

Commit b1d778b2 parents 344f906 668bbc87 files · +122 −24Browse files

Unified · Split

7 files
  1. drivers/gpu/drm/radeon/evergreen_cs.c +30 −0
  2. drivers/gpu/drm/radeon/r600_cs.c +29 −0
  3. drivers/gpu/drm/radeon/radeon.h +2 −1
  4. drivers/gpu/drm/radeon/radeon_device.c +14 −3
  5. drivers/gpu/drm/radeon/radeon_drv.c +2 −1
  6. drivers/gpu/drm/radeon/radeon_fence.c +33 −16
  7. drivers/gpu/drm/radeon/radeon_pm.c +12 −3
drivers/gpu/drm/radeon/evergreen_cs.c+30−0
@@ -2654,6 +2654,35 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, · 2653 unmodified lines
2654 ib[idx+4] = upper_32_bits(offset) & 0xff;2654 ib[idx+4] = upper_32_bits(offset) & 0xff;
2655 }2655 }
2656 break;2656 break;
2657 case PACKET3_MEM_WRITE:
2658 {
2659 u64 offset;
2660
2661 if (pkt->count != 3) {
2662 DRM_ERROR("bad MEM_WRITE (invalid count)\n");
2663 return -EINVAL;
2664 }
2665 r = evergreen_cs_packet_next_reloc(p, &reloc);
2666 if (r) {
2667 DRM_ERROR("bad MEM_WRITE (missing reloc)\n");
2668 return -EINVAL;
2669 }
2670 offset = radeon_get_ib_value(p, idx+0);
2671 offset += ((u64)(radeon_get_ib_value(p, idx+1) & 0xff)) << 32UL;
2672 if (offset & 0x7) {
2673 DRM_ERROR("bad MEM_WRITE (address not qwords aligned)\n");
2674 return -EINVAL;
2675 }
2676 if ((offset + 8) > radeon_bo_size(reloc->robj)) {
2677 DRM_ERROR("bad MEM_WRITE bo too small: 0x%llx, 0x%lx\n",
2678 offset + 8, radeon_bo_size(reloc->robj));
2679 return -EINVAL;
2680 }
2681 offset += reloc->lobj.gpu_offset;
2682 ib[idx+0] = offset;
2683 ib[idx+1] = upper_32_bits(offset) & 0xff;
2684 break;
2685 }
2657 case PACKET3_COPY_DW:2686 case PACKET3_COPY_DW:
2658 if (pkt->count != 4) {2687 if (pkt->count != 4) {
2659 DRM_ERROR("bad COPY_DW (invalid count)\n");2688 DRM_ERROR("bad COPY_DW (invalid count)\n");
@@ -3287,6 +3316,7 @@ static bool evergreen_vm_reg_valid(u32 reg) · 627 unmodified lines
3287 3316
3288 /* check config regs */3317 /* check config regs */
3289 switch (reg) {3318 switch (reg) {
3319 case WAIT_UNTIL:
3290 case GRBM_GFX_INDEX:3320 case GRBM_GFX_INDEX:
3291 case CP_STRMOUT_CNTL:3321 case CP_STRMOUT_CNTL:
3292 case CP_COHER_CNTL:3322 case CP_COHER_CNTL:
drivers/gpu/drm/radeon/r600_cs.c+29−0
@@ -2294,6 +2294,35 @@ static int r600_packet3_check(struct radeon_cs_parser *p, · 2293 unmodified lines
2294 ib[idx+4] = upper_32_bits(offset) & 0xff;2294 ib[idx+4] = upper_32_bits(offset) & 0xff;
2295 }2295 }
2296 break;2296 break;
2297 case PACKET3_MEM_WRITE:
2298 {
2299 u64 offset;
2300
2301 if (pkt->count != 3) {
2302 DRM_ERROR("bad MEM_WRITE (invalid count)\n");
2303 return -EINVAL;
2304 }
2305 r = r600_cs_packet_next_reloc(p, &reloc);
2306 if (r) {
2307 DRM_ERROR("bad MEM_WRITE (missing reloc)\n");
2308 return -EINVAL;
2309 }
2310 offset = radeon_get_ib_value(p, idx+0);
2311 offset += ((u64)(radeon_get_ib_value(p, idx+1) & 0xff)) << 32UL;
2312 if (offset & 0x7) {
2313 DRM_ERROR("bad MEM_WRITE (address not qwords aligned)\n");
2314 return -EINVAL;
2315 }
2316 if ((offset + 8) > radeon_bo_size(reloc->robj)) {
2317 DRM_ERROR("bad MEM_WRITE bo too small: 0x%llx, 0x%lx\n",
2318 offset + 8, radeon_bo_size(reloc->robj));
2319 return -EINVAL;
2320 }
2321 offset += reloc->lobj.gpu_offset;
2322 ib[idx+0] = offset;
2323 ib[idx+1] = upper_32_bits(offset) & 0xff;
2324 break;
2325 }
2297 case PACKET3_COPY_DW:2326 case PACKET3_COPY_DW:
2298 if (pkt->count != 4) {2327 if (pkt->count != 4) {
2299 DRM_ERROR("bad COPY_DW (invalid count)\n");2328 DRM_ERROR("bad COPY_DW (invalid count)\n");
drivers/gpu/drm/radeon/radeon.h+2−1
@@ -225,12 +225,13 @@ struct radeon_fence { · 224 unmodified lines
225int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring);225int radeon_fence_driver_start_ring(struct radeon_device *rdev, int ring);
226int radeon_fence_driver_init(struct radeon_device *rdev);226int radeon_fence_driver_init(struct radeon_device *rdev);
227void radeon_fence_driver_fini(struct radeon_device *rdev);227void radeon_fence_driver_fini(struct radeon_device *rdev);
228void radeon_fence_driver_force_completion(struct radeon_device *rdev);
228int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence **fence, int ring);229int radeon_fence_emit(struct radeon_device *rdev, struct radeon_fence **fence, int ring);
229void radeon_fence_process(struct radeon_device *rdev, int ring);230void radeon_fence_process(struct radeon_device *rdev, int ring);
230bool radeon_fence_signaled(struct radeon_fence *fence);231bool radeon_fence_signaled(struct radeon_fence *fence);
231int radeon_fence_wait(struct radeon_fence *fence, bool interruptible);232int radeon_fence_wait(struct radeon_fence *fence, bool interruptible);
232int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring);233int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring);
233void radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring);234int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring);
234int radeon_fence_wait_any(struct radeon_device *rdev,235int radeon_fence_wait_any(struct radeon_device *rdev,
235 struct radeon_fence **fences,236 struct radeon_fence **fences,
236 bool intr);237 bool intr);
drivers/gpu/drm/radeon/radeon_device.c+14−3
@@ -1164,6 +1164,7 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) · 1163 unmodified lines
1164 struct drm_crtc *crtc;1164 struct drm_crtc *crtc;
1165 struct drm_connector *connector;1165 struct drm_connector *connector;
1166 int i, r;1166 int i, r;
1167 bool force_completion = false;
1167 1168
1168 if (dev == NULL || dev->dev_private == NULL) {1169 if (dev == NULL || dev->dev_private == NULL) {
1169 return -ENODEV;1170 return -ENODEV;
@@ -1206,8 +1207,16 @@ int radeon_suspend_kms(struct drm_device *dev, pm_message_t state) · 36 unmodified lines
1206 1207
1207 mutex_lock(&rdev->ring_lock);1208 mutex_lock(&rdev->ring_lock);
1208 /* wait for gpu to finish processing current batch */1209 /* wait for gpu to finish processing current batch */
1209 for (i = 0; i < RADEON_NUM_RINGS; i++)1210 for (i = 0; i < RADEON_NUM_RINGS; i++) {
1210 radeon_fence_wait_empty_locked(rdev, i);1211 r = radeon_fence_wait_empty_locked(rdev, i);
1212 if (r) {
1213 /* delay GPU reset to resume */
1214 force_completion = true;
1215 }
1216 }
1217 if (force_completion) {
1218 radeon_fence_driver_force_completion(rdev);
1219 }
1211 mutex_unlock(&rdev->ring_lock);1220 mutex_unlock(&rdev->ring_lock);
1212 1221
1213 radeon_save_bios_scratch_regs(rdev);1222 radeon_save_bios_scratch_regs(rdev);
@@ -1338,7 +1347,6 @@ retry: · 124 unmodified lines
1338 }1347 }
1339 1348
1340 radeon_restore_bios_scratch_regs(rdev);1349 radeon_restore_bios_scratch_regs(rdev);
1341 drm_helper_resume_force_mode(rdev->ddev);
1342 1350
1343 if (!r) {1351 if (!r) {
1344 for (i = 0; i < RADEON_NUM_RINGS; ++i) {1352 for (i = 0; i < RADEON_NUM_RINGS; ++i) {
@@ -1358,11 +1366,14 @@ retry: · 13 unmodified lines
1358 }1366 }
1359 }1367 }
1360 } else {1368 } else {
1369 radeon_fence_driver_force_completion(rdev);
1361 for (i = 0; i < RADEON_NUM_RINGS; ++i) {1370 for (i = 0; i < RADEON_NUM_RINGS; ++i) {
1362 kfree(ring_data[i]);1371 kfree(ring_data[i]);
1363 }1372 }
1364 }1373 }
1365 1374
1375 drm_helper_resume_force_mode(rdev->ddev);
1376
1366 ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);1377 ttm_bo_unlock_delayed_workqueue(&rdev->mman.bdev, resched);
1367 if (r) {1378 if (r) {
1368 /* bad news, how to tell it to userspace ? */1379 /* bad news, how to tell it to userspace ? */
drivers/gpu/drm/radeon/radeon_drv.c+2−1
@@ -68,9 +68,10 @@ · 67 unmodified lines
68 * 2.25.0 - eg+: new info request for num SE and num SH68 * 2.25.0 - eg+: new info request for num SE and num SH
69 * 2.26.0 - r600-eg: fix htile size computation69 * 2.26.0 - r600-eg: fix htile size computation
70 * 2.27.0 - r600-SI: Add CS ioctl support for async DMA70 * 2.27.0 - r600-SI: Add CS ioctl support for async DMA
71 * 2.28.0 - r600-eg: Add MEM_WRITE packet support
71 */72 */
72#define KMS_DRIVER_MAJOR 273#define KMS_DRIVER_MAJOR 2
73#define KMS_DRIVER_MINOR 2774#define KMS_DRIVER_MINOR 28
74#define KMS_DRIVER_PATCHLEVEL 075#define KMS_DRIVER_PATCHLEVEL 0
75int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);76int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
76int radeon_driver_unload_kms(struct drm_device *dev);77int radeon_driver_unload_kms(struct drm_device *dev);
drivers/gpu/drm/radeon/radeon_fence.c+33−16
@@ -609,26 +609,20 @@ int radeon_fence_wait_next_locked(struct radeon_device *rdev, int ring) · 608 unmodified lines
609 * Returns 0 if the fences have passed, error for all other cases.609 * Returns 0 if the fences have passed, error for all other cases.
610 * Caller must hold ring lock.610 * Caller must hold ring lock.
611 */611 */
612void radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring)612int radeon_fence_wait_empty_locked(struct radeon_device *rdev, int ring)
613{613{
614 uint64_t seq = rdev->fence_drv[ring].sync_seq[ring];614 uint64_t seq = rdev->fence_drv[ring].sync_seq[ring];
615 int r;
615 616
616 while(1) {617 r = radeon_fence_wait_seq(rdev, seq, ring, false, false);
617 int r;618 if (r) {
618 r = radeon_fence_wait_seq(rdev, seq, ring, false, false);
619 if (r == -EDEADLK) {619 if (r == -EDEADLK) {
620 mutex_unlock(&rdev->ring_lock);620 return -EDEADLK;
621 r = radeon_gpu_reset(rdev);
622 mutex_lock(&rdev->ring_lock);
623 if (!r)
624 continue;
625 }
626 if (r) {
627 dev_err(rdev->dev, "error waiting for ring to become"
628 " idle (%d)\n", r);
629 }621 }
630 return;622 dev_err(rdev->dev, "error waiting for ring[%d] to become idle (%d)\n",
623 ring, r);
631 }624 }
625 return 0;
632}626}
633 627
634/**628/**
@@ -854,13 +848,17 @@ int radeon_fence_driver_init(struct radeon_device *rdev) · 219 unmodified lines
854 */848 */
855void radeon_fence_driver_fini(struct radeon_device *rdev)849void radeon_fence_driver_fini(struct radeon_device *rdev)
856{850{
857 int ring;851 int ring, r;
858 852
859 mutex_lock(&rdev->ring_lock);853 mutex_lock(&rdev->ring_lock);
860 for (ring = 0; ring < RADEON_NUM_RINGS; ring++) {854 for (ring = 0; ring < RADEON_NUM_RINGS; ring++) {
861 if (!rdev->fence_drv[ring].initialized)855 if (!rdev->fence_drv[ring].initialized)
862 continue;856 continue;
863 radeon_fence_wait_empty_locked(rdev, ring);857 r = radeon_fence_wait_empty_locked(rdev, ring);
858 if (r) {
859 /* no need to trigger GPU reset as we are unloading */
860 radeon_fence_driver_force_completion(rdev);
861 }
864 wake_up_all(&rdev->fence_queue);862 wake_up_all(&rdev->fence_queue);
865 radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);863 radeon_scratch_free(rdev, rdev->fence_drv[ring].scratch_reg);
866 rdev->fence_drv[ring].initialized = false;864 rdev->fence_drv[ring].initialized = false;
@@ -868,6 +866,25 @@ void radeon_fence_driver_fini(struct radeon_device *rdev) · 1 unmodified line
868 mutex_unlock(&rdev->ring_lock);866 mutex_unlock(&rdev->ring_lock);
869}867}
870 868
869/**
870 * radeon_fence_driver_force_completion - force all fence waiter to complete
871 *
872 * @rdev: radeon device pointer
873 *
874 * In case of GPU reset failure make sure no process keep waiting on fence
875 * that will never complete.
876 */
877void radeon_fence_driver_force_completion(struct radeon_device *rdev)
878{
879 int ring;
880
881 for (ring = 0; ring < RADEON_NUM_RINGS; ring++) {
882 if (!rdev->fence_drv[ring].initialized)
883 continue;
884 radeon_fence_write(rdev, rdev->fence_drv[ring].sync_seq[ring], ring);
885 }
886}
887
871 888
872/*889/*
873 * Fence debugfs890 * Fence debugfs
drivers/gpu/drm/radeon/radeon_pm.c+12−3
@@ -234,7 +234,7 @@ static void radeon_set_power_state(struct radeon_device *rdev) · 233 unmodified lines
234 234
235static void radeon_pm_set_clocks(struct radeon_device *rdev)235static void radeon_pm_set_clocks(struct radeon_device *rdev)
236{236{
237 int i;237 int i, r;
238 238
239 /* no need to take locks, etc. if nothing's going to change */239 /* no need to take locks, etc. if nothing's going to change */
240 if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) &&240 if ((rdev->pm.requested_clock_mode_index == rdev->pm.current_clock_mode_index) &&
@@ -248,8 +248,17 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev) · 7 unmodified lines
248 /* wait for the rings to drain */248 /* wait for the rings to drain */
249 for (i = 0; i < RADEON_NUM_RINGS; i++) {249 for (i = 0; i < RADEON_NUM_RINGS; i++) {
250 struct radeon_ring *ring = &rdev->ring[i];250 struct radeon_ring *ring = &rdev->ring[i];
251 if (ring->ready)251 if (!ring->ready) {
252 radeon_fence_wait_empty_locked(rdev, i);252 continue;
253 }
254 r = radeon_fence_wait_empty_locked(rdev, i);
255 if (r) {
256 /* needs a GPU reset dont reset here */
257 mutex_unlock(&rdev->ring_lock);
258 up_write(&rdev->pm.mclk_lock);
259 mutex_unlock(&rdev->ddev->struct_mutex);
260 return;
261 }
253 }262 }
254 263
255 radeon_unmap_vram_bos(rdev);264 radeon_unmap_vram_bos(rdev);