aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-11-10 18:28:44 -0500
committerDave Airlie <airlied@redhat.com>2016-11-10 18:28:44 -0500
commit3e91168a6a76f7e21c44f04ebf953589ca59f03c (patch)
tree27b12142f17fc575fd40825b91e7e8773994f13d
parentdb8feb6979e91c2e916631a75dbfe9f10f6b05e5 (diff)
parent4b514e10157a8e34a5e909487ef6fb8342e2e3ad (diff)
Merge tag 'topic/drm-misc-2016-11-10' of git://anongit.freedesktop.org/drm-intel into drm-next
- better atomic state debugging from Rob - fence prep from gustavo - sumits flushed out his backlog of pending dma-buf/fence patches from various people - drm_mm leak debugging plus trying to appease Kconfig (Chris) - a few misc things all over * tag 'topic/drm-misc-2016-11-10' of git://anongit.freedesktop.org/drm-intel: (35 commits) drm: Make DRM_DEBUG_MM depend on STACKTRACE_SUPPORT drm/i915: Restrict DRM_DEBUG_MM automatic selection drm: Restrict stackdepot usage to builtin drm.ko drm/msm: module param to dump state on error irq drm/msm/mdp5: add atomic_print_state support drm/atomic: add debugfs file to dump out atomic state drm/atomic: add new drm_debug bit to dump atomic state drm: add helpers to go from plane state to drm_rect drm: add helper for printing to log or seq_file drm: helper macros to print composite types reservation: revert "wait only with non-zero timeout specified (v3)" v2 drm/ttm: fix ttm_bo_wait dma-buf/fence: revert "don't wait when specified timeout is zero" (v2) dma-buf/fence: make timeout handling in fence_default_wait consistent (v2) drm/amdgpu: add the interface of waiting multiple fences (v4) dma-buf: return index of the first signaled fence (v2) MAINTAINERS: update Sync File Framework files dma-buf/sw_sync: put fence reference from the fence creation dma-buf/sw_sync: mark sync_timeline_create() static drm: Add stackdepot include for DRM_DEBUG_MM ...
-rw-r--r--Documentation/gpu/drm-internals.rst17
-rw-r--r--MAINTAINERS4
-rw-r--r--drivers/dma-buf/dma-fence.c32
-rw-r--r--drivers/dma-buf/reservation.c5
-rw-r--r--drivers/dma-buf/sw_sync.c4
-rw-r--r--drivers/gpu/drm/Kconfig14
-rw-r--r--drivers/gpu/drm/Makefile2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c174
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c1
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c3
-rw-r--r--drivers/gpu/drm/arc/arcpgu_drv.c2
-rw-r--r--drivers/gpu/drm/arm/hdlcd_drv.c2
-rw-r--r--drivers/gpu/drm/arm/malidp_drv.c2
-rw-r--r--drivers/gpu/drm/ast/ast_drv.c2
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c2
-rw-r--r--drivers/gpu/drm/bochs/bochs_drv.c2
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_drv.c2
-rw-r--r--drivers/gpu/drm/drm_atomic.c186
-rw-r--r--drivers/gpu/drm/drm_crtc.c4
-rw-r--r--drivers/gpu/drm/drm_debugfs.c9
-rw-r--r--drivers/gpu/drm/drm_edid.c4
-rw-r--r--drivers/gpu/drm/drm_fops.c13
-rw-r--r--drivers/gpu/drm/drm_framebuffer.c5
-rw-r--r--drivers/gpu/drm/drm_mm.c76
-rw-r--r--drivers/gpu/drm/drm_modes.c8
-rw-r--r--drivers/gpu/drm/drm_plane_helper.c11
-rw-r--r--drivers/gpu/drm/drm_print.c54
-rw-r--r--drivers/gpu/drm/drm_rect.c11
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_drv.c2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c2
-rw-r--r--drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c2
-rw-r--r--drivers/gpu/drm/gma500/gtt.c2
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.c1
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.h4
-rw-r--r--drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c2
-rw-r--r--drivers/gpu/drm/i810/i810_dma.c2
-rw-r--r--drivers/gpu/drm/i810/i810_drv.c2
-rw-r--r--drivers/gpu/drm/i915/Kconfig.debug1
-rw-r--r--drivers/gpu/drm/i915/i915_drv.c2
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h2
-rw-r--r--drivers/gpu/drm/i915/intel_display.c10
-rw-r--r--drivers/gpu/drm/i915/intel_sprite.c11
-rw-r--r--drivers/gpu/drm/imx/imx-drm-core.c6
-rw-r--r--drivers/gpu/drm/mediatek/mtk_drm_drv.c2
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_drv.c2
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c10
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c11
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h12
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c18
-rw-r--r--drivers/gpu/drm/msm/msm_atomic.c3
-rw-r--r--drivers/gpu/drm/msm/msm_drv.c6
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_drv.c2
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_drv.c2
-rw-r--r--drivers/gpu/drm/savage/savage_drv.c2
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_drv.c2
-rw-r--r--drivers/gpu/drm/sis/sis_drv.c2
-rw-r--r--drivers/gpu/drm/sti/sti_drv.c2
-rw-r--r--drivers/gpu/drm/sun4i/sun4i_drv.c2
-rw-r--r--drivers/gpu/drm/tdfx/tdfx_drv.c2
-rw-r--r--drivers/gpu/drm/tegra/drm.c2
-rw-r--r--drivers/gpu/drm/tilcdc/tilcdc_drv.c2
-rw-r--r--drivers/gpu/drm/ttm/ttm_bo.c9
-rw-r--r--drivers/gpu/drm/udl/udl_drv.c2
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.c2
-rw-r--r--drivers/gpu/drm/via/via_drv.c2
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_drv.c2
-rw-r--r--include/drm/drmP.h27
-rw-r--r--include/drm/drm_atomic.h9
-rw-r--r--include/drm/drm_connector.h13
-rw-r--r--include/drm/drm_crtc.h13
-rw-r--r--include/drm/drm_mm.h6
-rw-r--r--include/drm/drm_modeset_helper_vtables.h16
-rw-r--r--include/drm/drm_plane.h93
-rw-r--r--include/drm/drm_print.h117
-rw-r--r--include/linux/dma-fence.h3
-rw-r--r--include/uapi/drm/amdgpu_drm.h28
-rw-r--r--include/uapi/drm/drm_mode.h10
78 files changed, 969 insertions, 171 deletions
diff --git a/Documentation/gpu/drm-internals.rst b/Documentation/gpu/drm-internals.rst
index 37284bcc7764..25ee92c5df65 100644
--- a/Documentation/gpu/drm-internals.rst
+++ b/Documentation/gpu/drm-internals.rst
@@ -350,6 +350,23 @@ how the ioctl is allowed to be called.
350.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c 350.. kernel-doc:: drivers/gpu/drm/drm_ioctl.c
351 :export: 351 :export:
352 352
353
354Misc Utilities
355==============
356
357Printer
358-------
359
360.. kernel-doc:: include/drm/drm_print.h
361 :doc: print
362
363.. kernel-doc:: include/drm/drm_print.h
364 :internal:
365
366.. kernel-doc:: include/drm/drm_print.h
367 :export:
368
369
353Legacy Support Code 370Legacy Support Code
354=================== 371===================
355 372
diff --git a/MAINTAINERS b/MAINTAINERS
index 955134d22cff..561d4174cdfe 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -3919,8 +3919,10 @@ R: Gustavo Padovan <gustavo@padovan.org>
3919S: Maintained 3919S: Maintained
3920L: linux-media@vger.kernel.org 3920L: linux-media@vger.kernel.org
3921L: dri-devel@lists.freedesktop.org 3921L: dri-devel@lists.freedesktop.org
3922F: drivers/dma-buf/sync_file.c 3922F: drivers/dma-buf/sync_*
3923F: drivers/dma-buf/sw_sync.c
3923F: include/linux/sync_file.h 3924F: include/linux/sync_file.h
3925F: include/uapi/linux/sync_file.h
3924F: Documentation/sync_file.txt 3926F: Documentation/sync_file.txt
3925T: git git://git.linaro.org/people/sumitsemwal/linux-dma-buf.git 3927T: git git://git.linaro.org/people/sumitsemwal/linux-dma-buf.git
3926 3928
diff --git a/drivers/dma-buf/dma-fence.c b/drivers/dma-buf/dma-fence.c
index 3a7bf009c21c..0212af7997d9 100644
--- a/drivers/dma-buf/dma-fence.c
+++ b/drivers/dma-buf/dma-fence.c
@@ -161,9 +161,6 @@ dma_fence_wait_timeout(struct dma_fence *fence, bool intr, signed long timeout)
161 if (WARN_ON(timeout < 0)) 161 if (WARN_ON(timeout < 0))
162 return -EINVAL; 162 return -EINVAL;
163 163
164 if (timeout == 0)
165 return dma_fence_is_signaled(fence);
166
167 trace_dma_fence_wait_start(fence); 164 trace_dma_fence_wait_start(fence);
168 ret = fence->ops->wait(fence, intr, timeout); 165 ret = fence->ops->wait(fence, intr, timeout);
169 trace_dma_fence_wait_end(fence); 166 trace_dma_fence_wait_end(fence);
@@ -339,18 +336,20 @@ dma_fence_default_wait_cb(struct dma_fence *fence, struct dma_fence_cb *cb)
339 * @timeout: [in] timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT 336 * @timeout: [in] timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT
340 * 337 *
341 * Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or the 338 * Returns -ERESTARTSYS if interrupted, 0 if the wait timed out, or the
342 * remaining timeout in jiffies on success. 339 * remaining timeout in jiffies on success. If timeout is zero the value one is
340 * returned if the fence is already signaled for consistency with other
341 * functions taking a jiffies timeout.
343 */ 342 */
344signed long 343signed long
345dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout) 344dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout)
346{ 345{
347 struct default_wait_cb cb; 346 struct default_wait_cb cb;
348 unsigned long flags; 347 unsigned long flags;
349 signed long ret = timeout; 348 signed long ret = timeout ? timeout : 1;
350 bool was_set; 349 bool was_set;
351 350
352 if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) 351 if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
353 return timeout; 352 return ret;
354 353
355 spin_lock_irqsave(fence->lock, flags); 354 spin_lock_irqsave(fence->lock, flags);
356 355
@@ -403,14 +402,18 @@ out:
403EXPORT_SYMBOL(dma_fence_default_wait); 402EXPORT_SYMBOL(dma_fence_default_wait);
404 403
405static bool 404static bool
406dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count) 405dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count,
406 uint32_t *idx)
407{ 407{
408 int i; 408 int i;
409 409
410 for (i = 0; i < count; ++i) { 410 for (i = 0; i < count; ++i) {
411 struct dma_fence *fence = fences[i]; 411 struct dma_fence *fence = fences[i];
412 if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) 412 if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
413 if (idx)
414 *idx = i;
413 return true; 415 return true;
416 }
414 } 417 }
415 return false; 418 return false;
416} 419}
@@ -422,6 +425,8 @@ dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count)
422 * @count: [in] number of fences to wait on 425 * @count: [in] number of fences to wait on
423 * @intr: [in] if true, do an interruptible wait 426 * @intr: [in] if true, do an interruptible wait
424 * @timeout: [in] timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT 427 * @timeout: [in] timeout value in jiffies, or MAX_SCHEDULE_TIMEOUT
428 * @idx: [out] the first signaled fence index, meaningful only on
429 * positive return
425 * 430 *
426 * Returns -EINVAL on custom fence wait implementation, -ERESTARTSYS if 431 * Returns -EINVAL on custom fence wait implementation, -ERESTARTSYS if
427 * interrupted, 0 if the wait timed out, or the remaining timeout in jiffies 432 * interrupted, 0 if the wait timed out, or the remaining timeout in jiffies
@@ -433,7 +438,7 @@ dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count)
433 */ 438 */
434signed long 439signed long
435dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count, 440dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count,
436 bool intr, signed long timeout) 441 bool intr, signed long timeout, uint32_t *idx)
437{ 442{
438 struct default_wait_cb *cb; 443 struct default_wait_cb *cb;
439 signed long ret = timeout; 444 signed long ret = timeout;
@@ -444,8 +449,11 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count,
444 449
445 if (timeout == 0) { 450 if (timeout == 0) {
446 for (i = 0; i < count; ++i) 451 for (i = 0; i < count; ++i)
447 if (dma_fence_is_signaled(fences[i])) 452 if (dma_fence_is_signaled(fences[i])) {
453 if (idx)
454 *idx = i;
448 return 1; 455 return 1;
456 }
449 457
450 return 0; 458 return 0;
451 } 459 }
@@ -468,6 +476,8 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count,
468 if (dma_fence_add_callback(fence, &cb[i].base, 476 if (dma_fence_add_callback(fence, &cb[i].base,
469 dma_fence_default_wait_cb)) { 477 dma_fence_default_wait_cb)) {
470 /* This fence is already signaled */ 478 /* This fence is already signaled */
479 if (idx)
480 *idx = i;
471 goto fence_rm_cb; 481 goto fence_rm_cb;
472 } 482 }
473 } 483 }
@@ -478,7 +488,7 @@ dma_fence_wait_any_timeout(struct dma_fence **fences, uint32_t count,
478 else 488 else
479 set_current_state(TASK_UNINTERRUPTIBLE); 489 set_current_state(TASK_UNINTERRUPTIBLE);
480 490
481 if (dma_fence_test_signaled_any(fences, count)) 491 if (dma_fence_test_signaled_any(fences, count, idx))
482 break; 492 break;
483 493
484 ret = schedule_timeout(ret); 494 ret = schedule_timeout(ret);
diff --git a/drivers/dma-buf/reservation.c b/drivers/dma-buf/reservation.c
index 7ed56f3edfb7..393817e849ed 100644
--- a/drivers/dma-buf/reservation.c
+++ b/drivers/dma-buf/reservation.c
@@ -370,10 +370,7 @@ long reservation_object_wait_timeout_rcu(struct reservation_object *obj,
370{ 370{
371 struct dma_fence *fence; 371 struct dma_fence *fence;
372 unsigned seq, shared_count, i = 0; 372 unsigned seq, shared_count, i = 0;
373 long ret = timeout; 373 long ret = timeout ? timeout : 1;
374
375 if (!timeout)
376 return reservation_object_test_signaled_rcu(obj, wait_all);
377 374
378retry: 375retry:
379 fence = NULL; 376 fence = NULL;
diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c
index 82e0ca4dd0c1..69c5ff36e2f9 100644
--- a/drivers/dma-buf/sw_sync.c
+++ b/drivers/dma-buf/sw_sync.c
@@ -84,7 +84,7 @@ static inline struct sync_pt *dma_fence_to_sync_pt(struct dma_fence *fence)
84 * Creates a new sync_timeline. Returns the sync_timeline object or NULL in 84 * Creates a new sync_timeline. Returns the sync_timeline object or NULL in
85 * case of error. 85 * case of error.
86 */ 86 */
87struct sync_timeline *sync_timeline_create(const char *name) 87static struct sync_timeline *sync_timeline_create(const char *name)
88{ 88{
89 struct sync_timeline *obj; 89 struct sync_timeline *obj;
90 90
@@ -316,8 +316,8 @@ static long sw_sync_ioctl_create_fence(struct sync_timeline *obj,
316 } 316 }
317 317
318 sync_file = sync_file_create(&pt->base); 318 sync_file = sync_file_create(&pt->base);
319 dma_fence_put(&pt->base);
319 if (!sync_file) { 320 if (!sync_file) {
320 dma_fence_put(&pt->base);
321 err = -ENOMEM; 321 err = -ENOMEM;
322 goto err; 322 goto err;
323 } 323 }
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 483059a22b1b..2ac0a564af60 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -33,6 +33,20 @@ config DRM_DP_AUX_CHARDEV
33 read and write values to arbitrary DPCD registers on the DP aux 33 read and write values to arbitrary DPCD registers on the DP aux
34 channel. 34 channel.
35 35
36config DRM_DEBUG_MM
37 bool "Insert extra checks and debug info into the DRM range managers"
38 default n
39 depends on DRM=y
40 depends on STACKTRACE_SUPPORT
41 select STACKDEPOT
42 help
43 Enable allocation tracking of memory manager and leak detection on
44 shutdown.
45
46 Recommended for driver developers only.
47
48 If in doubt, say "N".
49
36config DRM_KMS_HELPER 50config DRM_KMS_HELPER
37 tristate 51 tristate
38 depends on DRM 52 depends on DRM
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 74579d2e796e..c1d0602fbe24 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -15,7 +15,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \
15 drm_modeset_lock.o drm_atomic.o drm_bridge.o \ 15 drm_modeset_lock.o drm_atomic.o drm_bridge.o \
16 drm_framebuffer.o drm_connector.o drm_blend.o \ 16 drm_framebuffer.o drm_connector.o drm_blend.o \
17 drm_encoder.o drm_mode_object.o drm_property.o \ 17 drm_encoder.o drm_mode_object.o drm_property.o \
18 drm_plane.o drm_color_mgmt.o 18 drm_plane.o drm_color_mgmt.o drm_print.o
19 19
20drm-$(CONFIG_COMPAT) += drm_ioc32.o 20drm-$(CONFIG_COMPAT) += drm_ioc32.o
21drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o 21drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 2ec7b3baeec2..c2b8496cdf63 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -1212,6 +1212,8 @@ int amdgpu_gem_op_ioctl(struct drm_device *dev, void *data,
1212 struct drm_file *filp); 1212 struct drm_file *filp);
1213int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); 1213int amdgpu_cs_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
1214int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *filp); 1214int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data, struct drm_file *filp);
1215int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data,
1216 struct drm_file *filp);
1215 1217
1216int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data, 1218int amdgpu_gem_metadata_ioctl(struct drm_device *dev, void *data,
1217 struct drm_file *filp); 1219 struct drm_file *filp);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
index a370101d923f..78da52f90099 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_cs.c
@@ -1141,6 +1141,180 @@ int amdgpu_cs_wait_ioctl(struct drm_device *dev, void *data,
1141} 1141}
1142 1142
1143/** 1143/**
1144 * amdgpu_cs_get_fence - helper to get fence from drm_amdgpu_fence
1145 *
1146 * @adev: amdgpu device
1147 * @filp: file private
1148 * @user: drm_amdgpu_fence copied from user space
1149 */
1150static struct dma_fence *amdgpu_cs_get_fence(struct amdgpu_device *adev,
1151 struct drm_file *filp,
1152 struct drm_amdgpu_fence *user)
1153{
1154 struct amdgpu_ring *ring;
1155 struct amdgpu_ctx *ctx;
1156 struct dma_fence *fence;
1157 int r;
1158
1159 r = amdgpu_cs_get_ring(adev, user->ip_type, user->ip_instance,
1160 user->ring, &ring);
1161 if (r)
1162 return ERR_PTR(r);
1163
1164 ctx = amdgpu_ctx_get(filp->driver_priv, user->ctx_id);
1165 if (ctx == NULL)
1166 return ERR_PTR(-EINVAL);
1167
1168 fence = amdgpu_ctx_get_fence(ctx, ring, user->seq_no);
1169 amdgpu_ctx_put(ctx);
1170
1171 return fence;
1172}
1173
1174/**
1175 * amdgpu_cs_wait_all_fence - wait on all fences to signal
1176 *
1177 * @adev: amdgpu device
1178 * @filp: file private
1179 * @wait: wait parameters
1180 * @fences: array of drm_amdgpu_fence
1181 */
1182static int amdgpu_cs_wait_all_fences(struct amdgpu_device *adev,
1183 struct drm_file *filp,
1184 union drm_amdgpu_wait_fences *wait,
1185 struct drm_amdgpu_fence *fences)
1186{
1187 uint32_t fence_count = wait->in.fence_count;
1188 unsigned int i;
1189 long r = 1;
1190
1191 for (i = 0; i < fence_count; i++) {
1192 struct dma_fence *fence;
1193 unsigned long timeout = amdgpu_gem_timeout(wait->in.timeout_ns);
1194
1195 fence = amdgpu_cs_get_fence(adev, filp, &fences[i]);
1196 if (IS_ERR(fence))
1197 return PTR_ERR(fence);
1198 else if (!fence)
1199 continue;
1200
1201 r = dma_fence_wait_timeout(fence, true, timeout);
1202 if (r < 0)
1203 return r;
1204
1205 if (r == 0)
1206 break;
1207 }
1208
1209 memset(wait, 0, sizeof(*wait));
1210 wait->out.status = (r > 0);
1211
1212 return 0;
1213}
1214
1215/**
1216 * amdgpu_cs_wait_any_fence - wait on any fence to signal
1217 *
1218 * @adev: amdgpu device
1219 * @filp: file private
1220 * @wait: wait parameters
1221 * @fences: array of drm_amdgpu_fence
1222 */
1223static int amdgpu_cs_wait_any_fence(struct amdgpu_device *adev,
1224 struct drm_file *filp,
1225 union drm_amdgpu_wait_fences *wait,
1226 struct drm_amdgpu_fence *fences)
1227{
1228 unsigned long timeout = amdgpu_gem_timeout(wait->in.timeout_ns);
1229 uint32_t fence_count = wait->in.fence_count;
1230 uint32_t first = ~0;
1231 struct dma_fence **array;
1232 unsigned int i;
1233 long r;
1234
1235 /* Prepare the fence array */
1236 array = kcalloc(fence_count, sizeof(struct dma_fence *), GFP_KERNEL);
1237
1238 if (array == NULL)
1239 return -ENOMEM;
1240
1241 for (i = 0; i < fence_count; i++) {
1242 struct dma_fence *fence;
1243
1244 fence = amdgpu_cs_get_fence(adev, filp, &fences[i]);
1245 if (IS_ERR(fence)) {
1246 r = PTR_ERR(fence);
1247 goto err_free_fence_array;
1248 } else if (fence) {
1249 array[i] = fence;
1250 } else { /* NULL, the fence has been already signaled */
1251 r = 1;
1252 goto out;
1253 }
1254 }
1255
1256 r = dma_fence_wait_any_timeout(array, fence_count, true, timeout,
1257 &first);
1258 if (r < 0)
1259 goto err_free_fence_array;
1260
1261out:
1262 memset(wait, 0, sizeof(*wait));
1263 wait->out.status = (r > 0);
1264 wait->out.first_signaled = first;
1265 /* set return value 0 to indicate success */
1266 r = 0;
1267
1268err_free_fence_array:
1269 for (i = 0; i < fence_count; i++)
1270 dma_fence_put(array[i]);
1271 kfree(array);
1272
1273 return r;
1274}
1275
1276/**
1277 * amdgpu_cs_wait_fences_ioctl - wait for multiple command submissions to finish
1278 *
1279 * @dev: drm device
1280 * @data: data from userspace
1281 * @filp: file private
1282 */
1283int amdgpu_cs_wait_fences_ioctl(struct drm_device *dev, void *data,
1284 struct drm_file *filp)
1285{
1286 struct amdgpu_device *adev = dev->dev_private;
1287 union drm_amdgpu_wait_fences *wait = data;
1288 uint32_t fence_count = wait->in.fence_count;
1289 struct drm_amdgpu_fence *fences_user;
1290 struct drm_amdgpu_fence *fences;
1291 int r;
1292
1293 /* Get the fences from userspace */
1294 fences = kmalloc_array(fence_count, sizeof(struct drm_amdgpu_fence),
1295 GFP_KERNEL);
1296 if (fences == NULL)
1297 return -ENOMEM;
1298
1299 fences_user = (void __user *)(unsigned long)(wait->in.fences);
1300 if (copy_from_user(fences, fences_user,
1301 sizeof(struct drm_amdgpu_fence) * fence_count)) {
1302 r = -EFAULT;
1303 goto err_free_fences;
1304 }
1305
1306 if (wait->in.wait_all)
1307 r = amdgpu_cs_wait_all_fences(adev, filp, wait, fences);
1308 else
1309 r = amdgpu_cs_wait_any_fence(adev, filp, wait, fences);
1310
1311err_free_fences:
1312 kfree(fences);
1313
1314 return r;
1315}
1316
1317/**
1144 * amdgpu_cs_find_bo_va - find bo_va for VM address 1318 * amdgpu_cs_find_bo_va - find bo_va for VM address
1145 * 1319 *
1146 * @parser: command submission parser context 1320 * @parser: command submission parser context
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
index 55c413a55a40..ad908612aff9 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c
@@ -823,6 +823,7 @@ const struct drm_ioctl_desc amdgpu_ioctls_kms[] = {
823 DRM_IOCTL_DEF_DRV(AMDGPU_CS, amdgpu_cs_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 823 DRM_IOCTL_DEF_DRV(AMDGPU_CS, amdgpu_cs_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
824 DRM_IOCTL_DEF_DRV(AMDGPU_INFO, amdgpu_info_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 824 DRM_IOCTL_DEF_DRV(AMDGPU_INFO, amdgpu_info_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
825 DRM_IOCTL_DEF_DRV(AMDGPU_WAIT_CS, amdgpu_cs_wait_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 825 DRM_IOCTL_DEF_DRV(AMDGPU_WAIT_CS, amdgpu_cs_wait_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
826 DRM_IOCTL_DEF_DRV(AMDGPU_WAIT_FENCES, amdgpu_cs_wait_fences_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
826 DRM_IOCTL_DEF_DRV(AMDGPU_GEM_METADATA, amdgpu_gem_metadata_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 827 DRM_IOCTL_DEF_DRV(AMDGPU_GEM_METADATA, amdgpu_gem_metadata_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
827 DRM_IOCTL_DEF_DRV(AMDGPU_GEM_VA, amdgpu_gem_va_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 828 DRM_IOCTL_DEF_DRV(AMDGPU_GEM_VA, amdgpu_gem_va_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
828 DRM_IOCTL_DEF_DRV(AMDGPU_GEM_OP, amdgpu_gem_op_ioctl, DRM_AUTH|DRM_RENDER_ALLOW), 829 DRM_IOCTL_DEF_DRV(AMDGPU_GEM_OP, amdgpu_gem_op_ioctl, DRM_AUTH|DRM_RENDER_ALLOW),
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
index fd26c4b8d793..34a795463988 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
@@ -361,7 +361,8 @@ int amdgpu_sa_bo_new(struct amdgpu_sa_manager *sa_manager,
361 if (count) { 361 if (count) {
362 spin_unlock(&sa_manager->wq.lock); 362 spin_unlock(&sa_manager->wq.lock);
363 t = dma_fence_wait_any_timeout(fences, count, false, 363 t = dma_fence_wait_any_timeout(fences, count, false,
364 MAX_SCHEDULE_TIMEOUT); 364 MAX_SCHEDULE_TIMEOUT,
365 NULL);
365 for (i = 0; i < count; ++i) 366 for (i = 0; i < count; ++i)
366 dma_fence_put(fences[i]); 367 dma_fence_put(fences[i]);
367 368
diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index 28e6471257d0..0b6eaa49a1db 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -65,9 +65,7 @@ static const struct file_operations arcpgu_drm_ops = {
65 .open = drm_open, 65 .open = drm_open,
66 .release = drm_release, 66 .release = drm_release,
67 .unlocked_ioctl = drm_ioctl, 67 .unlocked_ioctl = drm_ioctl,
68#ifdef CONFIG_COMPAT
69 .compat_ioctl = drm_compat_ioctl, 68 .compat_ioctl = drm_compat_ioctl,
70#endif
71 .poll = drm_poll, 69 .poll = drm_poll,
72 .read = drm_read, 70 .read = drm_read,
73 .llseek = no_llseek, 71 .llseek = no_llseek,
diff --git a/drivers/gpu/drm/arm/hdlcd_drv.c b/drivers/gpu/drm/arm/hdlcd_drv.c
index 6477d1a65266..59747ecaad54 100644
--- a/drivers/gpu/drm/arm/hdlcd_drv.c
+++ b/drivers/gpu/drm/arm/hdlcd_drv.c
@@ -268,9 +268,7 @@ static const struct file_operations fops = {
268 .open = drm_open, 268 .open = drm_open,
269 .release = drm_release, 269 .release = drm_release,
270 .unlocked_ioctl = drm_ioctl, 270 .unlocked_ioctl = drm_ioctl,
271#ifdef CONFIG_COMPAT
272 .compat_ioctl = drm_compat_ioctl, 271 .compat_ioctl = drm_compat_ioctl,
273#endif
274 .poll = drm_poll, 272 .poll = drm_poll,
275 .read = drm_read, 273 .read = drm_read,
276 .llseek = noop_llseek, 274 .llseek = noop_llseek,
diff --git a/drivers/gpu/drm/arm/malidp_drv.c b/drivers/gpu/drm/arm/malidp_drv.c
index 9f4739452a25..d53b625b14fe 100644
--- a/drivers/gpu/drm/arm/malidp_drv.c
+++ b/drivers/gpu/drm/arm/malidp_drv.c
@@ -197,9 +197,7 @@ static const struct file_operations fops = {
197 .open = drm_open, 197 .open = drm_open,
198 .release = drm_release, 198 .release = drm_release,
199 .unlocked_ioctl = drm_ioctl, 199 .unlocked_ioctl = drm_ioctl,
200#ifdef CONFIG_COMPAT
201 .compat_ioctl = drm_compat_ioctl, 200 .compat_ioctl = drm_compat_ioctl,
202#endif
203 .poll = drm_poll, 201 .poll = drm_poll,
204 .read = drm_read, 202 .read = drm_read,
205 .llseek = noop_llseek, 203 .llseek = noop_llseek,
diff --git a/drivers/gpu/drm/ast/ast_drv.c b/drivers/gpu/drm/ast/ast_drv.c
index f54afd2113a9..fd7c9eec92e4 100644
--- a/drivers/gpu/drm/ast/ast_drv.c
+++ b/drivers/gpu/drm/ast/ast_drv.c
@@ -188,9 +188,7 @@ static const struct file_operations ast_fops = {
188 .unlocked_ioctl = drm_ioctl, 188 .unlocked_ioctl = drm_ioctl,
189 .mmap = ast_mmap, 189 .mmap = ast_mmap,
190 .poll = drm_poll, 190 .poll = drm_poll,
191#ifdef CONFIG_COMPAT
192 .compat_ioctl = drm_compat_ioctl, 191 .compat_ioctl = drm_compat_ioctl,
193#endif
194 .read = drm_read, 192 .read = drm_read,
195}; 193};
196 194
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
index 9f6222895212..cbd0070265c9 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_dc.c
@@ -749,9 +749,7 @@ static const struct file_operations fops = {
749 .open = drm_open, 749 .open = drm_open,
750 .release = drm_release, 750 .release = drm_release,
751 .unlocked_ioctl = drm_ioctl, 751 .unlocked_ioctl = drm_ioctl,
752#ifdef CONFIG_COMPAT
753 .compat_ioctl = drm_compat_ioctl, 752 .compat_ioctl = drm_compat_ioctl,
754#endif
755 .poll = drm_poll, 753 .poll = drm_poll,
756 .read = drm_read, 754 .read = drm_read,
757 .llseek = no_llseek, 755 .llseek = no_llseek,
diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c
index 534227df23f3..15a293e65b31 100644
--- a/drivers/gpu/drm/bochs/bochs_drv.c
+++ b/drivers/gpu/drm/bochs/bochs_drv.c
@@ -70,9 +70,7 @@ static const struct file_operations bochs_fops = {
70 .open = drm_open, 70 .open = drm_open,
71 .release = drm_release, 71 .release = drm_release,
72 .unlocked_ioctl = drm_ioctl, 72 .unlocked_ioctl = drm_ioctl,
73#ifdef CONFIG_COMPAT
74 .compat_ioctl = drm_compat_ioctl, 73 .compat_ioctl = drm_compat_ioctl,
75#endif
76 .poll = drm_poll, 74 .poll = drm_poll,
77 .read = drm_read, 75 .read = drm_read,
78 .llseek = no_llseek, 76 .llseek = no_llseek,
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c
index 6c76d125995b..d893ea21a359 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.c
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.c
@@ -126,9 +126,7 @@ static const struct file_operations cirrus_driver_fops = {
126 .unlocked_ioctl = drm_ioctl, 126 .unlocked_ioctl = drm_ioctl,
127 .mmap = cirrus_mmap, 127 .mmap = cirrus_mmap,
128 .poll = drm_poll, 128 .poll = drm_poll,
129#ifdef CONFIG_COMPAT
130 .compat_ioctl = drm_compat_ioctl, 129 .compat_ioctl = drm_compat_ioctl,
131#endif
132}; 130};
133static struct drm_driver driver = { 131static struct drm_driver driver = {
134 .driver_features = DRIVER_MODESET | DRIVER_GEM, 132 .driver_features = DRIVER_MODESET | DRIVER_GEM,
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index 1d6ab371cd52..f5ea7db4a48a 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -30,6 +30,7 @@
30#include <drm/drm_atomic.h> 30#include <drm/drm_atomic.h>
31#include <drm/drm_mode.h> 31#include <drm/drm_mode.h>
32#include <drm/drm_plane_helper.h> 32#include <drm/drm_plane_helper.h>
33#include <drm/drm_print.h>
33 34
34#include "drm_crtc_internal.h" 35#include "drm_crtc_internal.h"
35 36
@@ -605,6 +606,28 @@ static int drm_atomic_crtc_check(struct drm_crtc *crtc,
605 return 0; 606 return 0;
606} 607}
607 608
609static void drm_atomic_crtc_print_state(struct drm_printer *p,
610 const struct drm_crtc_state *state)
611{
612 struct drm_crtc *crtc = state->crtc;
613
614 drm_printf(p, "crtc[%u]: %s\n", crtc->base.id, crtc->name);
615 drm_printf(p, "\tenable=%d\n", state->enable);
616 drm_printf(p, "\tactive=%d\n", state->active);
617 drm_printf(p, "\tplanes_changed=%d\n", state->planes_changed);
618 drm_printf(p, "\tmode_changed=%d\n", state->mode_changed);
619 drm_printf(p, "\tactive_changed=%d\n", state->active_changed);
620 drm_printf(p, "\tconnectors_changed=%d\n", state->connectors_changed);
621 drm_printf(p, "\tcolor_mgmt_changed=%d\n", state->color_mgmt_changed);
622 drm_printf(p, "\tplane_mask=%x\n", state->plane_mask);
623 drm_printf(p, "\tconnector_mask=%x\n", state->connector_mask);
624 drm_printf(p, "\tencoder_mask=%x\n", state->encoder_mask);
625 drm_printf(p, "\tmode: " DRM_MODE_FMT "\n", DRM_MODE_ARG(&state->mode));
626
627 if (crtc->funcs->atomic_print_state)
628 crtc->funcs->atomic_print_state(p, state);
629}
630
608/** 631/**
609 * drm_atomic_get_plane_state - get plane state 632 * drm_atomic_get_plane_state - get plane state
610 * @state: global atomic state object 633 * @state: global atomic state object
@@ -881,6 +904,38 @@ static int drm_atomic_plane_check(struct drm_plane *plane,
881 return 0; 904 return 0;
882} 905}
883 906
907static void drm_atomic_plane_print_state(struct drm_printer *p,
908 const struct drm_plane_state *state)
909{
910 struct drm_plane *plane = state->plane;
911 struct drm_rect src = drm_plane_state_src(state);
912 struct drm_rect dest = drm_plane_state_dest(state);
913
914 drm_printf(p, "plane[%u]: %s\n", plane->base.id, plane->name);
915 drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
916 drm_printf(p, "\tfb=%u\n", state->fb ? state->fb->base.id : 0);
917 if (state->fb) {
918 struct drm_framebuffer *fb = state->fb;
919 int i, n = drm_format_num_planes(fb->pixel_format);
920
921 drm_printf(p, "\t\tformat=%s\n",
922 drm_get_format_name(fb->pixel_format));
923 drm_printf(p, "\t\tsize=%dx%d\n", fb->width, fb->height);
924 drm_printf(p, "\t\tlayers:\n");
925 for (i = 0; i < n; i++) {
926 drm_printf(p, "\t\t\tpitch[%d]=%u\n", i, fb->pitches[i]);
927 drm_printf(p, "\t\t\toffset[%d]=%u\n", i, fb->offsets[i]);
928 drm_printf(p, "\t\t\tmodifier[%d]=0x%llx\n", i, fb->modifier[i]);
929 }
930 }
931 drm_printf(p, "\tcrtc-pos=" DRM_RECT_FMT "\n", DRM_RECT_ARG(&dest));
932 drm_printf(p, "\tsrc-pos=" DRM_RECT_FP_FMT "\n", DRM_RECT_FP_ARG(&src));
933 drm_printf(p, "\trotation=%x\n", state->rotation);
934
935 if (plane->funcs->atomic_print_state)
936 plane->funcs->atomic_print_state(p, state);
937}
938
884/** 939/**
885 * drm_atomic_get_connector_state - get connector state 940 * drm_atomic_get_connector_state - get connector state
886 * @state: global atomic state object 941 * @state: global atomic state object
@@ -996,6 +1051,18 @@ int drm_atomic_connector_set_property(struct drm_connector *connector,
996} 1051}
997EXPORT_SYMBOL(drm_atomic_connector_set_property); 1052EXPORT_SYMBOL(drm_atomic_connector_set_property);
998 1053
1054static void drm_atomic_connector_print_state(struct drm_printer *p,
1055 const struct drm_connector_state *state)
1056{
1057 struct drm_connector *connector = state->connector;
1058
1059 drm_printf(p, "connector[%u]: %s\n", connector->base.id, connector->name);
1060 drm_printf(p, "\tcrtc=%s\n", state->crtc ? state->crtc->name : "(null)");
1061
1062 if (connector->funcs->atomic_print_state)
1063 connector->funcs->atomic_print_state(p, state);
1064}
1065
999/** 1066/**
1000 * drm_atomic_connector_get_property - get property value from connector state 1067 * drm_atomic_connector_get_property - get property value from connector state
1001 * @connector: the drm connector to set a property on 1068 * @connector: the drm connector to set a property on
@@ -1150,6 +1217,36 @@ drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
1150EXPORT_SYMBOL(drm_atomic_set_fb_for_plane); 1217EXPORT_SYMBOL(drm_atomic_set_fb_for_plane);
1151 1218
1152/** 1219/**
1220 * drm_atomic_set_fence_for_plane - set fence for plane
1221 * @plane_state: atomic state object for the plane
1222 * @fence: dma_fence to use for the plane
1223 *
1224 * Helper to setup the plane_state fence in case it is not set yet.
1225 * By using this drivers doesn't need to worry if the user choose
1226 * implicit or explicit fencing.
1227 *
1228 * This function will not set the fence to the state if it was set
1229 * via explicit fencing interfaces on the atomic ioctl. It will
1230 * all drope the reference to the fence as we not storing it
1231 * anywhere.
1232 *
1233 * Otherwise, if plane_state->fence is not set this function we
1234 * just set it with the received implict fence.
1235 */
1236void
1237drm_atomic_set_fence_for_plane(struct drm_plane_state *plane_state,
1238 struct dma_fence *fence)
1239{
1240 if (plane_state->fence) {
1241 dma_fence_put(fence);
1242 return;
1243 }
1244
1245 plane_state->fence = fence;
1246}
1247EXPORT_SYMBOL(drm_atomic_set_fence_for_plane);
1248
1249/**
1153 * drm_atomic_set_crtc_for_connector - set crtc for connector 1250 * drm_atomic_set_crtc_for_connector - set crtc for connector
1154 * @conn_state: atomic state object for the connector 1251 * @conn_state: atomic state object for the connector
1155 * @crtc: crtc to use for the connector 1252 * @crtc: crtc to use for the connector
@@ -1460,6 +1557,92 @@ int drm_atomic_nonblocking_commit(struct drm_atomic_state *state)
1460} 1557}
1461EXPORT_SYMBOL(drm_atomic_nonblocking_commit); 1558EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
1462 1559
1560static void drm_atomic_print_state(const struct drm_atomic_state *state)
1561{
1562 struct drm_printer p = drm_info_printer(state->dev->dev);
1563 struct drm_plane *plane;
1564 struct drm_plane_state *plane_state;
1565 struct drm_crtc *crtc;
1566 struct drm_crtc_state *crtc_state;
1567 struct drm_connector *connector;
1568 struct drm_connector_state *connector_state;
1569 int i;
1570
1571 DRM_DEBUG_ATOMIC("checking %p\n", state);
1572
1573 for_each_plane_in_state(state, plane, plane_state, i)
1574 drm_atomic_plane_print_state(&p, plane_state);
1575
1576 for_each_crtc_in_state(state, crtc, crtc_state, i)
1577 drm_atomic_crtc_print_state(&p, crtc_state);
1578
1579 for_each_connector_in_state(state, connector, connector_state, i)
1580 drm_atomic_connector_print_state(&p, connector_state);
1581}
1582
1583/**
1584 * drm_state_dump - dump entire device atomic state
1585 * @dev: the drm device
1586 * @p: where to print the state to
1587 *
1588 * Just for debugging. Drivers might want an option to dump state
1589 * to dmesg in case of error irq's. (Hint, you probably want to
1590 * ratelimit this!)
1591 *
1592 * The caller must drm_modeset_lock_all(), or if this is called
1593 * from error irq handler, it should not be enabled by default.
1594 * (Ie. if you are debugging errors you might not care that this
1595 * is racey. But calling this without all modeset locks held is
1596 * not inherently safe.)
1597 */
1598void drm_state_dump(struct drm_device *dev, struct drm_printer *p)
1599{
1600 struct drm_mode_config *config = &dev->mode_config;
1601 struct drm_plane *plane;
1602 struct drm_crtc *crtc;
1603 struct drm_connector *connector;
1604
1605 if (!drm_core_check_feature(dev, DRIVER_ATOMIC))
1606 return;
1607
1608 list_for_each_entry(plane, &config->plane_list, head)
1609 drm_atomic_plane_print_state(p, plane->state);
1610
1611 list_for_each_entry(crtc, &config->crtc_list, head)
1612 drm_atomic_crtc_print_state(p, crtc->state);
1613
1614 list_for_each_entry(connector, &config->connector_list, head)
1615 drm_atomic_connector_print_state(p, connector->state);
1616}
1617EXPORT_SYMBOL(drm_state_dump);
1618
1619#ifdef CONFIG_DEBUG_FS
1620static int drm_state_info(struct seq_file *m, void *data)
1621{
1622 struct drm_info_node *node = (struct drm_info_node *) m->private;
1623 struct drm_device *dev = node->minor->dev;
1624 struct drm_printer p = drm_seq_file_printer(m);
1625
1626 drm_modeset_lock_all(dev);
1627 drm_state_dump(dev, &p);
1628 drm_modeset_unlock_all(dev);
1629
1630 return 0;
1631}
1632
1633/* any use in debugfs files to dump individual planes/crtc/etc? */
1634static const struct drm_info_list drm_atomic_debugfs_list[] = {
1635 {"state", drm_state_info, 0},
1636};
1637
1638int drm_atomic_debugfs_init(struct drm_minor *minor)
1639{
1640 return drm_debugfs_create_files(drm_atomic_debugfs_list,
1641 ARRAY_SIZE(drm_atomic_debugfs_list),
1642 minor->debugfs_root, minor);
1643}
1644#endif
1645
1463/* 1646/*
1464 * The big monstor ioctl 1647 * The big monstor ioctl
1465 */ 1648 */
@@ -1749,6 +1932,9 @@ retry:
1749 } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) { 1932 } else if (arg->flags & DRM_MODE_ATOMIC_NONBLOCK) {
1750 ret = drm_atomic_nonblocking_commit(state); 1933 ret = drm_atomic_nonblocking_commit(state);
1751 } else { 1934 } else {
1935 if (unlikely(drm_debug & DRM_UT_STATE))
1936 drm_atomic_print_state(state);
1937
1752 ret = drm_atomic_commit(state); 1938 ret = drm_atomic_commit(state);
1753 } 1939 }
1754 1940
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 13441e21117c..ce274edb9e52 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -229,9 +229,9 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
229 229
230 crtc->primary = primary; 230 crtc->primary = primary;
231 crtc->cursor = cursor; 231 crtc->cursor = cursor;
232 if (primary) 232 if (primary && !primary->possible_crtcs)
233 primary->possible_crtcs = 1 << drm_crtc_index(crtc); 233 primary->possible_crtcs = 1 << drm_crtc_index(crtc);
234 if (cursor) 234 if (cursor && !cursor->possible_crtcs)
235 cursor->possible_crtcs = 1 << drm_crtc_index(crtc); 235 cursor->possible_crtcs = 1 << drm_crtc_index(crtc);
236 236
237 ret = drm_crtc_crc_init(crtc); 237 ret = drm_crtc_crc_init(crtc);
diff --git a/drivers/gpu/drm/drm_debugfs.c b/drivers/gpu/drm/drm_debugfs.c
index 800055c39cdb..206a4fe7ea26 100644
--- a/drivers/gpu/drm/drm_debugfs.c
+++ b/drivers/gpu/drm/drm_debugfs.c
@@ -36,6 +36,7 @@
36#include <linux/export.h> 36#include <linux/export.h>
37#include <drm/drmP.h> 37#include <drm/drmP.h>
38#include <drm/drm_edid.h> 38#include <drm/drm_edid.h>
39#include <drm/drm_atomic.h>
39#include "drm_internal.h" 40#include "drm_internal.h"
40 41
41#if defined(CONFIG_DEBUG_FS) 42#if defined(CONFIG_DEBUG_FS)
@@ -163,6 +164,14 @@ int drm_debugfs_init(struct drm_minor *minor, int minor_id,
163 return ret; 164 return ret;
164 } 165 }
165 166
167 if (drm_core_check_feature(dev, DRIVER_ATOMIC)) {
168 ret = drm_atomic_debugfs_init(minor);
169 if (ret) {
170 DRM_ERROR("Failed to create atomic debugfs files\n");
171 return ret;
172 }
173 }
174
166 if (dev->driver->debugfs_init) { 175 if (dev->driver->debugfs_init) {
167 ret = dev->driver->debugfs_init(minor); 176 ret = dev->driver->debugfs_init(minor);
168 if (ret) { 177 if (ret) {
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 9506933b41cd..7eec18925b70 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -957,13 +957,13 @@ static const struct drm_display_mode edid_cea_modes[] = {
957 798, 858, 0, 480, 489, 495, 525, 0, 957 798, 858, 0, 480, 489, 495, 525, 0,
958 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC), 958 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC),
959 .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, }, 959 .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_16_9, },
960 /* 58 - 720(1440)x480i@240 */ 960 /* 58 - 720(1440)x480i@240Hz */
961 { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 54000, 720, 739, 961 { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 54000, 720, 739,
962 801, 858, 0, 480, 488, 494, 525, 0, 962 801, 858, 0, 480, 488, 494, 525, 0,
963 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 963 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
964 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK), 964 DRM_MODE_FLAG_INTERLACE | DRM_MODE_FLAG_DBLCLK),
965 .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, }, 965 .vrefresh = 240, .picture_aspect_ratio = HDMI_PICTURE_ASPECT_4_3, },
966 /* 59 - 720(1440)x480i@240 */ 966 /* 59 - 720(1440)x480i@240Hz */
967 { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 54000, 720, 739, 967 { DRM_MODE("720x480i", DRM_MODE_TYPE_DRIVER, 54000, 720, 739,
968 801, 858, 0, 480, 488, 494, 525, 0, 968 801, 858, 0, 480, 488, 494, 525, 0,
969 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC | 969 DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC |
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index cf993dbf602e..5d96de40b63f 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -51,10 +51,11 @@ DEFINE_MUTEX(drm_global_mutex);
51 * Drivers must define the file operations structure that forms the DRM 51 * Drivers must define the file operations structure that forms the DRM
52 * userspace API entry point, even though most of those operations are 52 * userspace API entry point, even though most of those operations are
53 * implemented in the DRM core. The mandatory functions are drm_open(), 53 * implemented in the DRM core. The mandatory functions are drm_open(),
54 * drm_read(), drm_ioctl() and drm_compat_ioctl if CONFIG_COMPAT is enabled. 54 * drm_read(), drm_ioctl() and drm_compat_ioctl() if CONFIG_COMPAT is enabled
55 * Drivers which implement private ioctls that require 32/64 bit compatibility 55 * (note that drm_compat_ioctl will be NULL if CONFIG_COMPAT=n). Drivers which
56 * support must provided their onw .compat_ioctl() handler that processes 56 * implement private ioctls that require 32/64 bit compatibility support must
57 * private ioctls and calls drm_compat_ioctl() for core ioctls. 57 * provide their own .compat_ioctl() handler that processes private ioctls and
58 * calls drm_compat_ioctl() for core ioctls.
58 * 59 *
59 * In addition drm_read() and drm_poll() provide support for DRM events. DRM 60 * In addition drm_read() and drm_poll() provide support for DRM events. DRM
60 * events are a generic and extensible means to send asynchronous events to 61 * events are a generic and extensible means to send asynchronous events to
@@ -75,9 +76,7 @@ DEFINE_MUTEX(drm_global_mutex);
75 * .open = drm_open, 76 * .open = drm_open,
76 * .release = drm_release, 77 * .release = drm_release,
77 * .unlocked_ioctl = drm_ioctl, 78 * .unlocked_ioctl = drm_ioctl,
78 * #ifdef CONFIG_COMPAT 79 * .compat_ioctl = drm_compat_ioctl, // NULL if CONFIG_COMPAT=n
79 * .compat_ioctl = drm_compat_ioctl,
80 * #endif
81 * .poll = drm_poll, 80 * .poll = drm_poll,
82 * .read = drm_read, 81 * .read = drm_read,
83 * .llseek = no_llseek, 82 * .llseek = no_llseek,
diff --git a/drivers/gpu/drm/drm_framebuffer.c b/drivers/gpu/drm/drm_framebuffer.c
index 49fd7db758e0..af786f27f72e 100644
--- a/drivers/gpu/drm/drm_framebuffer.c
+++ b/drivers/gpu/drm/drm_framebuffer.c
@@ -673,6 +673,11 @@ EXPORT_SYMBOL(drm_framebuffer_lookup);
673 * those used for fbdev. Note that the caller must hold a reference of it's own, 673 * those used for fbdev. Note that the caller must hold a reference of it's own,
674 * i.e. the object may not be destroyed through this call (since it'll lead to a 674 * i.e. the object may not be destroyed through this call (since it'll lead to a
675 * locking inversion). 675 * locking inversion).
676 *
677 * NOTE: This function is deprecated. For driver-private framebuffers it is not
678 * recommended to embed a framebuffer struct info fbdev struct, instead, a
679 * framebuffer pointer is preferred and drm_framebuffer_unreference() should be
680 * called when the framebuffer is to be cleaned up.
676 */ 681 */
677void drm_framebuffer_unregister_private(struct drm_framebuffer *fb) 682void drm_framebuffer_unregister_private(struct drm_framebuffer *fb)
678{ 683{
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 11d44a1e0ab3..632473beb40c 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -104,6 +104,68 @@ static struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_
104 u64 end, 104 u64 end,
105 enum drm_mm_search_flags flags); 105 enum drm_mm_search_flags flags);
106 106
107#ifdef CONFIG_DRM_DEBUG_MM
108#include <linux/stackdepot.h>
109
110#define STACKDEPTH 32
111#define BUFSZ 4096
112
113static noinline void save_stack(struct drm_mm_node *node)
114{
115 unsigned long entries[STACKDEPTH];
116 struct stack_trace trace = {
117 .entries = entries,
118 .max_entries = STACKDEPTH,
119 .skip = 1
120 };
121
122 save_stack_trace(&trace);
123 if (trace.nr_entries != 0 &&
124 trace.entries[trace.nr_entries-1] == ULONG_MAX)
125 trace.nr_entries--;
126
127 /* May be called under spinlock, so avoid sleeping */
128 node->stack = depot_save_stack(&trace, GFP_NOWAIT);
129}
130
131static void show_leaks(struct drm_mm *mm)
132{
133 struct drm_mm_node *node;
134 unsigned long entries[STACKDEPTH];
135 char *buf;
136
137 buf = kmalloc(BUFSZ, GFP_KERNEL);
138 if (!buf)
139 return;
140
141 list_for_each_entry(node, &mm->head_node.node_list, node_list) {
142 struct stack_trace trace = {
143 .entries = entries,
144 .max_entries = STACKDEPTH
145 };
146
147 if (!node->stack) {
148 DRM_ERROR("node [%08llx + %08llx]: unknown owner\n",
149 node->start, node->size);
150 continue;
151 }
152
153 depot_fetch_stack(node->stack, &trace);
154 snprint_stack_trace(buf, BUFSZ, &trace, 0);
155 DRM_ERROR("node [%08llx + %08llx]: inserted at\n%s",
156 node->start, node->size, buf);
157 }
158
159 kfree(buf);
160}
161
162#undef STACKDEPTH
163#undef BUFSZ
164#else
165static void save_stack(struct drm_mm_node *node) { }
166static void show_leaks(struct drm_mm *mm) { }
167#endif
168
107#define START(node) ((node)->start) 169#define START(node) ((node)->start)
108#define LAST(node) ((node)->start + (node)->size - 1) 170#define LAST(node) ((node)->start + (node)->size - 1)
109 171
@@ -228,6 +290,8 @@ static void drm_mm_insert_helper(struct drm_mm_node *hole_node,
228 list_add(&node->hole_stack, &mm->hole_stack); 290 list_add(&node->hole_stack, &mm->hole_stack);
229 node->hole_follows = 1; 291 node->hole_follows = 1;
230 } 292 }
293
294 save_stack(node);
231} 295}
232 296
233/** 297/**
@@ -293,6 +357,8 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node)
293 node->hole_follows = 1; 357 node->hole_follows = 1;
294 } 358 }
295 359
360 save_stack(node);
361
296 return 0; 362 return 0;
297} 363}
298EXPORT_SYMBOL(drm_mm_reserve_node); 364EXPORT_SYMBOL(drm_mm_reserve_node);
@@ -397,6 +463,8 @@ static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,
397 list_add(&node->hole_stack, &mm->hole_stack); 463 list_add(&node->hole_stack, &mm->hole_stack);
398 node->hole_follows = 1; 464 node->hole_follows = 1;
399 } 465 }
466
467 save_stack(node);
400} 468}
401 469
402/** 470/**
@@ -861,10 +929,12 @@ EXPORT_SYMBOL(drm_mm_init);
861 * Note that it is a bug to call this function on an allocator which is not 929 * Note that it is a bug to call this function on an allocator which is not
862 * clean. 930 * clean.
863 */ 931 */
864void drm_mm_takedown(struct drm_mm * mm) 932void drm_mm_takedown(struct drm_mm *mm)
865{ 933{
866 WARN(!list_empty(&mm->head_node.node_list), 934 if (WARN(!list_empty(&mm->head_node.node_list),
867 "Memory manager not clean during takedown.\n"); 935 "Memory manager not clean during takedown.\n"))
936 show_leaks(mm);
937
868} 938}
869EXPORT_SYMBOL(drm_mm_takedown); 939EXPORT_SYMBOL(drm_mm_takedown);
870 940
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index f64ac86deb84..ce6eeda02acf 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -49,13 +49,7 @@
49 */ 49 */
50void drm_mode_debug_printmodeline(const struct drm_display_mode *mode) 50void drm_mode_debug_printmodeline(const struct drm_display_mode *mode)
51{ 51{
52 DRM_DEBUG_KMS("Modeline %d:\"%s\" %d %d %d %d %d %d %d %d %d %d " 52 DRM_DEBUG_KMS("Modeline " DRM_MODE_FMT "\n", DRM_MODE_ARG(mode));
53 "0x%x 0x%x\n",
54 mode->base.id, mode->name, mode->vrefresh, mode->clock,
55 mode->hdisplay, mode->hsync_start,
56 mode->hsync_end, mode->htotal,
57 mode->vdisplay, mode->vsync_start,
58 mode->vsync_end, mode->vtotal, mode->type, mode->flags);
59} 53}
60EXPORT_SYMBOL(drm_mode_debug_printmodeline); 54EXPORT_SYMBOL(drm_mode_debug_printmodeline);
61 55
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
index 7899fc1dcdb0..7a7dddf604d7 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -130,15 +130,8 @@ int drm_plane_helper_check_state(struct drm_plane_state *state,
130 unsigned int rotation = state->rotation; 130 unsigned int rotation = state->rotation;
131 int hscale, vscale; 131 int hscale, vscale;
132 132
133 src->x1 = state->src_x; 133 *src = drm_plane_state_src(state);
134 src->y1 = state->src_y; 134 *dst = drm_plane_state_dest(state);
135 src->x2 = state->src_x + state->src_w;
136 src->y2 = state->src_y + state->src_h;
137
138 dst->x1 = state->crtc_x;
139 dst->y1 = state->crtc_y;
140 dst->x2 = state->crtc_x + state->crtc_w;
141 dst->y2 = state->crtc_y + state->crtc_h;
142 135
143 if (!fb) { 136 if (!fb) {
144 state->visible = false; 137 state->visible = false;
diff --git a/drivers/gpu/drm/drm_print.c b/drivers/gpu/drm/drm_print.c
new file mode 100644
index 000000000000..34eb85618b76
--- /dev/null
+++ b/drivers/gpu/drm/drm_print.c
@@ -0,0 +1,54 @@
1/*
2 * Copyright (C) 2016 Red Hat
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 * Authors:
23 * Rob Clark <robdclark@gmail.com>
24 */
25
26#include <stdarg.h>
27#include <linux/seq_file.h>
28#include <drm/drmP.h>
29#include <drm/drm_print.h>
30
31void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf)
32{
33 seq_printf(p->arg, "%pV", vaf);
34}
35EXPORT_SYMBOL(__drm_printfn_seq_file);
36
37void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf)
38{
39 dev_printk(KERN_INFO, p->arg, "[" DRM_NAME "] %pV", vaf);
40}
41EXPORT_SYMBOL(__drm_printfn_info);
42
43void drm_printf(struct drm_printer *p, const char *f, ...)
44{
45 struct va_format vaf;
46 va_list args;
47
48 va_start(args, f);
49 vaf.fmt = f;
50 vaf.va = &args;
51 p->printfn(p, &vaf);
52 va_end(args);
53}
54EXPORT_SYMBOL(drm_printf);
diff --git a/drivers/gpu/drm/drm_rect.c b/drivers/gpu/drm/drm_rect.c
index 73e53a8d1b37..e6057d8cdcd5 100644
--- a/drivers/gpu/drm/drm_rect.c
+++ b/drivers/gpu/drm/drm_rect.c
@@ -281,17 +281,10 @@ EXPORT_SYMBOL(drm_rect_calc_vscale_relaxed);
281 */ 281 */
282void drm_rect_debug_print(const char *prefix, const struct drm_rect *r, bool fixed_point) 282void drm_rect_debug_print(const char *prefix, const struct drm_rect *r, bool fixed_point)
283{ 283{
284 int w = drm_rect_width(r);
285 int h = drm_rect_height(r);
286
287 if (fixed_point) 284 if (fixed_point)
288 DRM_DEBUG_KMS("%s%d.%06ux%d.%06u%+d.%06u%+d.%06u\n", prefix, 285 DRM_DEBUG_KMS("%s" DRM_RECT_FP_FMT "\n", prefix, DRM_RECT_FP_ARG(r));
289 w >> 16, ((w & 0xffff) * 15625) >> 10,
290 h >> 16, ((h & 0xffff) * 15625) >> 10,
291 r->x1 >> 16, ((r->x1 & 0xffff) * 15625) >> 10,
292 r->y1 >> 16, ((r->y1 & 0xffff) * 15625) >> 10);
293 else 286 else
294 DRM_DEBUG_KMS("%s%dx%d%+d%+d\n", prefix, w, h, r->x1, r->y1); 287 DRM_DEBUG_KMS("%s" DRM_RECT_FMT "\n", prefix, DRM_RECT_ARG(r));
295} 288}
296EXPORT_SYMBOL(drm_rect_debug_print); 289EXPORT_SYMBOL(drm_rect_debug_print);
297 290
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
index 0dee6acbd880..a6799b0aa3d9 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c
+++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c
@@ -479,9 +479,7 @@ static const struct file_operations fops = {
479 .open = drm_open, 479 .open = drm_open,
480 .release = drm_release, 480 .release = drm_release,
481 .unlocked_ioctl = drm_ioctl, 481 .unlocked_ioctl = drm_ioctl,
482#ifdef CONFIG_COMPAT
483 .compat_ioctl = drm_compat_ioctl, 482 .compat_ioctl = drm_compat_ioctl,
484#endif
485 .poll = drm_poll, 483 .poll = drm_poll,
486 .read = drm_read, 484 .read = drm_read,
487 .llseek = no_llseek, 485 .llseek = no_llseek,
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 463d6fd56756..739180ac3da5 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -366,9 +366,7 @@ static const struct file_operations exynos_drm_driver_fops = {
366 .poll = drm_poll, 366 .poll = drm_poll,
367 .read = drm_read, 367 .read = drm_read,
368 .unlocked_ioctl = drm_ioctl, 368 .unlocked_ioctl = drm_ioctl,
369#ifdef CONFIG_COMPAT
370 .compat_ioctl = drm_compat_ioctl, 369 .compat_ioctl = drm_compat_ioctl,
371#endif
372 .release = drm_release, 370 .release = drm_release,
373}; 371};
374 372
diff --git a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
index e04efbed1a54..0b0d1cb11641 100644
--- a/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
+++ b/drivers/gpu/drm/fsl-dcu/fsl_dcu_drm_drv.c
@@ -180,9 +180,7 @@ static const struct file_operations fsl_dcu_drm_fops = {
180 .open = drm_open, 180 .open = drm_open,
181 .release = drm_release, 181 .release = drm_release,
182 .unlocked_ioctl = drm_ioctl, 182 .unlocked_ioctl = drm_ioctl,
183#ifdef CONFIG_COMPAT
184 .compat_ioctl = drm_compat_ioctl, 183 .compat_ioctl = drm_compat_ioctl,
185#endif
186 .poll = drm_poll, 184 .poll = drm_poll,
187 .read = drm_read, 185 .read = drm_read,
188 .llseek = no_llseek, 186 .llseek = no_llseek,
diff --git a/drivers/gpu/drm/gma500/gtt.c b/drivers/gpu/drm/gma500/gtt.c
index 76aea2e7fb9d..3f4f424196b2 100644
--- a/drivers/gpu/drm/gma500/gtt.c
+++ b/drivers/gpu/drm/gma500/gtt.c
@@ -131,7 +131,7 @@ static int psb_gtt_insert(struct drm_device *dev, struct gtt_range *r,
131 * page table entries with the dummy page. This is protected via the gtt 131 * page table entries with the dummy page. This is protected via the gtt
132 * mutex which the caller must hold. 132 * mutex which the caller must hold.
133 */ 133 */
134void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r) 134static void psb_gtt_remove(struct drm_device *dev, struct gtt_range *r)
135{ 135{
136 struct drm_psb_private *dev_priv = dev->dev_private; 136 struct drm_psb_private *dev_priv = dev->dev_private;
137 u32 __iomem *gtt_slot; 137 u32 __iomem *gtt_slot;
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c
index 50eb944fb78a..ff37ea585664 100644
--- a/drivers/gpu/drm/gma500/psb_drv.c
+++ b/drivers/gpu/drm/gma500/psb_drv.c
@@ -473,6 +473,7 @@ static const struct file_operations psb_gem_fops = {
473 .open = drm_open, 473 .open = drm_open,
474 .release = drm_release, 474 .release = drm_release,
475 .unlocked_ioctl = psb_unlocked_ioctl, 475 .unlocked_ioctl = psb_unlocked_ioctl,
476 .compat_ioctl = drm_compat_ioctl,
476 .mmap = drm_gem_mmap, 477 .mmap = drm_gem_mmap,
477 .poll = drm_poll, 478 .poll = drm_poll,
478 .read = drm_read, 479 .read = drm_read,
diff --git a/drivers/gpu/drm/gma500/psb_drv.h b/drivers/gpu/drm/gma500/psb_drv.h
index b74372760d7f..05d7aaf47eea 100644
--- a/drivers/gpu/drm/gma500/psb_drv.h
+++ b/drivers/gpu/drm/gma500/psb_drv.h
@@ -753,10 +753,6 @@ extern int psb_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
753extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev, 753extern int psb_gem_dumb_map_gtt(struct drm_file *file, struct drm_device *dev,
754 uint32_t handle, uint64_t *offset); 754 uint32_t handle, uint64_t *offset);
755extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf); 755extern int psb_gem_fault(struct vm_area_struct *vma, struct vm_fault *vmf);
756extern int psb_gem_create_ioctl(struct drm_device *dev, void *data,
757 struct drm_file *file);
758extern int psb_gem_mmap_ioctl(struct drm_device *dev, void *data,
759 struct drm_file *file);
760 756
761/* psb_device.c */ 757/* psb_device.c */
762extern const struct psb_ops psb_chip_ops; 758extern const struct psb_ops psb_chip_ops;
diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
index e88fde18c946..ebd5f4fe4c23 100644
--- a/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
+++ b/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
@@ -152,9 +152,7 @@ static const struct file_operations kirin_drm_fops = {
152 .open = drm_open, 152 .open = drm_open,
153 .release = drm_release, 153 .release = drm_release,
154 .unlocked_ioctl = drm_ioctl, 154 .unlocked_ioctl = drm_ioctl,
155#ifdef CONFIG_COMPAT
156 .compat_ioctl = drm_compat_ioctl, 155 .compat_ioctl = drm_compat_ioctl,
157#endif
158 .poll = drm_poll, 156 .poll = drm_poll,
159 .read = drm_read, 157 .read = drm_read,
160 .llseek = no_llseek, 158 .llseek = no_llseek,
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c
index d91856779beb..ab4e6cbe1f8b 100644
--- a/drivers/gpu/drm/i810/i810_dma.c
+++ b/drivers/gpu/drm/i810/i810_dma.c
@@ -113,9 +113,7 @@ static const struct file_operations i810_buffer_fops = {
113 .release = drm_release, 113 .release = drm_release,
114 .unlocked_ioctl = drm_ioctl, 114 .unlocked_ioctl = drm_ioctl,
115 .mmap = i810_mmap_buffers, 115 .mmap = i810_mmap_buffers,
116#ifdef CONFIG_COMPAT
117 .compat_ioctl = drm_compat_ioctl, 116 .compat_ioctl = drm_compat_ioctl,
118#endif
119 .llseek = noop_llseek, 117 .llseek = noop_llseek,
120}; 118};
121 119
diff --git a/drivers/gpu/drm/i810/i810_drv.c b/drivers/gpu/drm/i810/i810_drv.c
index 0be55dc1ef4b..02504a7cfaf2 100644
--- a/drivers/gpu/drm/i810/i810_drv.c
+++ b/drivers/gpu/drm/i810/i810_drv.c
@@ -49,9 +49,7 @@ static const struct file_operations i810_driver_fops = {
49 .unlocked_ioctl = drm_ioctl, 49 .unlocked_ioctl = drm_ioctl,
50 .mmap = drm_legacy_mmap, 50 .mmap = drm_legacy_mmap,
51 .poll = drm_poll, 51 .poll = drm_poll,
52#ifdef CONFIG_COMPAT
53 .compat_ioctl = drm_compat_ioctl, 52 .compat_ioctl = drm_compat_ioctl,
54#endif
55 .llseek = noop_llseek, 53 .llseek = noop_llseek,
56}; 54};
57 55
diff --git a/drivers/gpu/drm/i915/Kconfig.debug b/drivers/gpu/drm/i915/Kconfig.debug
index cee87bfd10c4..51ba630a134b 100644
--- a/drivers/gpu/drm/i915/Kconfig.debug
+++ b/drivers/gpu/drm/i915/Kconfig.debug
@@ -21,6 +21,7 @@ config DRM_I915_DEBUG
21 select PREEMPT_COUNT 21 select PREEMPT_COUNT
22 select X86_MSR # used by igt/pm_rpm 22 select X86_MSR # used by igt/pm_rpm
23 select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks) 23 select DRM_VGEM # used by igt/prime_vgem (dmabuf interop checks)
24 select DRM_DEBUG_MM if DRM=y
24 default n 25 default n
25 help 26 help
26 Choose this option to turn on extra driver debugging that may affect 27 Choose this option to turn on extra driver debugging that may affect
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c
index b72c24ff39c3..0213a3090ab3 100644
--- a/drivers/gpu/drm/i915/i915_drv.c
+++ b/drivers/gpu/drm/i915/i915_drv.c
@@ -2497,9 +2497,7 @@ static const struct file_operations i915_driver_fops = {
2497 .mmap = drm_gem_mmap, 2497 .mmap = drm_gem_mmap,
2498 .poll = drm_poll, 2498 .poll = drm_poll,
2499 .read = drm_read, 2499 .read = drm_read,
2500#ifdef CONFIG_COMPAT
2501 .compat_ioctl = i915_compat_ioctl, 2500 .compat_ioctl = i915_compat_ioctl,
2502#endif
2503 .llseek = noop_llseek, 2501 .llseek = noop_llseek,
2504}; 2502};
2505 2503
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 80775b882b4a..6f4a6bcf6ed4 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -3001,6 +3001,8 @@ __i915_printk(struct drm_i915_private *dev_priv, const char *level,
3001#ifdef CONFIG_COMPAT 3001#ifdef CONFIG_COMPAT
3002extern long i915_compat_ioctl(struct file *filp, unsigned int cmd, 3002extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
3003 unsigned long arg); 3003 unsigned long arg);
3004#else
3005#define i915_compat_ioctl NULL
3004#endif 3006#endif
3005extern const struct dev_pm_ops i915_pm_ops; 3007extern const struct dev_pm_ops i915_pm_ops;
3006 3008
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c
index 92ab01f33208..f4e321853fa4 100644
--- a/drivers/gpu/drm/i915/intel_display.c
+++ b/drivers/gpu/drm/i915/intel_display.c
@@ -2821,14 +2821,8 @@ valid_fb:
2821 plane_state->crtc_w = fb->width; 2821 plane_state->crtc_w = fb->width;
2822 plane_state->crtc_h = fb->height; 2822 plane_state->crtc_h = fb->height;
2823 2823
2824 intel_state->base.src.x1 = plane_state->src_x; 2824 intel_state->base.src = drm_plane_state_src(plane_state);
2825 intel_state->base.src.y1 = plane_state->src_y; 2825 intel_state->base.dst = drm_plane_state_dest(plane_state);
2826 intel_state->base.src.x2 = plane_state->src_x + plane_state->src_w;
2827 intel_state->base.src.y2 = plane_state->src_y + plane_state->src_h;
2828 intel_state->base.dst.x1 = plane_state->crtc_x;
2829 intel_state->base.dst.y1 = plane_state->crtc_y;
2830 intel_state->base.dst.x2 = plane_state->crtc_x + plane_state->crtc_w;
2831 intel_state->base.dst.y2 = plane_state->crtc_y + plane_state->crtc_h;
2832 2826
2833 obj = intel_fb_obj(fb); 2827 obj = intel_fb_obj(fb);
2834 if (i915_gem_object_is_tiled(obj)) 2828 if (i915_gem_object_is_tiled(obj))
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c
index df0fbb4b15a3..0e9aac2e3eae 100644
--- a/drivers/gpu/drm/i915/intel_sprite.c
+++ b/drivers/gpu/drm/i915/intel_sprite.c
@@ -773,15 +773,8 @@ intel_check_sprite_plane(struct drm_plane *plane,
773 bool can_scale; 773 bool can_scale;
774 int ret; 774 int ret;
775 775
776 src->x1 = state->base.src_x; 776 *src = drm_plane_state_src(&state->base);
777 src->y1 = state->base.src_y; 777 *dst = drm_plane_state_dest(&state->base);
778 src->x2 = state->base.src_x + state->base.src_w;
779 src->y2 = state->base.src_y + state->base.src_h;
780
781 dst->x1 = state->base.crtc_x;
782 dst->y1 = state->base.crtc_y;
783 dst->x2 = state->base.crtc_x + state->base.crtc_w;
784 dst->y2 = state->base.crtc_y + state->base.crtc_h;
785 778
786 if (!fb) { 779 if (!fb) {
787 state->base.visible = false; 780 state->base.visible = false;
diff --git a/drivers/gpu/drm/imx/imx-drm-core.c b/drivers/gpu/drm/imx/imx-drm-core.c
index 9672b579f950..a16e8b7df120 100644
--- a/drivers/gpu/drm/imx/imx-drm-core.c
+++ b/drivers/gpu/drm/imx/imx-drm-core.c
@@ -158,6 +158,7 @@ static int imx_drm_atomic_commit(struct drm_device *dev,
158 struct drm_plane_state *plane_state; 158 struct drm_plane_state *plane_state;
159 struct drm_plane *plane; 159 struct drm_plane *plane;
160 struct dma_buf *dma_buf; 160 struct dma_buf *dma_buf;
161 struct dma_fence *fence;
161 int i; 162 int i;
162 163
163 /* 164 /*
@@ -170,8 +171,9 @@ static int imx_drm_atomic_commit(struct drm_device *dev,
170 0)->base.dma_buf; 171 0)->base.dma_buf;
171 if (!dma_buf) 172 if (!dma_buf)
172 continue; 173 continue;
173 plane_state->fence = 174 fence = reservation_object_get_excl_rcu(dma_buf->resv);
174 reservation_object_get_excl_rcu(dma_buf->resv); 175
176 drm_atomic_set_fence_for_plane(plane_state, fence);
175 } 177 }
176 } 178 }
177 179
diff --git a/drivers/gpu/drm/mediatek/mtk_drm_drv.c b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
index 296f541fbe2f..d90152e85ed0 100644
--- a/drivers/gpu/drm/mediatek/mtk_drm_drv.c
+++ b/drivers/gpu/drm/mediatek/mtk_drm_drv.c
@@ -249,9 +249,7 @@ static const struct file_operations mtk_drm_fops = {
249 .mmap = mtk_drm_gem_mmap, 249 .mmap = mtk_drm_gem_mmap,
250 .poll = drm_poll, 250 .poll = drm_poll,
251 .read = drm_read, 251 .read = drm_read,
252#ifdef CONFIG_COMPAT
253 .compat_ioctl = drm_compat_ioctl, 252 .compat_ioctl = drm_compat_ioctl,
254#endif
255}; 253};
256 254
257static struct drm_driver mtk_drm_driver = { 255static struct drm_driver mtk_drm_driver = {
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c b/drivers/gpu/drm/mgag200/mgag200_drv.c
index 1443b3a34775..b0b874264f9d 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -82,9 +82,7 @@ static const struct file_operations mgag200_driver_fops = {
82 .unlocked_ioctl = drm_ioctl, 82 .unlocked_ioctl = drm_ioctl,
83 .mmap = mgag200_mmap, 83 .mmap = mgag200_mmap,
84 .poll = drm_poll, 84 .poll = drm_poll,
85#ifdef CONFIG_COMPAT
86 .compat_ioctl = drm_compat_ioctl, 85 .compat_ioctl = drm_compat_ioctl,
87#endif
88 .read = drm_read, 86 .read = drm_read,
89}; 87};
90 88
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c
index a521207db8a1..b764d7f10312 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_irq.c
@@ -15,6 +15,7 @@
15 * this program. If not, see <http://www.gnu.org/licenses/>. 15 * this program. If not, see <http://www.gnu.org/licenses/>.
16 */ 16 */
17 17
18#include <drm/drm_print.h>
18 19
19#include "msm_drv.h" 20#include "msm_drv.h"
20#include "mdp4_kms.h" 21#include "mdp4_kms.h"
@@ -29,7 +30,16 @@ void mdp4_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask,
29 30
30static void mdp4_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus) 31static void mdp4_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus)
31{ 32{
33 struct mdp4_kms *mdp4_kms = container_of(irq, struct mdp4_kms, error_handler);
34 static DEFINE_RATELIMIT_STATE(rs, 5*HZ, 1);
35 extern bool dumpstate;
36
32 DRM_ERROR_RATELIMITED("errors: %08x\n", irqstatus); 37 DRM_ERROR_RATELIMITED("errors: %08x\n", irqstatus);
38
39 if (dumpstate && __ratelimit(&rs)) {
40 struct drm_printer p = drm_info_printer(mdp4_kms->dev->dev);
41 drm_state_dump(mdp4_kms->dev, &p);
42 }
33} 43}
34 44
35void mdp4_irq_preinstall(struct msm_kms *kms) 45void mdp4_irq_preinstall(struct msm_kms *kms)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
index d53e5510fd7c..5c5940db898e 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c
@@ -17,6 +17,8 @@
17 17
18#include <linux/irq.h> 18#include <linux/irq.h>
19 19
20#include <drm/drm_print.h>
21
20#include "msm_drv.h" 22#include "msm_drv.h"
21#include "mdp5_kms.h" 23#include "mdp5_kms.h"
22 24
@@ -30,7 +32,16 @@ void mdp5_set_irqmask(struct mdp_kms *mdp_kms, uint32_t irqmask,
30 32
31static void mdp5_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus) 33static void mdp5_irq_error_handler(struct mdp_irq *irq, uint32_t irqstatus)
32{ 34{
35 struct mdp5_kms *mdp5_kms = container_of(irq, struct mdp5_kms, error_handler);
36 static DEFINE_RATELIMIT_STATE(rs, 5*HZ, 1);
37 extern bool dumpstate;
38
33 DRM_ERROR_RATELIMITED("errors: %08x\n", irqstatus); 39 DRM_ERROR_RATELIMITED("errors: %08x\n", irqstatus);
40
41 if (dumpstate && __ratelimit(&rs)) {
42 struct drm_printer p = drm_info_printer(mdp5_kms->dev->dev);
43 drm_state_dump(mdp5_kms->dev, &p);
44 }
34} 45}
35 46
36void mdp5_irq_preinstall(struct msm_kms *kms) 47void mdp5_irq_preinstall(struct msm_kms *kms)
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
index 03738927be10..c6fbcfad2d59 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h
@@ -114,6 +114,18 @@ static inline u32 mdp5_read(struct mdp5_kms *mdp5_kms, u32 reg)
114 return msm_readl(mdp5_kms->mmio + reg); 114 return msm_readl(mdp5_kms->mmio + reg);
115} 115}
116 116
117static inline const char *stage2name(enum mdp_mixer_stage_id stage)
118{
119 static const char *names[] = {
120#define NAME(n) [n] = #n
121 NAME(STAGE_UNUSED), NAME(STAGE_BASE),
122 NAME(STAGE0), NAME(STAGE1), NAME(STAGE2),
123 NAME(STAGE3), NAME(STAGE4), NAME(STAGE6),
124#undef NAME
125 };
126 return names[stage];
127}
128
117static inline const char *pipe2name(enum mdp5_pipe pipe) 129static inline const char *pipe2name(enum mdp5_pipe pipe)
118{ 130{
119 static const char *names[] = { 131 static const char *names[] = {
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
index cf50d3ec8d1b..8bf55e3450c5 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c
@@ -16,6 +16,7 @@
16 * this program. If not, see <http://www.gnu.org/licenses/>. 16 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 17 */
18 18
19#include <drm/drm_print.h>
19#include "mdp5_kms.h" 20#include "mdp5_kms.h"
20 21
21struct mdp5_plane { 22struct mdp5_plane {
@@ -181,6 +182,20 @@ done:
181#undef SET_PROPERTY 182#undef SET_PROPERTY
182} 183}
183 184
185static void
186mdp5_plane_atomic_print_state(struct drm_printer *p,
187 const struct drm_plane_state *state)
188{
189 struct mdp5_plane_state *pstate = to_mdp5_plane_state(state);
190
191 drm_printf(p, "\tpremultiplied=%u\n", pstate->premultiplied);
192 drm_printf(p, "\tzpos=%u\n", pstate->zpos);
193 drm_printf(p, "\talpha=%u\n", pstate->alpha);
194 drm_printf(p, "\tstage=%s\n", stage2name(pstate->stage));
195 drm_printf(p, "\tmode_changed=%u\n", pstate->mode_changed);
196 drm_printf(p, "\tpending=%u\n", pstate->pending);
197}
198
184static void mdp5_plane_reset(struct drm_plane *plane) 199static void mdp5_plane_reset(struct drm_plane *plane)
185{ 200{
186 struct mdp5_plane_state *mdp5_state; 201 struct mdp5_plane_state *mdp5_state;
@@ -244,6 +259,7 @@ static const struct drm_plane_funcs mdp5_plane_funcs = {
244 .reset = mdp5_plane_reset, 259 .reset = mdp5_plane_reset,
245 .atomic_duplicate_state = mdp5_plane_duplicate_state, 260 .atomic_duplicate_state = mdp5_plane_duplicate_state,
246 .atomic_destroy_state = mdp5_plane_destroy_state, 261 .atomic_destroy_state = mdp5_plane_destroy_state,
262 .atomic_print_state = mdp5_plane_atomic_print_state,
247}; 263};
248 264
249static int mdp5_plane_prepare_fb(struct drm_plane *plane, 265static int mdp5_plane_prepare_fb(struct drm_plane *plane,
@@ -913,7 +929,7 @@ struct drm_plane *mdp5_plane_init(struct drm_device *dev,
913 type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY; 929 type = private_plane ? DRM_PLANE_TYPE_PRIMARY : DRM_PLANE_TYPE_OVERLAY;
914 ret = drm_universal_plane_init(dev, plane, 0xff, &mdp5_plane_funcs, 930 ret = drm_universal_plane_init(dev, plane, 0xff, &mdp5_plane_funcs,
915 mdp5_plane->formats, mdp5_plane->nformats, 931 mdp5_plane->formats, mdp5_plane->nformats,
916 type, NULL); 932 type, "%s", mdp5_plane->name);
917 if (ret) 933 if (ret)
918 goto fail; 934 goto fail;
919 935
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index db193f835298..4e21e1d72378 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -217,8 +217,9 @@ int msm_atomic_commit(struct drm_device *dev,
217 if ((plane->state->fb != plane_state->fb) && plane_state->fb) { 217 if ((plane->state->fb != plane_state->fb) && plane_state->fb) {
218 struct drm_gem_object *obj = msm_framebuffer_bo(plane_state->fb, 0); 218 struct drm_gem_object *obj = msm_framebuffer_bo(plane_state->fb, 0);
219 struct msm_gem_object *msm_obj = to_msm_bo(obj); 219 struct msm_gem_object *msm_obj = to_msm_bo(obj);
220 struct dma_fence *fence = reservation_object_get_excl_rcu(msm_obj->resv);
220 221
221 plane_state->fence = reservation_object_get_excl_rcu(msm_obj->resv); 222 drm_atomic_set_fence_for_plane(plane_state, fence);
222 } 223 }
223 } 224 }
224 225
diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c
index 84d38eaea585..8d21fb27a401 100644
--- a/drivers/gpu/drm/msm/msm_drv.c
+++ b/drivers/gpu/drm/msm/msm_drv.c
@@ -79,6 +79,10 @@ static char *vram = "16m";
79MODULE_PARM_DESC(vram, "Configure VRAM size (for devices without IOMMU/GPUMMU)"); 79MODULE_PARM_DESC(vram, "Configure VRAM size (for devices without IOMMU/GPUMMU)");
80module_param(vram, charp, 0); 80module_param(vram, charp, 0);
81 81
82bool dumpstate = false;
83MODULE_PARM_DESC(dumpstate, "Dump KMS state on errors");
84module_param(dumpstate, bool, 0600);
85
82/* 86/*
83 * Util/helpers: 87 * Util/helpers:
84 */ 88 */
@@ -768,9 +772,7 @@ static const struct file_operations fops = {
768 .open = drm_open, 772 .open = drm_open,
769 .release = drm_release, 773 .release = drm_release,
770 .unlocked_ioctl = drm_ioctl, 774 .unlocked_ioctl = drm_ioctl,
771#ifdef CONFIG_COMPAT
772 .compat_ioctl = drm_compat_ioctl, 775 .compat_ioctl = drm_compat_ioctl,
773#endif
774 .poll = drm_poll, 776 .poll = drm_poll,
775 .read = drm_read, 777 .read = drm_read,
776 .llseek = no_llseek, 778 .llseek = no_llseek,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_drv.c b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
index 73c971e39b1c..68fd167d7313 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_drv.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_drv.c
@@ -201,9 +201,7 @@ static const struct file_operations rcar_du_fops = {
201 .open = drm_open, 201 .open = drm_open,
202 .release = drm_release, 202 .release = drm_release,
203 .unlocked_ioctl = drm_ioctl, 203 .unlocked_ioctl = drm_ioctl,
204#ifdef CONFIG_COMPAT
205 .compat_ioctl = drm_compat_ioctl, 204 .compat_ioctl = drm_compat_ioctl,
206#endif
207 .poll = drm_poll, 205 .poll = drm_poll,
208 .read = drm_read, 206 .read = drm_read,
209 .llseek = no_llseek, 207 .llseek = no_llseek,
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
index 6fe161192bb4..2390c8577617 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_drv.c
@@ -275,9 +275,7 @@ static const struct file_operations rockchip_drm_driver_fops = {
275 .poll = drm_poll, 275 .poll = drm_poll,
276 .read = drm_read, 276 .read = drm_read,
277 .unlocked_ioctl = drm_ioctl, 277 .unlocked_ioctl = drm_ioctl,
278#ifdef CONFIG_COMPAT
279 .compat_ioctl = drm_compat_ioctl, 278 .compat_ioctl = drm_compat_ioctl,
280#endif
281 .release = drm_release, 279 .release = drm_release,
282}; 280};
283 281
diff --git a/drivers/gpu/drm/savage/savage_drv.c b/drivers/gpu/drm/savage/savage_drv.c
index 3b807135a5cd..78c6d8e9b42c 100644
--- a/drivers/gpu/drm/savage/savage_drv.c
+++ b/drivers/gpu/drm/savage/savage_drv.c
@@ -42,9 +42,7 @@ static const struct file_operations savage_driver_fops = {
42 .unlocked_ioctl = drm_ioctl, 42 .unlocked_ioctl = drm_ioctl,
43 .mmap = drm_legacy_mmap, 43 .mmap = drm_legacy_mmap,
44 .poll = drm_poll, 44 .poll = drm_poll,
45#ifdef CONFIG_COMPAT
46 .compat_ioctl = drm_compat_ioctl, 45 .compat_ioctl = drm_compat_ioctl,
47#endif
48 .llseek = noop_llseek, 46 .llseek = noop_llseek,
49}; 47};
50 48
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_drv.c b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
index f0492603ea88..38dd55f4af81 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_drv.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_drv.c
@@ -245,9 +245,7 @@ static const struct file_operations shmob_drm_fops = {
245 .open = drm_open, 245 .open = drm_open,
246 .release = drm_release, 246 .release = drm_release,
247 .unlocked_ioctl = drm_ioctl, 247 .unlocked_ioctl = drm_ioctl,
248#ifdef CONFIG_COMPAT
249 .compat_ioctl = drm_compat_ioctl, 248 .compat_ioctl = drm_compat_ioctl,
250#endif
251 .poll = drm_poll, 249 .poll = drm_poll,
252 .read = drm_read, 250 .read = drm_read,
253 .llseek = no_llseek, 251 .llseek = no_llseek,
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c
index ae9839886c4d..a836451920f0 100644
--- a/drivers/gpu/drm/sis/sis_drv.c
+++ b/drivers/gpu/drm/sis/sis_drv.c
@@ -72,9 +72,7 @@ static const struct file_operations sis_driver_fops = {
72 .unlocked_ioctl = drm_ioctl, 72 .unlocked_ioctl = drm_ioctl,
73 .mmap = drm_legacy_mmap, 73 .mmap = drm_legacy_mmap,
74 .poll = drm_poll, 74 .poll = drm_poll,
75#ifdef CONFIG_COMPAT
76 .compat_ioctl = drm_compat_ioctl, 75 .compat_ioctl = drm_compat_ioctl,
77#endif
78 .llseek = noop_llseek, 76 .llseek = noop_llseek,
79}; 77};
80 78
diff --git a/drivers/gpu/drm/sti/sti_drv.c b/drivers/gpu/drm/sti/sti_drv.c
index d614701bdcc7..ff71e25ab5bf 100644
--- a/drivers/gpu/drm/sti/sti_drv.c
+++ b/drivers/gpu/drm/sti/sti_drv.c
@@ -297,9 +297,7 @@ static const struct file_operations sti_driver_fops = {
297 .poll = drm_poll, 297 .poll = drm_poll,
298 .read = drm_read, 298 .read = drm_read,
299 .unlocked_ioctl = drm_ioctl, 299 .unlocked_ioctl = drm_ioctl,
300#ifdef CONFIG_COMPAT
301 .compat_ioctl = drm_compat_ioctl, 300 .compat_ioctl = drm_compat_ioctl,
302#endif
303 .release = drm_release, 301 .release = drm_release,
304}; 302};
305 303
diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c
index b3c4ad605e81..aae723cd6d79 100644
--- a/drivers/gpu/drm/sun4i/sun4i_drv.c
+++ b/drivers/gpu/drm/sun4i/sun4i_drv.c
@@ -53,9 +53,7 @@ static const struct file_operations sun4i_drv_fops = {
53 .open = drm_open, 53 .open = drm_open,
54 .release = drm_release, 54 .release = drm_release,
55 .unlocked_ioctl = drm_ioctl, 55 .unlocked_ioctl = drm_ioctl,
56#ifdef CONFIG_COMPAT
57 .compat_ioctl = drm_compat_ioctl, 56 .compat_ioctl = drm_compat_ioctl,
58#endif
59 .poll = drm_poll, 57 .poll = drm_poll,
60 .read = drm_read, 58 .read = drm_read,
61 .llseek = no_llseek, 59 .llseek = no_llseek,
diff --git a/drivers/gpu/drm/tdfx/tdfx_drv.c b/drivers/gpu/drm/tdfx/tdfx_drv.c
index f418892b0c71..c54138c3a376 100644
--- a/drivers/gpu/drm/tdfx/tdfx_drv.c
+++ b/drivers/gpu/drm/tdfx/tdfx_drv.c
@@ -49,9 +49,7 @@ static const struct file_operations tdfx_driver_fops = {
49 .unlocked_ioctl = drm_ioctl, 49 .unlocked_ioctl = drm_ioctl,
50 .mmap = drm_legacy_mmap, 50 .mmap = drm_legacy_mmap,
51 .poll = drm_poll, 51 .poll = drm_poll,
52#ifdef CONFIG_COMPAT
53 .compat_ioctl = drm_compat_ioctl, 52 .compat_ioctl = drm_compat_ioctl,
54#endif
55 .llseek = noop_llseek, 53 .llseek = noop_llseek,
56}; 54};
57 55
diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c
index a9630c2d6cb3..b8be3ee4d3b8 100644
--- a/drivers/gpu/drm/tegra/drm.c
+++ b/drivers/gpu/drm/tegra/drm.c
@@ -802,9 +802,7 @@ static const struct file_operations tegra_drm_fops = {
802 .mmap = tegra_drm_mmap, 802 .mmap = tegra_drm_mmap,
803 .poll = drm_poll, 803 .poll = drm_poll,
804 .read = drm_read, 804 .read = drm_read,
805#ifdef CONFIG_COMPAT
806 .compat_ioctl = drm_compat_ioctl, 805 .compat_ioctl = drm_compat_ioctl,
807#endif
808 .llseek = noop_llseek, 806 .llseek = noop_llseek,
809}; 807};
810 808
diff --git a/drivers/gpu/drm/tilcdc/tilcdc_drv.c b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
index 147fb28287ae..0f58a74f25d1 100644
--- a/drivers/gpu/drm/tilcdc/tilcdc_drv.c
+++ b/drivers/gpu/drm/tilcdc/tilcdc_drv.c
@@ -573,9 +573,7 @@ static const struct file_operations fops = {
573 .open = drm_open, 573 .open = drm_open,
574 .release = drm_release, 574 .release = drm_release,
575 .unlocked_ioctl = drm_ioctl, 575 .unlocked_ioctl = drm_ioctl,
576#ifdef CONFIG_COMPAT
577 .compat_ioctl = drm_compat_ioctl, 576 .compat_ioctl = drm_compat_ioctl,
578#endif
579 .poll = drm_poll, 577 .poll = drm_poll,
580 .read = drm_read, 578 .read = drm_read,
581 .llseek = no_llseek, 579 .llseek = no_llseek,
diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c
index f6ff579e8918..d5063618efa7 100644
--- a/drivers/gpu/drm/ttm/ttm_bo.c
+++ b/drivers/gpu/drm/ttm/ttm_bo.c
@@ -1611,7 +1611,14 @@ EXPORT_SYMBOL(ttm_bo_unmap_virtual);
1611int ttm_bo_wait(struct ttm_buffer_object *bo, 1611int ttm_bo_wait(struct ttm_buffer_object *bo,
1612 bool interruptible, bool no_wait) 1612 bool interruptible, bool no_wait)
1613{ 1613{
1614 long timeout = no_wait ? 0 : 15 * HZ; 1614 long timeout = 15 * HZ;
1615
1616 if (no_wait) {
1617 if (reservation_object_test_signaled_rcu(bo->resv, true))
1618 return 0;
1619 else
1620 return -EBUSY;
1621 }
1615 1622
1616 timeout = reservation_object_wait_timeout_rcu(bo->resv, true, 1623 timeout = reservation_object_wait_timeout_rcu(bo->resv, true,
1617 interruptible, timeout); 1624 interruptible, timeout);
diff --git a/drivers/gpu/drm/udl/udl_drv.c b/drivers/gpu/drm/udl/udl_drv.c
index cc45d98f9bb5..cd8b01727734 100644
--- a/drivers/gpu/drm/udl/udl_drv.c
+++ b/drivers/gpu/drm/udl/udl_drv.c
@@ -44,9 +44,7 @@ static const struct file_operations udl_driver_fops = {
44 .read = drm_read, 44 .read = drm_read,
45 .unlocked_ioctl = drm_ioctl, 45 .unlocked_ioctl = drm_ioctl,
46 .release = drm_release, 46 .release = drm_release,
47#ifdef CONFIG_COMPAT
48 .compat_ioctl = drm_compat_ioctl, 47 .compat_ioctl = drm_compat_ioctl,
49#endif
50 .llseek = noop_llseek, 48 .llseek = noop_llseek,
51}; 49};
52 50
diff --git a/drivers/gpu/drm/vc4/vc4_drv.c b/drivers/gpu/drm/vc4/vc4_drv.c
index 8703f56b7947..eaf26d9b5f11 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.c
+++ b/drivers/gpu/drm/vc4/vc4_drv.c
@@ -103,9 +103,7 @@ static const struct file_operations vc4_drm_fops = {
103 .mmap = vc4_mmap, 103 .mmap = vc4_mmap,
104 .poll = drm_poll, 104 .poll = drm_poll,
105 .read = drm_read, 105 .read = drm_read,
106#ifdef CONFIG_COMPAT
107 .compat_ioctl = drm_compat_ioctl, 106 .compat_ioctl = drm_compat_ioctl,
108#endif
109 .llseek = noop_llseek, 107 .llseek = noop_llseek,
110}; 108};
111 109
diff --git a/drivers/gpu/drm/via/via_drv.c b/drivers/gpu/drm/via/via_drv.c
index e5582bab7e3c..9e0e5392b6ec 100644
--- a/drivers/gpu/drm/via/via_drv.c
+++ b/drivers/gpu/drm/via/via_drv.c
@@ -64,9 +64,7 @@ static const struct file_operations via_driver_fops = {
64 .unlocked_ioctl = drm_ioctl, 64 .unlocked_ioctl = drm_ioctl,
65 .mmap = drm_legacy_mmap, 65 .mmap = drm_legacy_mmap,
66 .poll = drm_poll, 66 .poll = drm_poll,
67#ifdef CONFIG_COMPAT
68 .compat_ioctl = drm_compat_ioctl, 67 .compat_ioctl = drm_compat_ioctl,
69#endif
70 .llseek = noop_llseek, 68 .llseek = noop_llseek,
71}; 69};
72 70
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c b/drivers/gpu/drm/virtio/virtgpu_drv.c
index 5820b7020ae5..04d98db75c64 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -108,9 +108,7 @@ static const struct file_operations virtio_gpu_driver_fops = {
108 .read = drm_read, 108 .read = drm_read,
109 .unlocked_ioctl = drm_ioctl, 109 .unlocked_ioctl = drm_ioctl,
110 .release = drm_release, 110 .release = drm_release,
111#ifdef CONFIG_COMPAT
112 .compat_ioctl = drm_compat_ioctl, 111 .compat_ioctl = drm_compat_ioctl,
113#endif
114 .llseek = noop_llseek, 112 .llseek = noop_llseek,
115}; 113};
116 114
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index e336e3901876..4e58137c1882 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -135,6 +135,7 @@ struct dma_buf_attachment;
135#define DRM_UT_PRIME 0x08 135#define DRM_UT_PRIME 0x08
136#define DRM_UT_ATOMIC 0x10 136#define DRM_UT_ATOMIC 0x10
137#define DRM_UT_VBL 0x20 137#define DRM_UT_VBL 0x20
138#define DRM_UT_STATE 0x40
138 139
139extern __printf(6, 7) 140extern __printf(6, 7)
140void drm_dev_printk(const struct device *dev, const char *level, 141void drm_dev_printk(const struct device *dev, const char *level,
@@ -306,6 +307,27 @@ void drm_printk(const char *level, unsigned int category,
306#define DRM_DEBUG_PRIME_RATELIMITED(fmt, args...) \ 307#define DRM_DEBUG_PRIME_RATELIMITED(fmt, args...) \
307 DRM_DEV_DEBUG_PRIME_RATELIMITED(NULL, fmt, ##args) 308 DRM_DEV_DEBUG_PRIME_RATELIMITED(NULL, fmt, ##args)
308 309
310/* Format strings and argument splitters to simplify printing
311 * various "complex" objects
312 */
313#define DRM_MODE_FMT "%d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x"
314#define DRM_MODE_ARG(m) \
315 (m)->base.id, (m)->name, (m)->vrefresh, (m)->clock, \
316 (m)->hdisplay, (m)->hsync_start, (m)->hsync_end, (m)->htotal, \
317 (m)->vdisplay, (m)->vsync_start, (m)->vsync_end, (m)->vtotal, \
318 (m)->type, (m)->flags
319
320#define DRM_RECT_FMT "%dx%d%+d%+d"
321#define DRM_RECT_ARG(r) drm_rect_width(r), drm_rect_height(r), (r)->x1, (r)->y1
322
323/* for rect's in fixed-point format: */
324#define DRM_RECT_FP_FMT "%d.%06ux%d.%06u%+d.%06u%+d.%06u"
325#define DRM_RECT_FP_ARG(r) \
326 drm_rect_width(r) >> 16, ((drm_rect_width(r) & 0xffff) * 15625) >> 10, \
327 drm_rect_height(r) >> 16, ((drm_rect_height(r) & 0xffff) * 15625) >> 10, \
328 (r)->x1 >> 16, (((r)->x1 & 0xffff) * 15625) >> 10, \
329 (r)->y1 >> 16, (((r)->y1 & 0xffff) * 15625) >> 10
330
309/*@}*/ 331/*@}*/
310 332
311/***********************************************************************/ 333/***********************************************************************/
@@ -941,8 +963,13 @@ static inline bool drm_is_primary_client(const struct drm_file *file_priv)
941extern int drm_ioctl_permit(u32 flags, struct drm_file *file_priv); 963extern int drm_ioctl_permit(u32 flags, struct drm_file *file_priv);
942extern long drm_ioctl(struct file *filp, 964extern long drm_ioctl(struct file *filp,
943 unsigned int cmd, unsigned long arg); 965 unsigned int cmd, unsigned long arg);
966#ifdef CONFIG_COMPAT
944extern long drm_compat_ioctl(struct file *filp, 967extern long drm_compat_ioctl(struct file *filp,
945 unsigned int cmd, unsigned long arg); 968 unsigned int cmd, unsigned long arg);
969#else
970/* Let drm_compat_ioctl be assigned to .compat_ioctl unconditionally */
971#define drm_compat_ioctl NULL
972#endif
946extern bool drm_ioctl_flags(unsigned int nr, unsigned int *flags); 973extern bool drm_ioctl_flags(unsigned int nr, unsigned int *flags);
947 974
948/* File Operations (drm_fops.c) */ 975/* File Operations (drm_fops.c) */
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index fc8af53b18aa..331bb100b718 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -345,6 +345,8 @@ drm_atomic_set_crtc_for_plane(struct drm_plane_state *plane_state,
345 struct drm_crtc *crtc); 345 struct drm_crtc *crtc);
346void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state, 346void drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
347 struct drm_framebuffer *fb); 347 struct drm_framebuffer *fb);
348void drm_atomic_set_fence_for_plane(struct drm_plane_state *plane_state,
349 struct dma_fence *fence);
348int __must_check 350int __must_check
349drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state, 351drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
350 struct drm_crtc *crtc); 352 struct drm_crtc *crtc);
@@ -364,6 +366,13 @@ int __must_check drm_atomic_check_only(struct drm_atomic_state *state);
364int __must_check drm_atomic_commit(struct drm_atomic_state *state); 366int __must_check drm_atomic_commit(struct drm_atomic_state *state);
365int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state); 367int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
366 368
369void drm_state_dump(struct drm_device *dev, struct drm_printer *p);
370
371#ifdef CONFIG_DEBUG_FS
372struct drm_minor;
373int drm_atomic_debugfs_init(struct drm_minor *minor);
374#endif
375
367#define for_each_connector_in_state(__state, connector, connector_state, __i) \ 376#define for_each_connector_in_state(__state, connector, connector_state, __i) \
368 for ((__i) = 0; \ 377 for ((__i) = 0; \
369 (__i) < (__state)->num_connector && \ 378 (__i) < (__state)->num_connector && \
diff --git a/include/drm/drm_connector.h b/include/drm/drm_connector.h
index ac9d7d8e0e43..3e9727264b65 100644
--- a/include/drm/drm_connector.h
+++ b/include/drm/drm_connector.h
@@ -37,6 +37,7 @@ struct drm_crtc;
37struct drm_encoder; 37struct drm_encoder;
38struct drm_property; 38struct drm_property;
39struct drm_property_blob; 39struct drm_property_blob;
40struct drm_printer;
40struct edid; 41struct edid;
41 42
42enum drm_connector_force { 43enum drm_connector_force {
@@ -481,6 +482,18 @@ struct drm_connector_funcs {
481 const struct drm_connector_state *state, 482 const struct drm_connector_state *state,
482 struct drm_property *property, 483 struct drm_property *property,
483 uint64_t *val); 484 uint64_t *val);
485
486 /**
487 * @atomic_print_state:
488 *
489 * If driver subclasses struct &drm_connector_state, it should implement
490 * this optional hook for printing additional driver specific state.
491 *
492 * Do not call this directly, use drm_atomic_connector_print_state()
493 * instead.
494 */
495 void (*atomic_print_state)(struct drm_printer *p,
496 const struct drm_connector_state *state);
484}; 497};
485 498
486/* mode specified on the command line */ 499/* mode specified on the command line */
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index fa1aa214c8ea..8cca2a895981 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -53,6 +53,7 @@ struct drm_device;
53struct drm_mode_set; 53struct drm_mode_set;
54struct drm_file; 54struct drm_file;
55struct drm_clip_rect; 55struct drm_clip_rect;
56struct drm_printer;
56struct device_node; 57struct device_node;
57struct dma_fence; 58struct dma_fence;
58struct edid; 59struct edid;
@@ -594,6 +595,18 @@ struct drm_crtc_funcs {
594 */ 595 */
595 int (*set_crc_source)(struct drm_crtc *crtc, const char *source, 596 int (*set_crc_source)(struct drm_crtc *crtc, const char *source,
596 size_t *values_cnt); 597 size_t *values_cnt);
598
599 /**
600 * @atomic_print_state:
601 *
602 * If driver subclasses struct &drm_crtc_state, it should implement
603 * this optional hook for printing additional driver specific state.
604 *
605 * Do not call this directly, use drm_atomic_crtc_print_state()
606 * instead.
607 */
608 void (*atomic_print_state)(struct drm_printer *p,
609 const struct drm_crtc_state *state);
597}; 610};
598 611
599/** 612/**
diff --git a/include/drm/drm_mm.h b/include/drm/drm_mm.h
index 205ddcf6d55d..41ddafe92b2f 100644
--- a/include/drm/drm_mm.h
+++ b/include/drm/drm_mm.h
@@ -44,6 +44,9 @@
44#ifdef CONFIG_DEBUG_FS 44#ifdef CONFIG_DEBUG_FS
45#include <linux/seq_file.h> 45#include <linux/seq_file.h>
46#endif 46#endif
47#ifdef CONFIG_DRM_DEBUG_MM
48#include <linux/stackdepot.h>
49#endif
47 50
48enum drm_mm_search_flags { 51enum drm_mm_search_flags {
49 DRM_MM_SEARCH_DEFAULT = 0, 52 DRM_MM_SEARCH_DEFAULT = 0,
@@ -74,6 +77,9 @@ struct drm_mm_node {
74 u64 size; 77 u64 size;
75 u64 __subtree_last; 78 u64 __subtree_last;
76 struct drm_mm *mm; 79 struct drm_mm *mm;
80#ifdef CONFIG_DRM_DEBUG_MM
81 depot_stack_handle_t stack;
82#endif
77}; 83};
78 84
79struct drm_mm { 85struct drm_mm {
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index 10e449c86dbd..72478cf82147 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -361,8 +361,8 @@ struct drm_crtc_helper_funcs {
361 * 361 *
362 * Note that the power state of the display pipe when this function is 362 * Note that the power state of the display pipe when this function is
363 * called depends upon the exact helpers and calling sequence the driver 363 * called depends upon the exact helpers and calling sequence the driver
364 * has picked. See drm_atomic_commit_planes() for a discussion of the 364 * has picked. See drm_atomic_helper_commit_planes() for a discussion of
365 * tradeoffs and variants of plane commit helpers. 365 * the tradeoffs and variants of plane commit helpers.
366 * 366 *
367 * This callback is used by the atomic modeset helpers and by the 367 * This callback is used by the atomic modeset helpers and by the
368 * transitional plane helpers, but it is optional. 368 * transitional plane helpers, but it is optional.
@@ -385,8 +385,8 @@ struct drm_crtc_helper_funcs {
385 * 385 *
386 * Note that the power state of the display pipe when this function is 386 * Note that the power state of the display pipe when this function is
387 * called depends upon the exact helpers and calling sequence the driver 387 * called depends upon the exact helpers and calling sequence the driver
388 * has picked. See drm_atomic_commit_planes() for a discussion of the 388 * has picked. See drm_atomic_helper_commit_planes() for a discussion of
389 * tradeoffs and variants of plane commit helpers. 389 * the tradeoffs and variants of plane commit helpers.
390 * 390 *
391 * This callback is used by the atomic modeset helpers and by the 391 * This callback is used by the atomic modeset helpers and by the
392 * transitional plane helpers, but it is optional. 392 * transitional plane helpers, but it is optional.
@@ -940,8 +940,8 @@ struct drm_plane_helper_funcs {
940 * 940 *
941 * Note that the power state of the display pipe when this function is 941 * Note that the power state of the display pipe when this function is
942 * called depends upon the exact helpers and calling sequence the driver 942 * called depends upon the exact helpers and calling sequence the driver
943 * has picked. See drm_atomic_commit_planes() for a discussion of the 943 * has picked. See drm_atomic_helper_commit_planes() for a discussion of
944 * tradeoffs and variants of plane commit helpers. 944 * the tradeoffs and variants of plane commit helpers.
945 * 945 *
946 * This callback is used by the atomic modeset helpers and by the 946 * This callback is used by the atomic modeset helpers and by the
947 * transitional plane helpers, but it is optional. 947 * transitional plane helpers, but it is optional.
@@ -963,8 +963,8 @@ struct drm_plane_helper_funcs {
963 * 963 *
964 * Note that the power state of the display pipe when this function is 964 * Note that the power state of the display pipe when this function is
965 * called depends upon the exact helpers and calling sequence the driver 965 * called depends upon the exact helpers and calling sequence the driver
966 * has picked. See drm_atomic_commit_planes() for a discussion of the 966 * has picked. See drm_atomic_helper_commit_planes() for a discussion of
967 * tradeoffs and variants of plane commit helpers. 967 * the tradeoffs and variants of plane commit helpers.
968 * 968 *
969 * This callback is used by the atomic modeset helpers and by the 969 * This callback is used by the atomic modeset helpers and by the
970 * transitional plane helpers, but it is optional. 970 * transitional plane helpers, but it is optional.
diff --git a/include/drm/drm_plane.h b/include/drm/drm_plane.h
index 0bed92c5dbd8..5b38eb94783b 100644
--- a/include/drm/drm_plane.h
+++ b/include/drm/drm_plane.h
@@ -28,15 +28,11 @@
28#include <drm/drm_mode_object.h> 28#include <drm/drm_mode_object.h>
29 29
30struct drm_crtc; 30struct drm_crtc;
31struct drm_printer;
31 32
32/** 33/**
33 * struct drm_plane_state - mutable plane state 34 * struct drm_plane_state - mutable plane state
34 * @plane: backpointer to the plane 35 * @plane: backpointer to the plane
35 * @crtc: currently bound CRTC, NULL if disabled
36 * @fb: currently bound framebuffer
37 * @fence: optional fence to wait for before scanning out @fb
38 * @crtc_x: left position of visible portion of plane on crtc
39 * @crtc_y: upper position of visible portion of plane on crtc
40 * @crtc_w: width of visible portion of plane on crtc 36 * @crtc_w: width of visible portion of plane on crtc
41 * @crtc_h: height of visible portion of plane on crtc 37 * @crtc_h: height of visible portion of plane on crtc
42 * @src_x: left position of visible portion of plane within 38 * @src_x: left position of visible portion of plane within
@@ -57,18 +53,51 @@ struct drm_crtc;
57 * it can be trusted. 53 * it can be trusted.
58 * @src: clipped source coordinates of the plane (in 16.16) 54 * @src: clipped source coordinates of the plane (in 16.16)
59 * @dst: clipped destination coordinates of the plane 55 * @dst: clipped destination coordinates of the plane
60 * @visible: visibility of the plane
61 * @state: backpointer to global drm_atomic_state 56 * @state: backpointer to global drm_atomic_state
62 */ 57 */
63struct drm_plane_state { 58struct drm_plane_state {
64 struct drm_plane *plane; 59 struct drm_plane *plane;
65 60
66 struct drm_crtc *crtc; /* do not write directly, use drm_atomic_set_crtc_for_plane() */ 61 /**
67 struct drm_framebuffer *fb; /* do not write directly, use drm_atomic_set_fb_for_plane() */ 62 * @crtc:
63 *
64 * Currently bound CRTC, NULL if disabled. Do not this write directly,
65 * use drm_atomic_set_crtc_for_plane()
66 */
67 struct drm_crtc *crtc;
68
69 /**
70 * @fb:
71 *
72 * Currently bound framebuffer. Do not write this directly, use
73 * drm_atomic_set_fb_for_plane()
74 */
75 struct drm_framebuffer *fb;
76
77 /**
78 * @fence:
79 *
80 * Optional fence to wait for before scanning out @fb. Do not write this
81 * directly, use drm_atomic_set_fence_for_plane()
82 */
68 struct dma_fence *fence; 83 struct dma_fence *fence;
69 84
70 /* Signed dest location allows it to be partially off screen */ 85 /**
71 int32_t crtc_x, crtc_y; 86 * @crtc_x:
87 *
88 * Left position of visible portion of plane on crtc, signed dest
89 * location allows it to be partially off screen.
90 */
91
92 int32_t crtc_x;
93 /**
94 * @crtc_y:
95 *
96 * Upper position of visible portion of plane on crtc, signed dest
97 * location allows it to be partially off screen.
98 */
99 int32_t crtc_y;
100
72 uint32_t crtc_w, crtc_h; 101 uint32_t crtc_w, crtc_h;
73 102
74 /* Source values are 16.16 fixed point */ 103 /* Source values are 16.16 fixed point */
@@ -85,15 +114,41 @@ struct drm_plane_state {
85 /* Clipped coordinates */ 114 /* Clipped coordinates */
86 struct drm_rect src, dst; 115 struct drm_rect src, dst;
87 116
88 /* 117 /**
89 * Is the plane actually visible? Can be false even 118 * @visible:
90 * if fb!=NULL and crtc!=NULL, due to clipping. 119 *
120 * Visibility of the plane. This can be false even if fb!=NULL and
121 * crtc!=NULL, due to clipping.
91 */ 122 */
92 bool visible; 123 bool visible;
93 124
94 struct drm_atomic_state *state; 125 struct drm_atomic_state *state;
95}; 126};
96 127
128static inline struct drm_rect
129drm_plane_state_src(const struct drm_plane_state *state)
130{
131 struct drm_rect src = {
132 .x1 = state->src_x,
133 .y1 = state->src_y,
134 .x2 = state->src_x + state->src_w,
135 .y2 = state->src_y + state->src_h,
136 };
137 return src;
138}
139
140static inline struct drm_rect
141drm_plane_state_dest(const struct drm_plane_state *state)
142{
143 struct drm_rect dest = {
144 .x1 = state->crtc_x,
145 .y1 = state->crtc_y,
146 .x2 = state->crtc_x + state->crtc_w,
147 .y2 = state->crtc_y + state->crtc_h,
148 };
149 return dest;
150}
151
97/** 152/**
98 * struct drm_plane_funcs - driver plane control functions 153 * struct drm_plane_funcs - driver plane control functions
99 */ 154 */
@@ -322,6 +377,18 @@ struct drm_plane_funcs {
322 * before data structures are torndown. 377 * before data structures are torndown.
323 */ 378 */
324 void (*early_unregister)(struct drm_plane *plane); 379 void (*early_unregister)(struct drm_plane *plane);
380
381 /**
382 * @atomic_print_state:
383 *
384 * If driver subclasses struct &drm_plane_state, it should implement
385 * this optional hook for printing additional driver specific state.
386 *
387 * Do not call this directly, use drm_atomic_plane_print_state()
388 * instead.
389 */
390 void (*atomic_print_state)(struct drm_printer *p,
391 const struct drm_plane_state *state);
325}; 392};
326 393
327/** 394/**
diff --git a/include/drm/drm_print.h b/include/drm/drm_print.h
new file mode 100644
index 000000000000..475ffe3730e9
--- /dev/null
+++ b/include/drm/drm_print.h
@@ -0,0 +1,117 @@
1/*
2 * Copyright (C) 2016 Red Hat
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 * Authors:
23 * Rob Clark <robdclark@gmail.com>
24 */
25
26#ifndef DRM_PRINT_H_
27#define DRM_PRINT_H_
28
29#include <linux/seq_file.h>
30#include <linux/device.h>
31
32/**
33 * DOC: print
34 *
35 * A simple wrapper for dev_printk(), seq_printf(), etc. Allows same
36 * debug code to be used for both debugfs and printk logging.
37 *
38 * For example::
39 *
40 * void log_some_info(struct drm_printer *p)
41 * {
42 * drm_printf(p, "foo=%d\n", foo);
43 * drm_printf(p, "bar=%d\n", bar);
44 * }
45 *
46 * #ifdef CONFIG_DEBUG_FS
47 * void debugfs_show(struct seq_file *f)
48 * {
49 * struct drm_printer p = drm_seq_file_printer(f);
50 * log_some_info(&p);
51 * }
52 * #endif
53 *
54 * void some_other_function(...)
55 * {
56 * struct drm_printer p = drm_info_printer(drm->dev);
57 * log_some_info(&p);
58 * }
59 */
60
61/**
62 * struct drm_printer - drm output "stream"
63 * @printfn: actual output fxn
64 * @arg: output fxn specific data
65 *
66 * Do not use struct members directly. Use drm_printer_seq_file(),
67 * drm_printer_info(), etc to initialize. And drm_printf() for output.
68 */
69struct drm_printer {
70 void (*printfn)(struct drm_printer *p, struct va_format *vaf);
71 void *arg;
72};
73
74void __drm_printfn_seq_file(struct drm_printer *p, struct va_format *vaf);
75void __drm_printfn_info(struct drm_printer *p, struct va_format *vaf);
76
77/**
78 * drm_printf - print to a &drm_printer stream
79 * @p: the &drm_printer
80 * @f: format string
81 */
82void drm_printf(struct drm_printer *p, const char *f, ...);
83
84
85/**
86 * drm_seq_file_printer - construct a &drm_printer that outputs to &seq_file
87 * @f: the struct &seq_file to output to
88 *
89 * RETURNS:
90 * The &drm_printer object
91 */
92static inline struct drm_printer drm_seq_file_printer(struct seq_file *f)
93{
94 struct drm_printer p = {
95 .printfn = __drm_printfn_seq_file,
96 .arg = f,
97 };
98 return p;
99}
100
101/**
102 * drm_info_printer - construct a &drm_printer that outputs to dev_printk()
103 * @dev: the struct &device pointer
104 *
105 * RETURNS:
106 * The &drm_printer object
107 */
108static inline struct drm_printer drm_info_printer(struct device *dev)
109{
110 struct drm_printer p = {
111 .printfn = __drm_printfn_info,
112 .arg = dev,
113 };
114 return p;
115}
116
117#endif /* DRM_PRINT_H_ */
diff --git a/include/linux/dma-fence.h b/include/linux/dma-fence.h
index ba60c043a5d3..fcf4b1971eba 100644
--- a/include/linux/dma-fence.h
+++ b/include/linux/dma-fence.h
@@ -382,7 +382,8 @@ signed long dma_fence_wait_timeout(struct dma_fence *,
382 bool intr, signed long timeout); 382 bool intr, signed long timeout);
383signed long dma_fence_wait_any_timeout(struct dma_fence **fences, 383signed long dma_fence_wait_any_timeout(struct dma_fence **fences,
384 uint32_t count, 384 uint32_t count,
385 bool intr, signed long timeout); 385 bool intr, signed long timeout,
386 uint32_t *idx);
386 387
387/** 388/**
388 * dma_fence_wait - sleep until the fence gets signaled 389 * dma_fence_wait - sleep until the fence gets signaled
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 4684f378f046..2191a9e4f3db 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -50,6 +50,7 @@ extern "C" {
50#define DRM_AMDGPU_WAIT_CS 0x09 50#define DRM_AMDGPU_WAIT_CS 0x09
51#define DRM_AMDGPU_GEM_OP 0x10 51#define DRM_AMDGPU_GEM_OP 0x10
52#define DRM_AMDGPU_GEM_USERPTR 0x11 52#define DRM_AMDGPU_GEM_USERPTR 0x11
53#define DRM_AMDGPU_WAIT_FENCES 0x12
53 54
54#define DRM_IOCTL_AMDGPU_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create) 55#define DRM_IOCTL_AMDGPU_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_CREATE, union drm_amdgpu_gem_create)
55#define DRM_IOCTL_AMDGPU_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap) 56#define DRM_IOCTL_AMDGPU_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_MMAP, union drm_amdgpu_gem_mmap)
@@ -63,6 +64,7 @@ extern "C" {
63#define DRM_IOCTL_AMDGPU_WAIT_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_CS, union drm_amdgpu_wait_cs) 64#define DRM_IOCTL_AMDGPU_WAIT_CS DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_CS, union drm_amdgpu_wait_cs)
64#define DRM_IOCTL_AMDGPU_GEM_OP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_OP, struct drm_amdgpu_gem_op) 65#define DRM_IOCTL_AMDGPU_GEM_OP DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_OP, struct drm_amdgpu_gem_op)
65#define DRM_IOCTL_AMDGPU_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_USERPTR, struct drm_amdgpu_gem_userptr) 66#define DRM_IOCTL_AMDGPU_GEM_USERPTR DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_GEM_USERPTR, struct drm_amdgpu_gem_userptr)
67#define DRM_IOCTL_AMDGPU_WAIT_FENCES DRM_IOWR(DRM_COMMAND_BASE + DRM_AMDGPU_WAIT_FENCES, union drm_amdgpu_wait_fences)
66 68
67#define AMDGPU_GEM_DOMAIN_CPU 0x1 69#define AMDGPU_GEM_DOMAIN_CPU 0x1
68#define AMDGPU_GEM_DOMAIN_GTT 0x2 70#define AMDGPU_GEM_DOMAIN_GTT 0x2
@@ -307,6 +309,32 @@ union drm_amdgpu_wait_cs {
307 struct drm_amdgpu_wait_cs_out out; 309 struct drm_amdgpu_wait_cs_out out;
308}; 310};
309 311
312struct drm_amdgpu_fence {
313 __u32 ctx_id;
314 __u32 ip_type;
315 __u32 ip_instance;
316 __u32 ring;
317 __u64 seq_no;
318};
319
320struct drm_amdgpu_wait_fences_in {
321 /** This points to uint64_t * which points to fences */
322 __u64 fences;
323 __u32 fence_count;
324 __u32 wait_all;
325 __u64 timeout_ns;
326};
327
328struct drm_amdgpu_wait_fences_out {
329 __u32 status;
330 __u32 first_signaled;
331};
332
333union drm_amdgpu_wait_fences {
334 struct drm_amdgpu_wait_fences_in in;
335 struct drm_amdgpu_wait_fences_out out;
336};
337
310#define AMDGPU_GEM_OP_GET_GEM_CREATE_INFO 0 338#define AMDGPU_GEM_OP_GET_GEM_CREATE_INFO 0
311#define AMDGPU_GEM_OP_SET_PLACEMENT 1 339#define AMDGPU_GEM_OP_SET_PLACEMENT 1
312 340
diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h
index 084b50a02dc5..01000c9f7c2c 100644
--- a/include/uapi/drm/drm_mode.h
+++ b/include/uapi/drm/drm_mode.h
@@ -47,7 +47,15 @@ extern "C" {
47#define DRM_MODE_TYPE_DRIVER (1<<6) 47#define DRM_MODE_TYPE_DRIVER (1<<6)
48 48
49/* Video mode flags */ 49/* Video mode flags */
50/* bit compatible with the xorg definitions. */ 50/* bit compatible with the xrandr RR_ definitions (bits 0-13)
51 *
52 * ABI warning: Existing userspace really expects
53 * the mode flags to match the xrandr definitions. Any
54 * changes that don't match the xrandr definitions will
55 * likely need a new client cap or some other mechanism
56 * to avoid breaking existing userspace. This includes
57 * allocating new flags in the previously unused bits!
58 */
51#define DRM_MODE_FLAG_PHSYNC (1<<0) 59#define DRM_MODE_FLAG_PHSYNC (1<<0)
52#define DRM_MODE_FLAG_NHSYNC (1<<1) 60#define DRM_MODE_FLAG_NHSYNC (1<<1)
53#define DRM_MODE_FLAG_PVSYNC (1<<2) 61#define DRM_MODE_FLAG_PVSYNC (1<<2)