Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge tag 'drm-vc4-fixes-2016-06-06' of github.com:anholt/linux into drm-fixes

This pull request brings in vblank/pageflip fixes I had hoped to see
merged before 4.7rc1, plus two new fixes that have come in since then.

* tag 'drm-vc4-fixes-2016-06-06' of github.com:anholt/linux:
drm/vc4: Make pageflip completion handling more robust.
drm/vc4: Fix ioctl permissions for render nodes.
drm/vc4: Return -EBUSY if there's already a pending flip event.
drm/vc4: Fix drm_vblank_put/get imbalance in page flip path.
drm/vc4: Fix get_vblank_counter with proper no-op for Linux 4.4+

+45 -21
+22 -10
drivers/gpu/drm/vc4/vc4_crtc.c
··· 456 456 457 457 WARN_ON_ONCE(dlist_next - dlist_start != vc4_state->mm.size); 458 458 459 - HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), 460 - vc4_state->mm.start); 461 - 462 - if (debug_dump_regs) { 463 - DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc)); 464 - vc4_hvs_dump_state(dev); 465 - } 466 - 467 459 if (crtc->state->event) { 468 460 unsigned long flags; 469 461 ··· 465 473 466 474 spin_lock_irqsave(&dev->event_lock, flags); 467 475 vc4_crtc->event = crtc->state->event; 468 - spin_unlock_irqrestore(&dev->event_lock, flags); 469 476 crtc->state->event = NULL; 477 + 478 + HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), 479 + vc4_state->mm.start); 480 + 481 + spin_unlock_irqrestore(&dev->event_lock, flags); 482 + } else { 483 + HVS_WRITE(SCALER_DISPLISTX(vc4_crtc->channel), 484 + vc4_state->mm.start); 485 + } 486 + 487 + if (debug_dump_regs) { 488 + DRM_INFO("CRTC %d HVS after:\n", drm_crtc_index(crtc)); 489 + vc4_hvs_dump_state(dev); 470 490 } 471 491 } 472 492 ··· 504 500 { 505 501 struct drm_crtc *crtc = &vc4_crtc->base; 506 502 struct drm_device *dev = crtc->dev; 503 + struct vc4_dev *vc4 = to_vc4_dev(dev); 504 + struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); 505 + u32 chan = vc4_crtc->channel; 507 506 unsigned long flags; 508 507 509 508 spin_lock_irqsave(&dev->event_lock, flags); 510 - if (vc4_crtc->event) { 509 + if (vc4_crtc->event && 510 + (vc4_state->mm.start == HVS_READ(SCALER_DISPLACTX(chan)))) { 511 511 drm_crtc_send_vblank_event(crtc, vc4_crtc->event); 512 512 vc4_crtc->event = NULL; 513 + drm_crtc_vblank_put(crtc); 513 514 } 514 515 spin_unlock_irqrestore(&dev->event_lock, flags); 515 516 } ··· 565 556 spin_unlock_irqrestore(&dev->event_lock, flags); 566 557 } 567 558 559 + drm_crtc_vblank_put(crtc); 568 560 drm_framebuffer_unreference(flip_state->fb); 569 561 kfree(flip_state); 570 562 ··· 607 597 kfree(flip_state); 608 598 return ret; 609 599 } 600 + 601 + WARN_ON(drm_crtc_vblank_get(crtc) != 0); 610 602 611 603 /* Immediately update the plane's legacy fb pointer, so that later 612 604 * modeset prep sees the state that will be present when the semaphore
+7 -7
drivers/gpu/drm/vc4/vc4_drv.c
··· 66 66 }; 67 67 68 68 static const struct drm_ioctl_desc vc4_drm_ioctls[] = { 69 - DRM_IOCTL_DEF_DRV(VC4_SUBMIT_CL, vc4_submit_cl_ioctl, 0), 70 - DRM_IOCTL_DEF_DRV(VC4_WAIT_SEQNO, vc4_wait_seqno_ioctl, 0), 71 - DRM_IOCTL_DEF_DRV(VC4_WAIT_BO, vc4_wait_bo_ioctl, 0), 72 - DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, 0), 73 - DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, 0), 74 - DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, 0), 69 + DRM_IOCTL_DEF_DRV(VC4_SUBMIT_CL, vc4_submit_cl_ioctl, DRM_RENDER_ALLOW), 70 + DRM_IOCTL_DEF_DRV(VC4_WAIT_SEQNO, vc4_wait_seqno_ioctl, DRM_RENDER_ALLOW), 71 + DRM_IOCTL_DEF_DRV(VC4_WAIT_BO, vc4_wait_bo_ioctl, DRM_RENDER_ALLOW), 72 + DRM_IOCTL_DEF_DRV(VC4_CREATE_BO, vc4_create_bo_ioctl, DRM_RENDER_ALLOW), 73 + DRM_IOCTL_DEF_DRV(VC4_MMAP_BO, vc4_mmap_bo_ioctl, DRM_RENDER_ALLOW), 74 + DRM_IOCTL_DEF_DRV(VC4_CREATE_SHADER_BO, vc4_create_shader_bo_ioctl, DRM_RENDER_ALLOW), 75 75 DRM_IOCTL_DEF_DRV(VC4_GET_HANG_STATE, vc4_get_hang_state_ioctl, 76 76 DRM_ROOT_ONLY), 77 77 }; ··· 91 91 92 92 .enable_vblank = vc4_enable_vblank, 93 93 .disable_vblank = vc4_disable_vblank, 94 - .get_vblank_counter = drm_vblank_count, 94 + .get_vblank_counter = drm_vblank_no_hw_counter, 95 95 96 96 #if defined(CONFIG_DEBUG_FS) 97 97 .debugfs_init = vc4_debugfs_init,
+12 -4
drivers/gpu/drm/vc4/vc4_kms.c
··· 117 117 return -ENOMEM; 118 118 119 119 /* Make sure that any outstanding modesets have finished. */ 120 - ret = down_interruptible(&vc4->async_modeset); 121 - if (ret) { 122 - kfree(c); 123 - return ret; 120 + if (nonblock) { 121 + ret = down_trylock(&vc4->async_modeset); 122 + if (ret) { 123 + kfree(c); 124 + return -EBUSY; 125 + } 126 + } else { 127 + ret = down_interruptible(&vc4->async_modeset); 128 + if (ret) { 129 + kfree(c); 130 + return ret; 131 + } 124 132 } 125 133 126 134 ret = drm_atomic_helper_prepare_planes(dev, state);
+4
drivers/gpu/drm/vc4/vc4_regs.h
··· 341 341 #define SCALER_DISPLACT0 0x00000030 342 342 #define SCALER_DISPLACT1 0x00000034 343 343 #define SCALER_DISPLACT2 0x00000038 344 + #define SCALER_DISPLACTX(x) (SCALER_DISPLACT0 + \ 345 + (x) * (SCALER_DISPLACT1 - \ 346 + SCALER_DISPLACT0)) 347 + 344 348 #define SCALER_DISPCTRL0 0x00000040 345 349 # define SCALER_DISPCTRLX_ENABLE BIT(31) 346 350 # define SCALER_DISPCTRLX_RESET BIT(30)