aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2016-06-08 21:19:28 -0400
committerDave Airlie <airlied@redhat.com>2016-06-08 21:19:28 -0400
commit2cca45574007b4a77fa5f63ea45d664510cec22a (patch)
treedd32a0b2bea4f3cef900b15c6badc8dfde69ab69
parentbb4cec0222f984d7ef282c06cc3644069db21bac (diff)
parente8395081636734da19778b0446d65588a06bc40d (diff)
Merge tag 'topic/drm-misc-2016-06-07' of git://anongit.freedesktop.org/drm-intel into drm-next
As promised, piles of prep work all around: - drm_atomic_state rework, prep for nonblocking commit helpers - fence patches from Gustavo and Christian to prep for atomic fences and some cool work in ttm/amdgpu from Christian - drm event prep for both nonblocking commit and atomic fences - Gustavo seems on a crusade against the non-kms-native version of the vblank functions. - prep work from Boris to nuke all the silly ->best_encoder implementations we have (we really only need that for truly dynamic cases like dvi-i vs dvi-d or dp mst selecting the right transcoder on intel) - prep work from Laurent to rework the format handling functions - and few small things all over * tag 'topic/drm-misc-2016-06-07' of git://anongit.freedesktop.org/drm-intel: (47 commits) drm/dsi: Implement set tear scanline drm/fb_cma_helper: Implement fb_mmap callback drm/qxl: Remove useless drm_fb_get_bpp_depth() call drm/ast: Remove useless drm_fb_get_bpp_depth() call drm/atomic: Fix remaining places where !funcs->best_encoder is valid drm/core: Change declaration for gamma_set. Documentation: add fence-array to kernel DocBook drm/shmobile: use drm_crtc_vblank_{get,put}() drm/radeon: use drm_crtc_vblank_{get,put}() drm/qxl: use drm_crtc_vblank_{get,put}() drm/atmel: use drm_crtc_vblank_{get,put}() drm/armada: use drm_crtc_vblank_{get,put}() drm/amdgpu: use drm_crtc_vblank_{get,put}() drm/virtio: use drm_crtc_send_vblank_event() drm/udl: use drm_crtc_send_vblank_event() drm/qxl: use drm_crtc_send_vblank_event() drm/atmel: use drm_crtc_send_vblank_event() drm/armada: use drm_crtc_send_vblank_event() drm/doc: Switch to sphinx/rst fixed-width quoting drm/doc: Drop kerneldoc for static functions in drm_irq.c ...
-rw-r--r--Documentation/DocBook/device-drivers.tmpl4
-rw-r--r--Documentation/DocBook/gpu.tmpl2
-rw-r--r--drivers/dma-buf/Makefile2
-rw-r--r--drivers/dma-buf/fence-array.c144
-rw-r--r--drivers/dma-buf/fence.c8
-rw-r--r--drivers/dma-buf/sync_file.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu.h2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_display.c4
-rw-r--r--drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c2
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v10_0.c12
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v11_0.c12
-rw-r--r--drivers/gpu/drm/amd/amdgpu/dce_v8_0.c12
-rw-r--r--drivers/gpu/drm/arc/arcpgu_drv.c2
-rw-r--r--drivers/gpu/drm/arm/hdlcd_crtc.c19
-rw-r--r--drivers/gpu/drm/armada/armada_crtc.c14
-rw-r--r--drivers/gpu/drm/ast/ast_fb.c3
-rw-r--r--drivers/gpu/drm/ast/ast_mode.c10
-rw-r--r--drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c4
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_mode.c8
-rw-r--r--drivers/gpu/drm/drm_atomic.c80
-rw-r--r--drivers/gpu/drm/drm_atomic_helper.c76
-rw-r--r--drivers/gpu/drm/drm_bridge.c2
-rw-r--r--drivers/gpu/drm/drm_crtc.c102
-rw-r--r--drivers/gpu/drm/drm_fb_cma_helper.c27
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c15
-rw-r--r--drivers/gpu/drm/drm_fops.c18
-rw-r--r--drivers/gpu/drm/drm_gem.c2
-rw-r--r--drivers/gpu/drm/drm_irq.c12
-rw-r--r--drivers/gpu/drm/drm_mipi_dsi.c22
-rw-r--r--drivers/gpu/drm/drm_modes.c4
-rw-r--r--drivers/gpu/drm/drm_modeset_lock.c2
-rw-r--r--drivers/gpu/drm/drm_plane_helper.c10
-rw-r--r--drivers/gpu/drm/drm_probe_helper.c21
-rw-r--r--drivers/gpu/drm/drm_vma_manager.c3
-rw-r--r--drivers/gpu/drm/etnaviv/etnaviv_gpu.h2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c8
-rw-r--r--drivers/gpu/drm/gma500/gma_display.c9
-rw-r--r--drivers/gpu/drm/gma500/gma_display.h4
-rw-r--r--drivers/gpu/drm/i915/i915_reg.h2
-rw-r--r--drivers/gpu/drm/i915/i915_vgpu.c24
-rw-r--r--drivers/gpu/drm/i915/intel_atomic.c5
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c16
-rw-r--r--drivers/gpu/drm/i915/intel_fbc.c3
-rw-r--r--drivers/gpu/drm/mgag200/mgag200_mode.c9
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c20
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c10
-rw-r--r--drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c12
-rw-r--r--drivers/gpu/drm/msm/msm_atomic.c37
-rw-r--r--drivers/gpu/drm/nouveau/dispnv04/crtc.c12
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fence.h3
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_usif.c1
-rw-r--r--drivers/gpu/drm/nouveau/nv50_display.c9
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c11
-rw-r--r--drivers/gpu/drm/qxl/qxl_display.c7
-rw-r--r--drivers/gpu/drm/qxl/qxl_fb.c4
-rw-r--r--drivers/gpu/drm/qxl/qxl_release.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon.h2
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c17
-rw-r--r--drivers/gpu/drm/radeon/radeon_pm.c13
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_kms.c8
-rw-r--r--drivers/gpu/drm/rcar-du/rcar_du_plane.c20
-rw-r--r--drivers/gpu/drm/rockchip/rockchip_drm_vop.c2
-rw-r--r--drivers/gpu/drm/shmobile/shmob_drm_crtc.c4
-rw-r--r--drivers/gpu/drm/udl/udl_modeset.c2
-rw-r--r--drivers/gpu/drm/vc4/vc4_crtc.c21
-rw-r--r--drivers/gpu/drm/vc4/vc4_drv.h2
-rw-r--r--drivers/gpu/drm/vc4/vc4_kms.c10
-rw-r--r--drivers/gpu/drm/vc4/vc4_plane.c5
-rw-r--r--drivers/gpu/drm/virtio/virtgpu_display.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fence.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c8
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.h4
-rw-r--r--drivers/staging/android/sync.h3
-rw-r--r--include/drm/drmP.h13
-rw-r--r--include/drm/drm_atomic.h66
-rw-r--r--include/drm/drm_atomic_helper.h30
-rw-r--r--include/drm/drm_crtc.h161
-rw-r--r--include/drm/drm_mipi_dsi.h1
-rw-r--r--include/drm/drm_modes.h2
-rw-r--r--include/drm/drm_modeset_helper_vtables.h10
-rw-r--r--include/linux/fence-array.h73
-rw-r--r--include/linux/fence.h13
82 files changed, 849 insertions, 517 deletions
diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl
index 8c68768ebee5..c3313d45f4d6 100644
--- a/Documentation/DocBook/device-drivers.tmpl
+++ b/Documentation/DocBook/device-drivers.tmpl
@@ -161,6 +161,10 @@ X!Edrivers/base/interface.c
161!Iinclude/linux/fence.h 161!Iinclude/linux/fence.h
162!Edrivers/dma-buf/seqno-fence.c 162!Edrivers/dma-buf/seqno-fence.c
163!Iinclude/linux/seqno-fence.h 163!Iinclude/linux/seqno-fence.h
164!Edrivers/dma-buf/fence-array.c
165!Iinclude/linux/fence-array.h
166!Edrivers/dma-buf/reservation.c
167!Iinclude/linux/reservation.h
164!Edrivers/dma-buf/sync_file.c 168!Edrivers/dma-buf/sync_file.c
165!Iinclude/linux/sync_file.h 169!Iinclude/linux/sync_file.h
166 </sect2> 170 </sect2>
diff --git a/Documentation/DocBook/gpu.tmpl b/Documentation/DocBook/gpu.tmpl
index b3a04b521b22..dac18b4ff090 100644
--- a/Documentation/DocBook/gpu.tmpl
+++ b/Documentation/DocBook/gpu.tmpl
@@ -1570,7 +1570,7 @@ void intel_crt_init(struct drm_device *dev)
1570 </sect3> 1570 </sect3>
1571 <sect3> 1571 <sect3>
1572 <title>Implementing Asynchronous Atomic Commit</title> 1572 <title>Implementing Asynchronous Atomic Commit</title>
1573!Pdrivers/gpu/drm/drm_atomic_helper.c implementing async commit 1573!Pdrivers/gpu/drm/drm_atomic_helper.c implementing nonblocking commit
1574 </sect3> 1574 </sect3>
1575 <sect3> 1575 <sect3>
1576 <title>Atomic State Reset and Initialization</title> 1576 <title>Atomic State Reset and Initialization</title>
diff --git a/drivers/dma-buf/Makefile b/drivers/dma-buf/Makefile
index 4a424eca75ed..f353db213a81 100644
--- a/drivers/dma-buf/Makefile
+++ b/drivers/dma-buf/Makefile
@@ -1,2 +1,2 @@
1obj-y := dma-buf.o fence.o reservation.o seqno-fence.o 1obj-y := dma-buf.o fence.o reservation.o seqno-fence.o fence-array.o
2obj-$(CONFIG_SYNC_FILE) += sync_file.o 2obj-$(CONFIG_SYNC_FILE) += sync_file.o
diff --git a/drivers/dma-buf/fence-array.c b/drivers/dma-buf/fence-array.c
new file mode 100644
index 000000000000..a8731c853da6
--- /dev/null
+++ b/drivers/dma-buf/fence-array.c
@@ -0,0 +1,144 @@
1/*
2 * fence-array: aggregate fences to be waited together
3 *
4 * Copyright (C) 2016 Collabora Ltd
5 * Copyright (C) 2016 Advanced Micro Devices, Inc.
6 * Authors:
7 * Gustavo Padovan <gustavo@padovan.org>
8 * Christian König <christian.koenig@amd.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published by
12 * the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 */
19
20#include <linux/export.h>
21#include <linux/slab.h>
22#include <linux/fence-array.h>
23
24static void fence_array_cb_func(struct fence *f, struct fence_cb *cb);
25
26static const char *fence_array_get_driver_name(struct fence *fence)
27{
28 return "fence_array";
29}
30
31static const char *fence_array_get_timeline_name(struct fence *fence)
32{
33 return "unbound";
34}
35
36static void fence_array_cb_func(struct fence *f, struct fence_cb *cb)
37{
38 struct fence_array_cb *array_cb =
39 container_of(cb, struct fence_array_cb, cb);
40 struct fence_array *array = array_cb->array;
41
42 if (atomic_dec_and_test(&array->num_pending))
43 fence_signal(&array->base);
44 fence_put(&array->base);
45}
46
47static bool fence_array_enable_signaling(struct fence *fence)
48{
49 struct fence_array *array = to_fence_array(fence);
50 struct fence_array_cb *cb = (void *)(&array[1]);
51 unsigned i;
52
53 for (i = 0; i < array->num_fences; ++i) {
54 cb[i].array = array;
55 /*
56 * As we may report that the fence is signaled before all
57 * callbacks are complete, we need to take an additional
58 * reference count on the array so that we do not free it too
59 * early. The core fence handling will only hold the reference
60 * until we signal the array as complete (but that is now
61 * insufficient).
62 */
63 fence_get(&array->base);
64 if (fence_add_callback(array->fences[i], &cb[i].cb,
65 fence_array_cb_func)) {
66 fence_put(&array->base);
67 if (atomic_dec_and_test(&array->num_pending))
68 return false;
69 }
70 }
71
72 return true;
73}
74
75static bool fence_array_signaled(struct fence *fence)
76{
77 struct fence_array *array = to_fence_array(fence);
78
79 return atomic_read(&array->num_pending) <= 0;
80}
81
82static void fence_array_release(struct fence *fence)
83{
84 struct fence_array *array = to_fence_array(fence);
85 unsigned i;
86
87 for (i = 0; i < array->num_fences; ++i)
88 fence_put(array->fences[i]);
89
90 kfree(array->fences);
91 fence_free(fence);
92}
93
94const struct fence_ops fence_array_ops = {
95 .get_driver_name = fence_array_get_driver_name,
96 .get_timeline_name = fence_array_get_timeline_name,
97 .enable_signaling = fence_array_enable_signaling,
98 .signaled = fence_array_signaled,
99 .wait = fence_default_wait,
100 .release = fence_array_release,
101};
102
103/**
104 * fence_array_create - Create a custom fence array
105 * @num_fences: [in] number of fences to add in the array
106 * @fences: [in] array containing the fences
107 * @context: [in] fence context to use
108 * @seqno: [in] sequence number to use
109 * @signal_on_any [in] signal on any fence in the array
110 *
111 * Allocate a fence_array object and initialize the base fence with fence_init().
112 * In case of error it returns NULL.
113 *
114 * The caller should allocte the fences array with num_fences size
115 * and fill it with the fences it wants to add to the object. Ownership of this
116 * array is take and fence_put() is used on each fence on release.
117 *
118 * If @signal_on_any is true the fence array signals if any fence in the array
119 * signals, otherwise it signals when all fences in the array signal.
120 */
121struct fence_array *fence_array_create(int num_fences, struct fence **fences,
122 u64 context, unsigned seqno,
123 bool signal_on_any)
124{
125 struct fence_array *array;
126 size_t size = sizeof(*array);
127
128 /* Allocate the callback structures behind the array. */
129 size += num_fences * sizeof(struct fence_array_cb);
130 array = kzalloc(size, GFP_KERNEL);
131 if (!array)
132 return NULL;
133
134 spin_lock_init(&array->lock);
135 fence_init(&array->base, &fence_array_ops, &array->lock,
136 context, seqno);
137
138 array->num_fences = num_fences;
139 atomic_set(&array->num_pending, signal_on_any ? 1 : num_fences);
140 array->fences = fences;
141
142 return array;
143}
144EXPORT_SYMBOL(fence_array_create);
diff --git a/drivers/dma-buf/fence.c b/drivers/dma-buf/fence.c
index 7b05dbe9b296..4d51f9e83fa8 100644
--- a/drivers/dma-buf/fence.c
+++ b/drivers/dma-buf/fence.c
@@ -35,7 +35,7 @@ EXPORT_TRACEPOINT_SYMBOL(fence_emit);
35 * context or not. One device can have multiple separate contexts, 35 * context or not. One device can have multiple separate contexts,
36 * and they're used if some engine can run independently of another. 36 * and they're used if some engine can run independently of another.
37 */ 37 */
38static atomic_t fence_context_counter = ATOMIC_INIT(0); 38static atomic64_t fence_context_counter = ATOMIC64_INIT(0);
39 39
40/** 40/**
41 * fence_context_alloc - allocate an array of fence contexts 41 * fence_context_alloc - allocate an array of fence contexts
@@ -44,10 +44,10 @@ static atomic_t fence_context_counter = ATOMIC_INIT(0);
44 * This function will return the first index of the number of fences allocated. 44 * This function will return the first index of the number of fences allocated.
45 * The fence context is used for setting fence->context to a unique number. 45 * The fence context is used for setting fence->context to a unique number.
46 */ 46 */
47unsigned fence_context_alloc(unsigned num) 47u64 fence_context_alloc(unsigned num)
48{ 48{
49 BUG_ON(!num); 49 BUG_ON(!num);
50 return atomic_add_return(num, &fence_context_counter) - num; 50 return atomic64_add_return(num, &fence_context_counter) - num;
51} 51}
52EXPORT_SYMBOL(fence_context_alloc); 52EXPORT_SYMBOL(fence_context_alloc);
53 53
@@ -513,7 +513,7 @@ EXPORT_SYMBOL(fence_wait_any_timeout);
513 */ 513 */
514void 514void
515fence_init(struct fence *fence, const struct fence_ops *ops, 515fence_init(struct fence *fence, const struct fence_ops *ops,
516 spinlock_t *lock, unsigned context, unsigned seqno) 516 spinlock_t *lock, u64 context, unsigned seqno)
517{ 517{
518 BUG_ON(!lock); 518 BUG_ON(!lock);
519 BUG_ON(!ops || !ops->wait || !ops->enable_signaling || 519 BUG_ON(!ops || !ops->wait || !ops->enable_signaling ||
diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c
index f08cf2d8309e..9aaa608dfe01 100644
--- a/drivers/dma-buf/sync_file.c
+++ b/drivers/dma-buf/sync_file.c
@@ -82,7 +82,7 @@ struct sync_file *sync_file_create(struct fence *fence)
82 82
83 sync_file->num_fences = 1; 83 sync_file->num_fences = 1;
84 atomic_set(&sync_file->status, 1); 84 atomic_set(&sync_file->status, 1);
85 snprintf(sync_file->name, sizeof(sync_file->name), "%s-%s%d-%d", 85 snprintf(sync_file->name, sizeof(sync_file->name), "%s-%s%llu-%d",
86 fence->ops->get_driver_name(fence), 86 fence->ops->get_driver_name(fence),
87 fence->ops->get_timeline_name(fence), fence->context, 87 fence->ops->get_timeline_name(fence), fence->context,
88 fence->seqno); 88 fence->seqno);
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu.h b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
index 992f00b65be4..da3d02154fa6 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu.h
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu.h
@@ -2032,7 +2032,7 @@ struct amdgpu_device {
2032 struct amdgpu_irq_src hpd_irq; 2032 struct amdgpu_irq_src hpd_irq;
2033 2033
2034 /* rings */ 2034 /* rings */
2035 unsigned fence_context; 2035 u64 fence_context;
2036 unsigned num_rings; 2036 unsigned num_rings;
2037 struct amdgpu_ring *rings[AMDGPU_MAX_RINGS]; 2037 struct amdgpu_ring *rings[AMDGPU_MAX_RINGS];
2038 bool ib_pool_ready; 2038 bool ib_pool_ready;
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
index b0832da2ef7e..0b5f3accb1e4 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_display.c
@@ -240,7 +240,7 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc,
240 240
241 work->base = base; 241 work->base = base;
242 242
243 r = drm_vblank_get(crtc->dev, amdgpu_crtc->crtc_id); 243 r = drm_crtc_vblank_get(crtc);
244 if (r) { 244 if (r) {
245 DRM_ERROR("failed to get vblank before flip\n"); 245 DRM_ERROR("failed to get vblank before flip\n");
246 goto pflip_cleanup; 246 goto pflip_cleanup;
@@ -268,7 +268,7 @@ int amdgpu_crtc_page_flip(struct drm_crtc *crtc,
268 return 0; 268 return 0;
269 269
270vblank_cleanup: 270vblank_cleanup:
271 drm_vblank_put(crtc->dev, amdgpu_crtc->crtc_id); 271 drm_crtc_vblank_put(&amdgpu_crtc->base);
272 272
273pflip_cleanup: 273pflip_cleanup:
274 if (unlikely(amdgpu_bo_reserve(new_rbo, false) != 0)) { 274 if (unlikely(amdgpu_bo_reserve(new_rbo, false) != 0)) {
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
index 8bf84efafb04..b16366c2b4a0 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sa.c
@@ -427,7 +427,7 @@ void amdgpu_sa_bo_dump_debug_info(struct amdgpu_sa_manager *sa_manager,
427 soffset, eoffset, eoffset - soffset); 427 soffset, eoffset, eoffset - soffset);
428 428
429 if (i->fence) 429 if (i->fence)
430 seq_printf(m, " protected by 0x%08x on context %d", 430 seq_printf(m, " protected by 0x%08x on context %llu",
431 i->fence->seqno, i->fence->context); 431 i->fence->seqno, i->fence->context);
432 432
433 seq_printf(m, "\n"); 433 seq_printf(m, "\n");
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
index 8227344d2ff6..112e358f0f9b 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v10_0.c
@@ -2667,19 +2667,21 @@ static void dce_v10_0_cursor_reset(struct drm_crtc *crtc)
2667 } 2667 }
2668} 2668}
2669 2669
2670static void dce_v10_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, 2670static int dce_v10_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
2671 u16 *blue, uint32_t start, uint32_t size) 2671 u16 *blue, uint32_t size)
2672{ 2672{
2673 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 2673 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
2674 int end = (start + size > 256) ? 256 : start + size, i; 2674 int i;
2675 2675
2676 /* userspace palettes are always correct as is */ 2676 /* userspace palettes are always correct as is */
2677 for (i = start; i < end; i++) { 2677 for (i = 0; i < size; i++) {
2678 amdgpu_crtc->lut_r[i] = red[i] >> 6; 2678 amdgpu_crtc->lut_r[i] = red[i] >> 6;
2679 amdgpu_crtc->lut_g[i] = green[i] >> 6; 2679 amdgpu_crtc->lut_g[i] = green[i] >> 6;
2680 amdgpu_crtc->lut_b[i] = blue[i] >> 6; 2680 amdgpu_crtc->lut_b[i] = blue[i] >> 6;
2681 } 2681 }
2682 dce_v10_0_crtc_load_lut(crtc); 2682 dce_v10_0_crtc_load_lut(crtc);
2683
2684 return 0;
2683} 2685}
2684 2686
2685static void dce_v10_0_crtc_destroy(struct drm_crtc *crtc) 2687static void dce_v10_0_crtc_destroy(struct drm_crtc *crtc)
@@ -3372,7 +3374,7 @@ static int dce_v10_0_pageflip_irq(struct amdgpu_device *adev,
3372 3374
3373 spin_unlock_irqrestore(&adev->ddev->event_lock, flags); 3375 spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
3374 3376
3375 drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id); 3377 drm_crtc_vblank_put(&amdgpu_crtc->base);
3376 schedule_work(&works->unpin_work); 3378 schedule_work(&works->unpin_work);
3377 3379
3378 return 0; 3380 return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
index af26ec0bc59d..b522fa2435a8 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v11_0.c
@@ -2678,19 +2678,21 @@ static void dce_v11_0_cursor_reset(struct drm_crtc *crtc)
2678 } 2678 }
2679} 2679}
2680 2680
2681static void dce_v11_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, 2681static int dce_v11_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
2682 u16 *blue, uint32_t start, uint32_t size) 2682 u16 *blue, uint32_t size)
2683{ 2683{
2684 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 2684 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
2685 int end = (start + size > 256) ? 256 : start + size, i; 2685 int i;
2686 2686
2687 /* userspace palettes are always correct as is */ 2687 /* userspace palettes are always correct as is */
2688 for (i = start; i < end; i++) { 2688 for (i = 0; i < size; i++) {
2689 amdgpu_crtc->lut_r[i] = red[i] >> 6; 2689 amdgpu_crtc->lut_r[i] = red[i] >> 6;
2690 amdgpu_crtc->lut_g[i] = green[i] >> 6; 2690 amdgpu_crtc->lut_g[i] = green[i] >> 6;
2691 amdgpu_crtc->lut_b[i] = blue[i] >> 6; 2691 amdgpu_crtc->lut_b[i] = blue[i] >> 6;
2692 } 2692 }
2693 dce_v11_0_crtc_load_lut(crtc); 2693 dce_v11_0_crtc_load_lut(crtc);
2694
2695 return 0;
2694} 2696}
2695 2697
2696static void dce_v11_0_crtc_destroy(struct drm_crtc *crtc) 2698static void dce_v11_0_crtc_destroy(struct drm_crtc *crtc)
@@ -3433,7 +3435,7 @@ static int dce_v11_0_pageflip_irq(struct amdgpu_device *adev,
3433 3435
3434 spin_unlock_irqrestore(&adev->ddev->event_lock, flags); 3436 spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
3435 3437
3436 drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id); 3438 drm_crtc_vblank_put(&amdgpu_crtc->base);
3437 schedule_work(&works->unpin_work); 3439 schedule_work(&works->unpin_work);
3438 3440
3439 return 0; 3441 return 0;
diff --git a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
index 3fb65e41a6ef..b50ed72feedb 100644
--- a/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
+++ b/drivers/gpu/drm/amd/amdgpu/dce_v8_0.c
@@ -2574,19 +2574,21 @@ static void dce_v8_0_cursor_reset(struct drm_crtc *crtc)
2574 } 2574 }
2575} 2575}
2576 2576
2577static void dce_v8_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, 2577static int dce_v8_0_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
2578 u16 *blue, uint32_t start, uint32_t size) 2578 u16 *blue, uint32_t size)
2579{ 2579{
2580 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc); 2580 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
2581 int end = (start + size > 256) ? 256 : start + size, i; 2581 int i;
2582 2582
2583 /* userspace palettes are always correct as is */ 2583 /* userspace palettes are always correct as is */
2584 for (i = start; i < end; i++) { 2584 for (i = 0; i < size; i++) {
2585 amdgpu_crtc->lut_r[i] = red[i] >> 6; 2585 amdgpu_crtc->lut_r[i] = red[i] >> 6;
2586 amdgpu_crtc->lut_g[i] = green[i] >> 6; 2586 amdgpu_crtc->lut_g[i] = green[i] >> 6;
2587 amdgpu_crtc->lut_b[i] = blue[i] >> 6; 2587 amdgpu_crtc->lut_b[i] = blue[i] >> 6;
2588 } 2588 }
2589 dce_v8_0_crtc_load_lut(crtc); 2589 dce_v8_0_crtc_load_lut(crtc);
2590
2591 return 0;
2590} 2592}
2591 2593
2592static void dce_v8_0_crtc_destroy(struct drm_crtc *crtc) 2594static void dce_v8_0_crtc_destroy(struct drm_crtc *crtc)
@@ -3376,7 +3378,7 @@ static int dce_v8_0_pageflip_irq(struct amdgpu_device *adev,
3376 3378
3377 spin_unlock_irqrestore(&adev->ddev->event_lock, flags); 3379 spin_unlock_irqrestore(&adev->ddev->event_lock, flags);
3378 3380
3379 drm_vblank_put(adev->ddev, amdgpu_crtc->crtc_id); 3381 drm_crtc_vblank_put(&amdgpu_crtc->base);
3380 schedule_work(&works->unpin_work); 3382 schedule_work(&works->unpin_work);
3381 3383
3382 return 0; 3384 return 0;
diff --git a/drivers/gpu/drm/arc/arcpgu_drv.c b/drivers/gpu/drm/arc/arcpgu_drv.c
index bc53ebb83f75..7675bbc70133 100644
--- a/drivers/gpu/drm/arc/arcpgu_drv.c
+++ b/drivers/gpu/drm/arc/arcpgu_drv.c
@@ -92,7 +92,7 @@ static void arcpgu_preclose(struct drm_device *drm, struct drm_file *file)
92 if (e->base.file_priv != file) 92 if (e->base.file_priv != file)
93 continue; 93 continue;
94 list_del(&e->base.link); 94 list_del(&e->base.link);
95 e->base.destroy(&e->base); 95 kfree(&e->base);
96 } 96 }
97 spin_unlock_irqrestore(&drm->event_lock, flags); 97 spin_unlock_irqrestore(&drm->event_lock, flags);
98} 98}
diff --git a/drivers/gpu/drm/arm/hdlcd_crtc.c b/drivers/gpu/drm/arm/hdlcd_crtc.c
index 0813c2f06931..48019ae22ddb 100644
--- a/drivers/gpu/drm/arm/hdlcd_crtc.c
+++ b/drivers/gpu/drm/arm/hdlcd_crtc.c
@@ -196,30 +196,11 @@ static void hdlcd_crtc_atomic_begin(struct drm_crtc *crtc,
196 } 196 }
197} 197}
198 198
199static void hdlcd_crtc_atomic_flush(struct drm_crtc *crtc,
200 struct drm_crtc_state *state)
201{
202}
203
204static bool hdlcd_crtc_mode_fixup(struct drm_crtc *crtc,
205 const struct drm_display_mode *mode,
206 struct drm_display_mode *adjusted_mode)
207{
208 return true;
209}
210
211static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = { 199static const struct drm_crtc_helper_funcs hdlcd_crtc_helper_funcs = {
212 .mode_fixup = hdlcd_crtc_mode_fixup,
213 .mode_set = drm_helper_crtc_mode_set,
214 .mode_set_base = drm_helper_crtc_mode_set_base,
215 .mode_set_nofb = hdlcd_crtc_mode_set_nofb,
216 .enable = hdlcd_crtc_enable, 200 .enable = hdlcd_crtc_enable,
217 .disable = hdlcd_crtc_disable, 201 .disable = hdlcd_crtc_disable,
218 .prepare = hdlcd_crtc_disable,
219 .commit = hdlcd_crtc_enable,
220 .atomic_check = hdlcd_crtc_atomic_check, 202 .atomic_check = hdlcd_crtc_atomic_check,
221 .atomic_begin = hdlcd_crtc_atomic_begin, 203 .atomic_begin = hdlcd_crtc_atomic_begin,
222 .atomic_flush = hdlcd_crtc_atomic_flush,
223}; 204};
224 205
225static int hdlcd_plane_atomic_check(struct drm_plane *plane, 206static int hdlcd_plane_atomic_check(struct drm_plane *plane,
diff --git a/drivers/gpu/drm/armada/armada_crtc.c b/drivers/gpu/drm/armada/armada_crtc.c
index 3130aa8bcdd0..34405e4a5d36 100644
--- a/drivers/gpu/drm/armada/armada_crtc.c
+++ b/drivers/gpu/drm/armada/armada_crtc.c
@@ -199,7 +199,7 @@ static void armada_drm_plane_work_run(struct armada_crtc *dcrtc,
199 /* Handle any pending frame work. */ 199 /* Handle any pending frame work. */
200 if (work) { 200 if (work) {
201 work->fn(dcrtc, plane, work); 201 work->fn(dcrtc, plane, work);
202 drm_vblank_put(dcrtc->crtc.dev, dcrtc->num); 202 drm_crtc_vblank_put(&dcrtc->crtc);
203 } 203 }
204 204
205 wake_up(&plane->frame_wait); 205 wake_up(&plane->frame_wait);
@@ -210,7 +210,7 @@ int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
210{ 210{
211 int ret; 211 int ret;
212 212
213 ret = drm_vblank_get(dcrtc->crtc.dev, dcrtc->num); 213 ret = drm_crtc_vblank_get(&dcrtc->crtc);
214 if (ret) { 214 if (ret) {
215 DRM_ERROR("failed to acquire vblank counter\n"); 215 DRM_ERROR("failed to acquire vblank counter\n");
216 return ret; 216 return ret;
@@ -218,7 +218,7 @@ int armada_drm_plane_work_queue(struct armada_crtc *dcrtc,
218 218
219 ret = cmpxchg(&plane->work, NULL, work) ? -EBUSY : 0; 219 ret = cmpxchg(&plane->work, NULL, work) ? -EBUSY : 0;
220 if (ret) 220 if (ret)
221 drm_vblank_put(dcrtc->crtc.dev, dcrtc->num); 221 drm_crtc_vblank_put(&dcrtc->crtc);
222 222
223 return ret; 223 return ret;
224} 224}
@@ -234,7 +234,7 @@ struct armada_plane_work *armada_drm_plane_work_cancel(
234 struct armada_plane_work *work = xchg(&plane->work, NULL); 234 struct armada_plane_work *work = xchg(&plane->work, NULL);
235 235
236 if (work) 236 if (work)
237 drm_vblank_put(dcrtc->crtc.dev, dcrtc->num); 237 drm_crtc_vblank_put(&dcrtc->crtc);
238 238
239 return work; 239 return work;
240} 240}
@@ -260,7 +260,7 @@ static void armada_drm_crtc_complete_frame_work(struct armada_crtc *dcrtc,
260 260
261 if (fwork->event) { 261 if (fwork->event) {
262 spin_lock_irqsave(&dev->event_lock, flags); 262 spin_lock_irqsave(&dev->event_lock, flags);
263 drm_send_vblank_event(dev, dcrtc->num, fwork->event); 263 drm_crtc_send_vblank_event(&dcrtc->crtc, fwork->event);
264 spin_unlock_irqrestore(&dev->event_lock, flags); 264 spin_unlock_irqrestore(&dev->event_lock, flags);
265 } 265 }
266 266
@@ -592,9 +592,9 @@ static int armada_drm_crtc_mode_set(struct drm_crtc *crtc,
592 592
593 if (interlaced ^ dcrtc->interlaced) { 593 if (interlaced ^ dcrtc->interlaced) {
594 if (adj->flags & DRM_MODE_FLAG_INTERLACE) 594 if (adj->flags & DRM_MODE_FLAG_INTERLACE)
595 drm_vblank_get(dcrtc->crtc.dev, dcrtc->num); 595 drm_crtc_vblank_get(&dcrtc->crtc);
596 else 596 else
597 drm_vblank_put(dcrtc->crtc.dev, dcrtc->num); 597 drm_crtc_vblank_put(&dcrtc->crtc);
598 dcrtc->interlaced = interlaced; 598 dcrtc->interlaced = interlaced;
599 } 599 }
600 600
diff --git a/drivers/gpu/drm/ast/ast_fb.c b/drivers/gpu/drm/ast/ast_fb.c
index 5320f8c57884..c017a9330a18 100644
--- a/drivers/gpu/drm/ast/ast_fb.c
+++ b/drivers/gpu/drm/ast/ast_fb.c
@@ -167,12 +167,9 @@ static int astfb_create_object(struct ast_fbdev *afbdev,
167 struct drm_gem_object **gobj_p) 167 struct drm_gem_object **gobj_p)
168{ 168{
169 struct drm_device *dev = afbdev->helper.dev; 169 struct drm_device *dev = afbdev->helper.dev;
170 u32 bpp, depth;
171 u32 size; 170 u32 size;
172 struct drm_gem_object *gobj; 171 struct drm_gem_object *gobj;
173
174 int ret = 0; 172 int ret = 0;
175 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);
176 173
177 size = mode_cmd->pitches[0] * mode_cmd->height; 174 size = mode_cmd->pitches[0] * mode_cmd->height;
178 ret = ast_gem_create(dev, size, true, &gobj); 175 ret = ast_gem_create(dev, size, true, &gobj);
diff --git a/drivers/gpu/drm/ast/ast_mode.c b/drivers/gpu/drm/ast/ast_mode.c
index c337922606e3..5957c3e659fe 100644
--- a/drivers/gpu/drm/ast/ast_mode.c
+++ b/drivers/gpu/drm/ast/ast_mode.c
@@ -624,19 +624,21 @@ static void ast_crtc_reset(struct drm_crtc *crtc)
624 624
625} 625}
626 626
627static void ast_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, 627static int ast_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
628 u16 *blue, uint32_t start, uint32_t size) 628 u16 *blue, uint32_t size)
629{ 629{
630 struct ast_crtc *ast_crtc = to_ast_crtc(crtc); 630 struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
631 int end = (start + size > 256) ? 256 : start + size, i; 631 int i;
632 632
633 /* userspace palettes are always correct as is */ 633 /* userspace palettes are always correct as is */
634 for (i = start; i < end; i++) { 634 for (i = 0; i < size; i++) {
635 ast_crtc->lut_r[i] = red[i] >> 8; 635 ast_crtc->lut_r[i] = red[i] >> 8;
636 ast_crtc->lut_g[i] = green[i] >> 8; 636 ast_crtc->lut_g[i] = green[i] >> 8;
637 ast_crtc->lut_b[i] = blue[i] >> 8; 637 ast_crtc->lut_b[i] = blue[i] >> 8;
638 } 638 }
639 ast_crtc_load_lut(crtc); 639 ast_crtc_load_lut(crtc);
640
641 return 0;
640} 642}
641 643
642 644
diff --git a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
index bd12231ab0cd..613f6c99b76a 100644
--- a/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
+++ b/drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_crtc.c
@@ -374,8 +374,8 @@ static void atmel_hlcdc_crtc_finish_page_flip(struct atmel_hlcdc_crtc *crtc)
374 374
375 spin_lock_irqsave(&dev->event_lock, flags); 375 spin_lock_irqsave(&dev->event_lock, flags);
376 if (crtc->event) { 376 if (crtc->event) {
377 drm_send_vblank_event(dev, crtc->id, crtc->event); 377 drm_crtc_send_vblank_event(&crtc->base, crtc->event);
378 drm_vblank_put(dev, crtc->id); 378 drm_crtc_vblank_put(&crtc->base);
379 crtc->event = NULL; 379 crtc->event = NULL;
380 } 380 }
381 spin_unlock_irqrestore(&dev->event_lock, flags); 381 spin_unlock_irqrestore(&dev->event_lock, flags);
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index 0b1a411cb89e..17c915d9a03e 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -325,18 +325,20 @@ static void cirrus_crtc_commit(struct drm_crtc *crtc)
325 * use this for 8-bit mode so can't perform smooth fades on deeper modes, 325 * use this for 8-bit mode so can't perform smooth fades on deeper modes,
326 * but it's a requirement that we provide the function 326 * but it's a requirement that we provide the function
327 */ 327 */
328static void cirrus_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, 328static int cirrus_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
329 u16 *blue, uint32_t start, uint32_t size) 329 u16 *blue, uint32_t size)
330{ 330{
331 struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc); 331 struct cirrus_crtc *cirrus_crtc = to_cirrus_crtc(crtc);
332 int i; 332 int i;
333 333
334 for (i = 0; i < CIRRUS_LUT_SIZE; i++) { 334 for (i = 0; i < size; i++) {
335 cirrus_crtc->lut_r[i] = red[i]; 335 cirrus_crtc->lut_r[i] = red[i];
336 cirrus_crtc->lut_g[i] = green[i]; 336 cirrus_crtc->lut_g[i] = green[i];
337 cirrus_crtc->lut_b[i] = blue[i]; 337 cirrus_crtc->lut_b[i] = blue[i];
338 } 338 }
339 cirrus_crtc_load_lut(crtc); 339 cirrus_crtc_load_lut(crtc);
340
341 return 0;
340} 342}
341 343
342/* Simple cleanup function */ 344/* Simple cleanup function */
diff --git a/drivers/gpu/drm/drm_atomic.c b/drivers/gpu/drm/drm_atomic.c
index c204ef32df16..5e4b820a977c 100644
--- a/drivers/gpu/drm/drm_atomic.c
+++ b/drivers/gpu/drm/drm_atomic.c
@@ -44,11 +44,8 @@
44void drm_atomic_state_default_release(struct drm_atomic_state *state) 44void drm_atomic_state_default_release(struct drm_atomic_state *state)
45{ 45{
46 kfree(state->connectors); 46 kfree(state->connectors);
47 kfree(state->connector_states);
48 kfree(state->crtcs); 47 kfree(state->crtcs);
49 kfree(state->crtc_states);
50 kfree(state->planes); 48 kfree(state->planes);
51 kfree(state->plane_states);
52} 49}
53EXPORT_SYMBOL(drm_atomic_state_default_release); 50EXPORT_SYMBOL(drm_atomic_state_default_release);
54 51
@@ -72,18 +69,10 @@ drm_atomic_state_init(struct drm_device *dev, struct drm_atomic_state *state)
72 sizeof(*state->crtcs), GFP_KERNEL); 69 sizeof(*state->crtcs), GFP_KERNEL);
73 if (!state->crtcs) 70 if (!state->crtcs)
74 goto fail; 71 goto fail;
75 state->crtc_states = kcalloc(dev->mode_config.num_crtc,
76 sizeof(*state->crtc_states), GFP_KERNEL);
77 if (!state->crtc_states)
78 goto fail;
79 state->planes = kcalloc(dev->mode_config.num_total_plane, 72 state->planes = kcalloc(dev->mode_config.num_total_plane,
80 sizeof(*state->planes), GFP_KERNEL); 73 sizeof(*state->planes), GFP_KERNEL);
81 if (!state->planes) 74 if (!state->planes)
82 goto fail; 75 goto fail;
83 state->plane_states = kcalloc(dev->mode_config.num_total_plane,
84 sizeof(*state->plane_states), GFP_KERNEL);
85 if (!state->plane_states)
86 goto fail;
87 76
88 state->dev = dev; 77 state->dev = dev;
89 78
@@ -139,40 +128,40 @@ void drm_atomic_state_default_clear(struct drm_atomic_state *state)
139 DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state); 128 DRM_DEBUG_ATOMIC("Clearing atomic state %p\n", state);
140 129
141 for (i = 0; i < state->num_connector; i++) { 130 for (i = 0; i < state->num_connector; i++) {
142 struct drm_connector *connector = state->connectors[i]; 131 struct drm_connector *connector = state->connectors[i].ptr;
143 132
144 if (!connector) 133 if (!connector)
145 continue; 134 continue;
146 135
147 connector->funcs->atomic_destroy_state(connector, 136 connector->funcs->atomic_destroy_state(connector,
148 state->connector_states[i]); 137 state->connectors[i].state);
149 state->connectors[i] = NULL; 138 state->connectors[i].ptr = NULL;
150 state->connector_states[i] = NULL; 139 state->connectors[i].state = NULL;
151 drm_connector_unreference(connector); 140 drm_connector_unreference(connector);
152 } 141 }
153 142
154 for (i = 0; i < config->num_crtc; i++) { 143 for (i = 0; i < config->num_crtc; i++) {
155 struct drm_crtc *crtc = state->crtcs[i]; 144 struct drm_crtc *crtc = state->crtcs[i].ptr;
156 145
157 if (!crtc) 146 if (!crtc)
158 continue; 147 continue;
159 148
160 crtc->funcs->atomic_destroy_state(crtc, 149 crtc->funcs->atomic_destroy_state(crtc,
161 state->crtc_states[i]); 150 state->crtcs[i].state);
162 state->crtcs[i] = NULL; 151 state->crtcs[i].ptr = NULL;
163 state->crtc_states[i] = NULL; 152 state->crtcs[i].state = NULL;
164 } 153 }
165 154
166 for (i = 0; i < config->num_total_plane; i++) { 155 for (i = 0; i < config->num_total_plane; i++) {
167 struct drm_plane *plane = state->planes[i]; 156 struct drm_plane *plane = state->planes[i].ptr;
168 157
169 if (!plane) 158 if (!plane)
170 continue; 159 continue;
171 160
172 plane->funcs->atomic_destroy_state(plane, 161 plane->funcs->atomic_destroy_state(plane,
173 state->plane_states[i]); 162 state->planes[i].state);
174 state->planes[i] = NULL; 163 state->planes[i].ptr = NULL;
175 state->plane_states[i] = NULL; 164 state->planes[i].state = NULL;
176 } 165 }
177} 166}
178EXPORT_SYMBOL(drm_atomic_state_default_clear); 167EXPORT_SYMBOL(drm_atomic_state_default_clear);
@@ -270,8 +259,8 @@ drm_atomic_get_crtc_state(struct drm_atomic_state *state,
270 if (!crtc_state) 259 if (!crtc_state)
271 return ERR_PTR(-ENOMEM); 260 return ERR_PTR(-ENOMEM);
272 261
273 state->crtc_states[index] = crtc_state; 262 state->crtcs[index].state = crtc_state;
274 state->crtcs[index] = crtc; 263 state->crtcs[index].ptr = crtc;
275 crtc_state->state = state; 264 crtc_state->state = state;
276 265
277 DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n", 266 DRM_DEBUG_ATOMIC("Added [CRTC:%d:%s] %p state to %p\n",
@@ -632,8 +621,8 @@ drm_atomic_get_plane_state(struct drm_atomic_state *state,
632 if (!plane_state) 621 if (!plane_state)
633 return ERR_PTR(-ENOMEM); 622 return ERR_PTR(-ENOMEM);
634 623
635 state->plane_states[index] = plane_state; 624 state->planes[index].state = plane_state;
636 state->planes[index] = plane; 625 state->planes[index].ptr = plane;
637 plane_state->state = state; 626 plane_state->state = state;
638 627
639 DRM_DEBUG_ATOMIC("Added [PLANE:%d:%s] %p state to %p\n", 628 DRM_DEBUG_ATOMIC("Added [PLANE:%d:%s] %p state to %p\n",
@@ -897,8 +886,7 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state,
897 index = drm_connector_index(connector); 886 index = drm_connector_index(connector);
898 887
899 if (index >= state->num_connector) { 888 if (index >= state->num_connector) {
900 struct drm_connector **c; 889 struct __drm_connnectors_state *c;
901 struct drm_connector_state **cs;
902 int alloc = max(index + 1, config->num_connector); 890 int alloc = max(index + 1, config->num_connector);
903 891
904 c = krealloc(state->connectors, alloc * sizeof(*state->connectors), GFP_KERNEL); 892 c = krealloc(state->connectors, alloc * sizeof(*state->connectors), GFP_KERNEL);
@@ -909,26 +897,19 @@ drm_atomic_get_connector_state(struct drm_atomic_state *state,
909 memset(&state->connectors[state->num_connector], 0, 897 memset(&state->connectors[state->num_connector], 0,
910 sizeof(*state->connectors) * (alloc - state->num_connector)); 898 sizeof(*state->connectors) * (alloc - state->num_connector));
911 899
912 cs = krealloc(state->connector_states, alloc * sizeof(*state->connector_states), GFP_KERNEL);
913 if (!cs)
914 return ERR_PTR(-ENOMEM);
915
916 state->connector_states = cs;
917 memset(&state->connector_states[state->num_connector], 0,
918 sizeof(*state->connector_states) * (alloc - state->num_connector));
919 state->num_connector = alloc; 900 state->num_connector = alloc;
920 } 901 }
921 902
922 if (state->connector_states[index]) 903 if (state->connectors[index].state)
923 return state->connector_states[index]; 904 return state->connectors[index].state;
924 905
925 connector_state = connector->funcs->atomic_duplicate_state(connector); 906 connector_state = connector->funcs->atomic_duplicate_state(connector);
926 if (!connector_state) 907 if (!connector_state)
927 return ERR_PTR(-ENOMEM); 908 return ERR_PTR(-ENOMEM);
928 909
929 drm_connector_reference(connector); 910 drm_connector_reference(connector);
930 state->connector_states[index] = connector_state; 911 state->connectors[index].state = connector_state;
931 state->connectors[index] = connector; 912 state->connectors[index].ptr = connector;
932 connector_state->state = state; 913 connector_state->state = state;
933 914
934 DRM_DEBUG_ATOMIC("Added [CONNECTOR:%d] %p state to %p\n", 915 DRM_DEBUG_ATOMIC("Added [CONNECTOR:%d] %p state to %p\n",
@@ -1432,7 +1413,8 @@ EXPORT_SYMBOL(drm_atomic_nonblocking_commit);
1432 */ 1413 */
1433 1414
1434static struct drm_pending_vblank_event *create_vblank_event( 1415static struct drm_pending_vblank_event *create_vblank_event(
1435 struct drm_device *dev, struct drm_file *file_priv, uint64_t user_data) 1416 struct drm_device *dev, struct drm_file *file_priv,
1417 struct fence *fence, uint64_t user_data)
1436{ 1418{
1437 struct drm_pending_vblank_event *e = NULL; 1419 struct drm_pending_vblank_event *e = NULL;
1438 int ret; 1420 int ret;
@@ -1445,12 +1427,17 @@ static struct drm_pending_vblank_event *create_vblank_event(
1445 e->event.base.length = sizeof(e->event); 1427 e->event.base.length = sizeof(e->event);
1446 e->event.user_data = user_data; 1428 e->event.user_data = user_data;
1447 1429
1448 ret = drm_event_reserve_init(dev, file_priv, &e->base, &e->event.base); 1430 if (file_priv) {
1449 if (ret) { 1431 ret = drm_event_reserve_init(dev, file_priv, &e->base,
1450 kfree(e); 1432 &e->event.base);
1451 return NULL; 1433 if (ret) {
1434 kfree(e);
1435 return NULL;
1436 }
1452 } 1437 }
1453 1438
1439 e->base.fence = fence;
1440
1454 return e; 1441 return e;
1455} 1442}
1456 1443
@@ -1690,7 +1677,8 @@ retry:
1690 for_each_crtc_in_state(state, crtc, crtc_state, i) { 1677 for_each_crtc_in_state(state, crtc, crtc_state, i) {
1691 struct drm_pending_vblank_event *e; 1678 struct drm_pending_vblank_event *e;
1692 1679
1693 e = create_vblank_event(dev, file_priv, arg->user_data); 1680 e = create_vblank_event(dev, file_priv, NULL,
1681 arg->user_data);
1694 if (!e) { 1682 if (!e) {
1695 ret = -ENOMEM; 1683 ret = -ENOMEM;
1696 goto out; 1684 goto out;
diff --git a/drivers/gpu/drm/drm_atomic_helper.c b/drivers/gpu/drm/drm_atomic_helper.c
index 939df900dcaa..bb98d74d1a2e 100644
--- a/drivers/gpu/drm/drm_atomic_helper.c
+++ b/drivers/gpu/drm/drm_atomic_helper.c
@@ -110,8 +110,10 @@ static int handle_conflicting_encoders(struct drm_atomic_state *state,
110 110
111 if (funcs->atomic_best_encoder) 111 if (funcs->atomic_best_encoder)
112 new_encoder = funcs->atomic_best_encoder(connector, conn_state); 112 new_encoder = funcs->atomic_best_encoder(connector, conn_state);
113 else 113 else if (funcs->best_encoder)
114 new_encoder = funcs->best_encoder(connector); 114 new_encoder = funcs->best_encoder(connector);
115 else
116 new_encoder = drm_atomic_helper_best_encoder(connector);
115 117
116 if (new_encoder) { 118 if (new_encoder) {
117 if (encoder_mask & (1 << drm_encoder_index(new_encoder))) { 119 if (encoder_mask & (1 << drm_encoder_index(new_encoder))) {
@@ -298,8 +300,10 @@ update_connector_routing(struct drm_atomic_state *state,
298 if (funcs->atomic_best_encoder) 300 if (funcs->atomic_best_encoder)
299 new_encoder = funcs->atomic_best_encoder(connector, 301 new_encoder = funcs->atomic_best_encoder(connector,
300 connector_state); 302 connector_state);
301 else 303 else if (funcs->best_encoder)
302 new_encoder = funcs->best_encoder(connector); 304 new_encoder = funcs->best_encoder(connector);
305 else
306 new_encoder = drm_atomic_helper_best_encoder(connector);
303 307
304 if (!new_encoder) { 308 if (!new_encoder) {
305 DRM_DEBUG_ATOMIC("No suitable encoder found for [CONNECTOR:%d:%s]\n", 309 DRM_DEBUG_ATOMIC("No suitable encoder found for [CONNECTOR:%d:%s]\n",
@@ -614,7 +618,7 @@ drm_atomic_helper_check_planes(struct drm_device *dev,
614 if (!funcs || !funcs->atomic_check) 618 if (!funcs || !funcs->atomic_check)
615 continue; 619 continue;
616 620
617 ret = funcs->atomic_check(crtc, state->crtc_states[i]); 621 ret = funcs->atomic_check(crtc, crtc_state);
618 if (ret) { 622 if (ret) {
619 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic driver check failed\n", 623 DRM_DEBUG_ATOMIC("[CRTC:%d:%s] atomic driver check failed\n",
620 crtc->base.id, crtc->name); 624 crtc->base.id, crtc->name);
@@ -1252,16 +1256,12 @@ EXPORT_SYMBOL(drm_atomic_helper_commit);
1252int drm_atomic_helper_prepare_planes(struct drm_device *dev, 1256int drm_atomic_helper_prepare_planes(struct drm_device *dev,
1253 struct drm_atomic_state *state) 1257 struct drm_atomic_state *state)
1254{ 1258{
1255 int nplanes = dev->mode_config.num_total_plane; 1259 struct drm_plane *plane;
1256 int ret, i; 1260 struct drm_plane_state *plane_state;
1261 int ret, i, j;
1257 1262
1258 for (i = 0; i < nplanes; i++) { 1263 for_each_plane_in_state(state, plane, plane_state, i) {
1259 const struct drm_plane_helper_funcs *funcs; 1264 const struct drm_plane_helper_funcs *funcs;
1260 struct drm_plane *plane = state->planes[i];
1261 struct drm_plane_state *plane_state = state->plane_states[i];
1262
1263 if (!plane)
1264 continue;
1265 1265
1266 funcs = plane->helper_private; 1266 funcs = plane->helper_private;
1267 1267
@@ -1275,12 +1275,10 @@ int drm_atomic_helper_prepare_planes(struct drm_device *dev,
1275 return 0; 1275 return 0;
1276 1276
1277fail: 1277fail:
1278 for (i--; i >= 0; i--) { 1278 for_each_plane_in_state(state, plane, plane_state, j) {
1279 const struct drm_plane_helper_funcs *funcs; 1279 const struct drm_plane_helper_funcs *funcs;
1280 struct drm_plane *plane = state->planes[i];
1281 struct drm_plane_state *plane_state = state->plane_states[i];
1282 1280
1283 if (!plane) 1281 if (j >= i)
1284 continue; 1282 continue;
1285 1283
1286 funcs = plane->helper_private; 1284 funcs = plane->helper_private;
@@ -1567,37 +1565,28 @@ void drm_atomic_helper_swap_state(struct drm_device *dev,
1567 struct drm_atomic_state *state) 1565 struct drm_atomic_state *state)
1568{ 1566{
1569 int i; 1567 int i;
1568 struct drm_connector *connector;
1569 struct drm_connector_state *conn_state;
1570 struct drm_crtc *crtc;
1571 struct drm_crtc_state *crtc_state;
1572 struct drm_plane *plane;
1573 struct drm_plane_state *plane_state;
1570 1574
1571 for (i = 0; i < state->num_connector; i++) { 1575 for_each_connector_in_state(state, connector, conn_state, i) {
1572 struct drm_connector *connector = state->connectors[i];
1573
1574 if (!connector)
1575 continue;
1576
1577 connector->state->state = state; 1576 connector->state->state = state;
1578 swap(state->connector_states[i], connector->state); 1577 swap(state->connectors[i].state, connector->state);
1579 connector->state->state = NULL; 1578 connector->state->state = NULL;
1580 } 1579 }
1581 1580
1582 for (i = 0; i < dev->mode_config.num_crtc; i++) { 1581 for_each_crtc_in_state(state, crtc, crtc_state, i) {
1583 struct drm_crtc *crtc = state->crtcs[i];
1584
1585 if (!crtc)
1586 continue;
1587
1588 crtc->state->state = state; 1582 crtc->state->state = state;
1589 swap(state->crtc_states[i], crtc->state); 1583 swap(state->crtcs[i].state, crtc->state);
1590 crtc->state->state = NULL; 1584 crtc->state->state = NULL;
1591 } 1585 }
1592 1586
1593 for (i = 0; i < dev->mode_config.num_total_plane; i++) { 1587 for_each_plane_in_state(state, plane, plane_state, i) {
1594 struct drm_plane *plane = state->planes[i];
1595
1596 if (!plane)
1597 continue;
1598
1599 plane->state->state = state; 1588 plane->state->state = state;
1600 swap(state->plane_states[i], plane->state); 1589 swap(state->planes[i].state, plane->state);
1601 plane->state->state = NULL; 1590 plane->state->state = NULL;
1602 } 1591 }
1603} 1592}
@@ -2412,7 +2401,7 @@ EXPORT_SYMBOL(drm_atomic_helper_page_flip);
2412 * This is the main helper function provided by the atomic helper framework for 2401 * This is the main helper function provided by the atomic helper framework for
2413 * implementing the legacy DPMS connector interface. It computes the new desired 2402 * implementing the legacy DPMS connector interface. It computes the new desired
2414 * ->active state for the corresponding CRTC (if the connector is enabled) and 2403 * ->active state for the corresponding CRTC (if the connector is enabled) and
2415 * updates it. 2404 * updates it.
2416 * 2405 *
2417 * Returns: 2406 * Returns:
2418 * Returns 0 on success, negative errno numbers on failure. 2407 * Returns 0 on success, negative errno numbers on failure.
@@ -2933,16 +2922,15 @@ EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
2933 * @red: red correction table 2922 * @red: red correction table
2934 * @green: green correction table 2923 * @green: green correction table
2935 * @blue: green correction table 2924 * @blue: green correction table
2936 * @start:
2937 * @size: size of the tables 2925 * @size: size of the tables
2938 * 2926 *
2939 * Implements support for legacy gamma correction table for drivers 2927 * Implements support for legacy gamma correction table for drivers
2940 * that support color management through the DEGAMMA_LUT/GAMMA_LUT 2928 * that support color management through the DEGAMMA_LUT/GAMMA_LUT
2941 * properties. 2929 * properties.
2942 */ 2930 */
2943void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, 2931int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
2944 u16 *red, u16 *green, u16 *blue, 2932 u16 *red, u16 *green, u16 *blue,
2945 uint32_t start, uint32_t size) 2933 uint32_t size)
2946{ 2934{
2947 struct drm_device *dev = crtc->dev; 2935 struct drm_device *dev = crtc->dev;
2948 struct drm_mode_config *config = &dev->mode_config; 2936 struct drm_mode_config *config = &dev->mode_config;
@@ -2954,7 +2942,7 @@ void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
2954 2942
2955 state = drm_atomic_state_alloc(crtc->dev); 2943 state = drm_atomic_state_alloc(crtc->dev);
2956 if (!state) 2944 if (!state)
2957 return; 2945 return -ENOMEM;
2958 2946
2959 blob = drm_property_create_blob(dev, 2947 blob = drm_property_create_blob(dev,
2960 sizeof(struct drm_color_lut) * size, 2948 sizeof(struct drm_color_lut) * size,
@@ -3005,7 +2993,7 @@ retry:
3005 2993
3006 drm_property_unreference_blob(blob); 2994 drm_property_unreference_blob(blob);
3007 2995
3008 return; 2996 return 0;
3009fail: 2997fail:
3010 if (ret == -EDEADLK) 2998 if (ret == -EDEADLK)
3011 goto backoff; 2999 goto backoff;
@@ -3013,7 +3001,7 @@ fail:
3013 drm_atomic_state_free(state); 3001 drm_atomic_state_free(state);
3014 drm_property_unreference_blob(blob); 3002 drm_property_unreference_blob(blob);
3015 3003
3016 return; 3004 return ret;
3017backoff: 3005backoff:
3018 drm_atomic_state_clear(state); 3006 drm_atomic_state_clear(state);
3019 drm_atomic_legacy_backoff(state); 3007 drm_atomic_legacy_backoff(state);
diff --git a/drivers/gpu/drm/drm_bridge.c b/drivers/gpu/drm/drm_bridge.c
index b3654404abd0..255543086590 100644
--- a/drivers/gpu/drm/drm_bridge.c
+++ b/drivers/gpu/drm/drm_bridge.c
@@ -36,7 +36,7 @@
36 * encoder chain. 36 * encoder chain.
37 * 37 *
38 * A bridge is always attached to a single &drm_encoder at a time, but can be 38 * A bridge is always attached to a single &drm_encoder at a time, but can be
39 * either connected to it directly, or through an intermediate bridge: 39 * either connected to it directly, or through an intermediate bridge::
40 * 40 *
41 * encoder ---> bridge B ---> bridge A 41 * encoder ---> bridge B ---> bridge A
42 * 42 *
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c
index 1e28eeefcd65..da2f28ea5fad 100644
--- a/drivers/gpu/drm/drm_crtc.c
+++ b/drivers/gpu/drm/drm_crtc.c
@@ -535,7 +535,7 @@ EXPORT_SYMBOL(drm_framebuffer_unregister_private);
535 * 535 *
536 * Cleanup framebuffer. This function is intended to be used from the drivers 536 * Cleanup framebuffer. This function is intended to be used from the drivers
537 * ->destroy callback. It can also be used to clean up driver private 537 * ->destroy callback. It can also be used to clean up driver private
538 * framebuffers embedded into a larger structure. 538 * framebuffers embedded into a larger structure.
539 * 539 *
540 * Note that this function does not remove the fb from active usuage - if it is 540 * Note that this function does not remove the fb from active usuage - if it is
541 * still used anywhere, hilarity can ensue since userspace could call getfb on 541 * still used anywhere, hilarity can ensue since userspace could call getfb on
@@ -692,7 +692,7 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc,
692 crtc->base.properties = &crtc->properties; 692 crtc->base.properties = &crtc->properties;
693 693
694 list_add_tail(&crtc->head, &config->crtc_list); 694 list_add_tail(&crtc->head, &config->crtc_list);
695 config->num_crtc++; 695 crtc->index = config->num_crtc++;
696 696
697 crtc->primary = primary; 697 crtc->primary = primary;
698 crtc->cursor = cursor; 698 crtc->cursor = cursor;
@@ -722,6 +722,11 @@ void drm_crtc_cleanup(struct drm_crtc *crtc)
722{ 722{
723 struct drm_device *dev = crtc->dev; 723 struct drm_device *dev = crtc->dev;
724 724
725 /* Note that the crtc_list is considered to be static; should we
726 * remove the drm_crtc at runtime we would have to decrement all
727 * the indices on the drm_crtc after us in the crtc_list.
728 */
729
725 kfree(crtc->gamma_store); 730 kfree(crtc->gamma_store);
726 crtc->gamma_store = NULL; 731 crtc->gamma_store = NULL;
727 732
@@ -741,29 +746,6 @@ void drm_crtc_cleanup(struct drm_crtc *crtc)
741} 746}
742EXPORT_SYMBOL(drm_crtc_cleanup); 747EXPORT_SYMBOL(drm_crtc_cleanup);
743 748
744/**
745 * drm_crtc_index - find the index of a registered CRTC
746 * @crtc: CRTC to find index for
747 *
748 * Given a registered CRTC, return the index of that CRTC within a DRM
749 * device's list of CRTCs.
750 */
751unsigned int drm_crtc_index(struct drm_crtc *crtc)
752{
753 unsigned int index = 0;
754 struct drm_crtc *tmp;
755
756 drm_for_each_crtc(tmp, crtc->dev) {
757 if (tmp == crtc)
758 return index;
759
760 index++;
761 }
762
763 BUG();
764}
765EXPORT_SYMBOL(drm_crtc_index);
766
767/* 749/*
768 * drm_mode_remove - remove and free a mode 750 * drm_mode_remove - remove and free a mode
769 * @connector: connector list to modify 751 * @connector: connector list to modify
@@ -1166,7 +1148,7 @@ int drm_encoder_init(struct drm_device *dev,
1166 } 1148 }
1167 1149
1168 list_add_tail(&encoder->head, &dev->mode_config.encoder_list); 1150 list_add_tail(&encoder->head, &dev->mode_config.encoder_list);
1169 dev->mode_config.num_encoder++; 1151 encoder->index = dev->mode_config.num_encoder++;
1170 1152
1171out_put: 1153out_put:
1172 if (ret) 1154 if (ret)
@@ -1180,29 +1162,6 @@ out_unlock:
1180EXPORT_SYMBOL(drm_encoder_init); 1162EXPORT_SYMBOL(drm_encoder_init);
1181 1163
1182/** 1164/**
1183 * drm_encoder_index - find the index of a registered encoder
1184 * @encoder: encoder to find index for
1185 *
1186 * Given a registered encoder, return the index of that encoder within a DRM
1187 * device's list of encoders.
1188 */
1189unsigned int drm_encoder_index(struct drm_encoder *encoder)
1190{
1191 unsigned int index = 0;
1192 struct drm_encoder *tmp;
1193
1194 drm_for_each_encoder(tmp, encoder->dev) {
1195 if (tmp == encoder)
1196 return index;
1197
1198 index++;
1199 }
1200
1201 BUG();
1202}
1203EXPORT_SYMBOL(drm_encoder_index);
1204
1205/**
1206 * drm_encoder_cleanup - cleans up an initialised encoder 1165 * drm_encoder_cleanup - cleans up an initialised encoder
1207 * @encoder: encoder to cleanup 1166 * @encoder: encoder to cleanup
1208 * 1167 *
@@ -1212,6 +1171,11 @@ void drm_encoder_cleanup(struct drm_encoder *encoder)
1212{ 1171{
1213 struct drm_device *dev = encoder->dev; 1172 struct drm_device *dev = encoder->dev;
1214 1173
1174 /* Note that the encoder_list is considered to be static; should we
1175 * remove the drm_encoder at runtime we would have to decrement all
1176 * the indices on the drm_encoder after us in the encoder_list.
1177 */
1178
1215 drm_modeset_lock_all(dev); 1179 drm_modeset_lock_all(dev);
1216 drm_mode_object_unregister(dev, &encoder->base); 1180 drm_mode_object_unregister(dev, &encoder->base);
1217 kfree(encoder->name); 1181 kfree(encoder->name);
@@ -1300,7 +1264,7 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane,
1300 plane->type = type; 1264 plane->type = type;
1301 1265
1302 list_add_tail(&plane->head, &config->plane_list); 1266 list_add_tail(&plane->head, &config->plane_list);
1303 config->num_total_plane++; 1267 plane->index = config->num_total_plane++;
1304 if (plane->type == DRM_PLANE_TYPE_OVERLAY) 1268 if (plane->type == DRM_PLANE_TYPE_OVERLAY)
1305 config->num_overlay_plane++; 1269 config->num_overlay_plane++;
1306 1270
@@ -1374,6 +1338,11 @@ void drm_plane_cleanup(struct drm_plane *plane)
1374 1338
1375 BUG_ON(list_empty(&plane->head)); 1339 BUG_ON(list_empty(&plane->head));
1376 1340
1341 /* Note that the plane_list is considered to be static; should we
1342 * remove the drm_plane at runtime we would have to decrement all
1343 * the indices on the drm_plane after us in the plane_list.
1344 */
1345
1377 list_del(&plane->head); 1346 list_del(&plane->head);
1378 dev->mode_config.num_total_plane--; 1347 dev->mode_config.num_total_plane--;
1379 if (plane->type == DRM_PLANE_TYPE_OVERLAY) 1348 if (plane->type == DRM_PLANE_TYPE_OVERLAY)
@@ -1391,29 +1360,6 @@ void drm_plane_cleanup(struct drm_plane *plane)
1391EXPORT_SYMBOL(drm_plane_cleanup); 1360EXPORT_SYMBOL(drm_plane_cleanup);
1392 1361
1393/** 1362/**
1394 * drm_plane_index - find the index of a registered plane
1395 * @plane: plane to find index for
1396 *
1397 * Given a registered plane, return the index of that CRTC within a DRM
1398 * device's list of planes.
1399 */
1400unsigned int drm_plane_index(struct drm_plane *plane)
1401{
1402 unsigned int index = 0;
1403 struct drm_plane *tmp;
1404
1405 drm_for_each_plane(tmp, plane->dev) {
1406 if (tmp == plane)
1407 return index;
1408
1409 index++;
1410 }
1411
1412 BUG();
1413}
1414EXPORT_SYMBOL(drm_plane_index);
1415
1416/**
1417 * drm_plane_from_index - find the registered plane at an index 1363 * drm_plane_from_index - find the registered plane at an index
1418 * @dev: DRM device 1364 * @dev: DRM device
1419 * @idx: index of registered plane to find for 1365 * @idx: index of registered plane to find for
@@ -1425,13 +1371,11 @@ struct drm_plane *
1425drm_plane_from_index(struct drm_device *dev, int idx) 1371drm_plane_from_index(struct drm_device *dev, int idx)
1426{ 1372{
1427 struct drm_plane *plane; 1373 struct drm_plane *plane;
1428 unsigned int i = 0;
1429 1374
1430 drm_for_each_plane(plane, dev) { 1375 drm_for_each_plane(plane, dev)
1431 if (i == idx) 1376 if (idx == plane->index)
1432 return plane; 1377 return plane;
1433 i++; 1378
1434 }
1435 return NULL; 1379 return NULL;
1436} 1380}
1437EXPORT_SYMBOL(drm_plane_from_index); 1381EXPORT_SYMBOL(drm_plane_from_index);
@@ -5227,7 +5171,7 @@ int drm_mode_gamma_set_ioctl(struct drm_device *dev,
5227 goto out; 5171 goto out;
5228 } 5172 }
5229 5173
5230 crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size); 5174 ret = crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, crtc->gamma_size);
5231 5175
5232out: 5176out:
5233 drm_modeset_unlock_all(dev); 5177 drm_modeset_unlock_all(dev);
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c
index 5075fae3c4e2..2e7ef0b325e2 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -23,6 +23,7 @@
23#include <drm/drm_crtc_helper.h> 23#include <drm/drm_crtc_helper.h>
24#include <drm/drm_gem_cma_helper.h> 24#include <drm/drm_gem_cma_helper.h>
25#include <drm/drm_fb_cma_helper.h> 25#include <drm/drm_fb_cma_helper.h>
26#include <linux/dma-mapping.h>
26#include <linux/module.h> 27#include <linux/module.h>
27 28
28#define DEFAULT_FBDEFIO_DELAY_MS 50 29#define DEFAULT_FBDEFIO_DELAY_MS 50
@@ -52,7 +53,7 @@ struct drm_fbdev_cma {
52 * will be set up automatically. dirty() is called by 53 * will be set up automatically. dirty() is called by
53 * drm_fb_helper_deferred_io() in process context (struct delayed_work). 54 * drm_fb_helper_deferred_io() in process context (struct delayed_work).
54 * 55 *
55 * Example fbdev deferred io code: 56 * Example fbdev deferred io code::
56 * 57 *
57 * static int driver_fbdev_fb_dirty(struct drm_framebuffer *fb, 58 * static int driver_fbdev_fb_dirty(struct drm_framebuffer *fb,
58 * struct drm_file *file_priv, 59 * struct drm_file *file_priv,
@@ -162,6 +163,10 @@ static struct drm_fb_cma *drm_fb_cma_alloc(struct drm_device *dev,
162 * drm_fb_cma_create_with_funcs() - helper function for the 163 * drm_fb_cma_create_with_funcs() - helper function for the
163 * &drm_mode_config_funcs ->fb_create 164 * &drm_mode_config_funcs ->fb_create
164 * callback function 165 * callback function
166 * @dev: DRM device
167 * @file_priv: drm file for the ioctl call
168 * @mode_cmd: metadata from the userspace fb creation request
169 * @funcs: vtable to be used for the new framebuffer object
165 * 170 *
166 * This can be used to set &drm_framebuffer_funcs for drivers that need the 171 * This can be used to set &drm_framebuffer_funcs for drivers that need the
167 * dirty() callback. Use drm_fb_cma_create() if you don't need to change 172 * dirty() callback. Use drm_fb_cma_create() if you don't need to change
@@ -223,6 +228,9 @@ EXPORT_SYMBOL_GPL(drm_fb_cma_create_with_funcs);
223 228
224/** 229/**
225 * drm_fb_cma_create() - &drm_mode_config_funcs ->fb_create callback function 230 * drm_fb_cma_create() - &drm_mode_config_funcs ->fb_create callback function
231 * @dev: DRM device
232 * @file_priv: drm file for the ioctl call
233 * @mode_cmd: metadata from the userspace fb creation request
226 * 234 *
227 * If your hardware has special alignment or pitch requirements these should be 235 * If your hardware has special alignment or pitch requirements these should be
228 * checked before calling this function. Use drm_fb_cma_create_with_funcs() if 236 * checked before calling this function. Use drm_fb_cma_create_with_funcs() if
@@ -246,7 +254,7 @@ EXPORT_SYMBOL_GPL(drm_fb_cma_create);
246 * This function will usually be called from the CRTC callback functions. 254 * This function will usually be called from the CRTC callback functions.
247 */ 255 */
248struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb, 256struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb,
249 unsigned int plane) 257 unsigned int plane)
250{ 258{
251 struct drm_fb_cma *fb_cma = to_fb_cma(fb); 259 struct drm_fb_cma *fb_cma = to_fb_cma(fb);
252 260
@@ -258,10 +266,6 @@ struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb,
258EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj); 266EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj);
259 267
260#ifdef CONFIG_DEBUG_FS 268#ifdef CONFIG_DEBUG_FS
261/*
262 * drm_fb_cma_describe() - Helper to dump information about a single
263 * CMA framebuffer object
264 */
265static void drm_fb_cma_describe(struct drm_framebuffer *fb, struct seq_file *m) 269static void drm_fb_cma_describe(struct drm_framebuffer *fb, struct seq_file *m)
266{ 270{
267 struct drm_fb_cma *fb_cma = to_fb_cma(fb); 271 struct drm_fb_cma *fb_cma = to_fb_cma(fb);
@@ -279,7 +283,9 @@ static void drm_fb_cma_describe(struct drm_framebuffer *fb, struct seq_file *m)
279 283
280/** 284/**
281 * drm_fb_cma_debugfs_show() - Helper to list CMA framebuffer objects 285 * drm_fb_cma_debugfs_show() - Helper to list CMA framebuffer objects
282 * in debugfs. 286 * in debugfs.
287 * @m: output file
288 * @arg: private data for the callback
283 */ 289 */
284int drm_fb_cma_debugfs_show(struct seq_file *m, void *arg) 290int drm_fb_cma_debugfs_show(struct seq_file *m, void *arg)
285{ 291{
@@ -297,6 +303,12 @@ int drm_fb_cma_debugfs_show(struct seq_file *m, void *arg)
297EXPORT_SYMBOL_GPL(drm_fb_cma_debugfs_show); 303EXPORT_SYMBOL_GPL(drm_fb_cma_debugfs_show);
298#endif 304#endif
299 305
306static int drm_fb_cma_mmap(struct fb_info *info, struct vm_area_struct *vma)
307{
308 return dma_mmap_writecombine(info->device, vma, info->screen_base,
309 info->fix.smem_start, info->fix.smem_len);
310}
311
300static struct fb_ops drm_fbdev_cma_ops = { 312static struct fb_ops drm_fbdev_cma_ops = {
301 .owner = THIS_MODULE, 313 .owner = THIS_MODULE,
302 .fb_fillrect = drm_fb_helper_sys_fillrect, 314 .fb_fillrect = drm_fb_helper_sys_fillrect,
@@ -307,6 +319,7 @@ static struct fb_ops drm_fbdev_cma_ops = {
307 .fb_blank = drm_fb_helper_blank, 319 .fb_blank = drm_fb_helper_blank,
308 .fb_pan_display = drm_fb_helper_pan_display, 320 .fb_pan_display = drm_fb_helper_pan_display,
309 .fb_setcmap = drm_fb_helper_setcmap, 321 .fb_setcmap = drm_fb_helper_setcmap,
322 .fb_mmap = drm_fb_cma_mmap,
310}; 323};
311 324
312static int drm_fbdev_cma_deferred_io_mmap(struct fb_info *info, 325static int drm_fbdev_cma_deferred_io_mmap(struct fb_info *info,
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 7590df5e2e72..ba5aac7276e4 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -227,7 +227,7 @@ static void drm_fb_helper_restore_lut_atomic(struct drm_crtc *crtc)
227 g_base = r_base + crtc->gamma_size; 227 g_base = r_base + crtc->gamma_size;
228 b_base = g_base + crtc->gamma_size; 228 b_base = g_base + crtc->gamma_size;
229 229
230 crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, 0, crtc->gamma_size); 230 crtc->funcs->gamma_set(crtc, r_base, g_base, b_base, crtc->gamma_size);
231} 231}
232 232
233/** 233/**
@@ -1971,7 +1971,18 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper,
1971 my_score++; 1971 my_score++;
1972 1972
1973 connector_funcs = connector->helper_private; 1973 connector_funcs = connector->helper_private;
1974 encoder = connector_funcs->best_encoder(connector); 1974
1975 /*
1976 * If the DRM device implements atomic hooks and ->best_encoder() is
1977 * NULL we fallback to the default drm_atomic_helper_best_encoder()
1978 * helper.
1979 */
1980 if (fb_helper->dev->mode_config.funcs->atomic_commit &&
1981 !connector_funcs->best_encoder)
1982 encoder = drm_atomic_helper_best_encoder(connector);
1983 else
1984 encoder = connector_funcs->best_encoder(connector);
1985
1975 if (!encoder) 1986 if (!encoder)
1976 goto out; 1987 goto out;
1977 1988
diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
index 7af7f8bcb355..64121f567234 100644
--- a/drivers/gpu/drm/drm_fops.c
+++ b/drivers/gpu/drm/drm_fops.c
@@ -67,7 +67,7 @@ DEFINE_MUTEX(drm_global_mutex);
67 * specific implementations. For GEM-based drivers this is drm_gem_mmap(). 67 * specific implementations. For GEM-based drivers this is drm_gem_mmap().
68 * 68 *
69 * No other file operations are supported by the DRM userspace API. Overall the 69 * No other file operations are supported by the DRM userspace API. Overall the
70 * following is an example #file_operations structure: 70 * following is an example #file_operations structure::
71 * 71 *
72 * static const example_drm_fops = { 72 * static const example_drm_fops = {
73 * .owner = THIS_MODULE, 73 * .owner = THIS_MODULE,
@@ -368,7 +368,7 @@ static void drm_events_release(struct drm_file *file_priv)
368 /* Remove unconsumed events */ 368 /* Remove unconsumed events */
369 list_for_each_entry_safe(e, et, &file_priv->event_list, link) { 369 list_for_each_entry_safe(e, et, &file_priv->event_list, link) {
370 list_del(&e->link); 370 list_del(&e->link);
371 e->destroy(e); 371 kfree(e);
372 } 372 }
373 373
374 spin_unlock_irqrestore(&dev->event_lock, flags); 374 spin_unlock_irqrestore(&dev->event_lock, flags);
@@ -636,7 +636,7 @@ put_back_event:
636 } 636 }
637 637
638 ret += length; 638 ret += length;
639 e->destroy(e); 639 kfree(e);
640 } 640 }
641 } 641 }
642 mutex_unlock(&file_priv->event_read_lock); 642 mutex_unlock(&file_priv->event_read_lock);
@@ -713,9 +713,6 @@ int drm_event_reserve_init_locked(struct drm_device *dev,
713 list_add(&p->pending_link, &file_priv->pending_event_list); 713 list_add(&p->pending_link, &file_priv->pending_event_list);
714 p->file_priv = file_priv; 714 p->file_priv = file_priv;
715 715
716 /* we *could* pass this in as arg, but everyone uses kfree: */
717 p->destroy = (void (*) (struct drm_pending_event *)) kfree;
718
719 return 0; 716 return 0;
720} 717}
721EXPORT_SYMBOL(drm_event_reserve_init_locked); 718EXPORT_SYMBOL(drm_event_reserve_init_locked);
@@ -778,7 +775,7 @@ void drm_event_cancel_free(struct drm_device *dev,
778 list_del(&p->pending_link); 775 list_del(&p->pending_link);
779 } 776 }
780 spin_unlock_irqrestore(&dev->event_lock, flags); 777 spin_unlock_irqrestore(&dev->event_lock, flags);
781 p->destroy(p); 778 kfree(p);
782} 779}
783EXPORT_SYMBOL(drm_event_cancel_free); 780EXPORT_SYMBOL(drm_event_cancel_free);
784 781
@@ -800,8 +797,13 @@ void drm_send_event_locked(struct drm_device *dev, struct drm_pending_event *e)
800{ 797{
801 assert_spin_locked(&dev->event_lock); 798 assert_spin_locked(&dev->event_lock);
802 799
800 if (e->fence) {
801 fence_signal(e->fence);
802 fence_put(e->fence);
803 }
804
803 if (!e->file_priv) { 805 if (!e->file_priv) {
804 e->destroy(e); 806 kfree(e);
805 return; 807 return;
806 } 808 }
807 809
diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 32156060b9c9..5c19dde1cd31 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -787,7 +787,7 @@ EXPORT_SYMBOL(drm_gem_object_release);
787 * @kref: kref of the object to free 787 * @kref: kref of the object to free
788 * 788 *
789 * Called after the last reference to the object has been lost. 789 * Called after the last reference to the object has been lost.
790 * Must be called holding struct_ mutex 790 * Must be called holding &drm_device->struct_mutex.
791 * 791 *
792 * Frees the object 792 * Frees the object
793 */ 793 */
diff --git a/drivers/gpu/drm/drm_irq.c b/drivers/gpu/drm/drm_irq.c
index 5a773e437e2f..4dc41ff388f9 100644
--- a/drivers/gpu/drm/drm_irq.c
+++ b/drivers/gpu/drm/drm_irq.c
@@ -89,11 +89,7 @@ static void store_vblank(struct drm_device *dev, unsigned int pipe,
89 write_sequnlock(&vblank->seqlock); 89 write_sequnlock(&vblank->seqlock);
90} 90}
91 91
92/** 92/*
93 * drm_reset_vblank_timestamp - reset the last timestamp to the last vblank
94 * @dev: DRM device
95 * @pipe: index of CRTC for which to reset the timestamp
96 *
97 * Reset the stored timestamp for the current vblank count to correspond 93 * Reset the stored timestamp for the current vblank count to correspond
98 * to the last vblank occurred. 94 * to the last vblank occurred.
99 * 95 *
@@ -137,11 +133,7 @@ static void drm_reset_vblank_timestamp(struct drm_device *dev, unsigned int pipe
137 spin_unlock(&dev->vblank_time_lock); 133 spin_unlock(&dev->vblank_time_lock);
138} 134}
139 135
140/** 136/*
141 * drm_update_vblank_count - update the master vblank counter
142 * @dev: DRM device
143 * @pipe: counter to update
144 *
145 * Call back into the driver to update the appropriate vblank counter 137 * Call back into the driver to update the appropriate vblank counter
146 * (specified by @pipe). Deal with wraparound, if it occurred, and 138 * (specified by @pipe). Deal with wraparound, if it occurred, and
147 * update the last read value so we can deal with wraparound on the next 139 * update the last read value so we can deal with wraparound on the next
diff --git a/drivers/gpu/drm/drm_mipi_dsi.c b/drivers/gpu/drm/drm_mipi_dsi.c
index f5d80839a90c..7938ce7ebed8 100644
--- a/drivers/gpu/drm/drm_mipi_dsi.c
+++ b/drivers/gpu/drm/drm_mipi_dsi.c
@@ -983,6 +983,28 @@ int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
983EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on); 983EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on);
984 984
985/** 985/**
986 * mipi_dsi_set_tear_scanline() - turn on the display module's Tearing Effect
987 * output signal on the TE signal line when display module reaches line N
988 * defined by STS[n:0].
989 * @dsi: DSI peripheral device
990 * @param: STS[10:0]
991 * Return: 0 on success or a negative error code on failure
992 */
993int mipi_dsi_set_tear_scanline(struct mipi_dsi_device *dsi, u16 param)
994{
995 u8 payload[3] = { MIPI_DCS_SET_TEAR_SCANLINE, param >> 8,
996 param & 0xff };
997 ssize_t err;
998
999 err = mipi_dsi_generic_write(dsi, payload, sizeof(payload));
1000 if (err < 0)
1001 return err;
1002
1003 return 0;
1004}
1005EXPORT_SYMBOL(mipi_dsi_set_tear_scanline);
1006
1007/**
986 * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image 1008 * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image
987 * data used by the interface 1009 * data used by the interface
988 * @dsi: DSI peripheral device 1010 * @dsi: DSI peripheral device
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index e5e6f504d8cc..fc5040ae5f25 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -544,6 +544,7 @@ EXPORT_SYMBOL(drm_gtf_mode_complex);
544 * 544 *
545 * This function is to create the modeline based on the GTF algorithm. 545 * This function is to create the modeline based on the GTF algorithm.
546 * Generalized Timing Formula is derived from: 546 * Generalized Timing Formula is derived from:
547 *
547 * GTF Spreadsheet by Andy Morrish (1/5/97) 548 * GTF Spreadsheet by Andy Morrish (1/5/97)
548 * available at http://www.vesa.org 549 * available at http://www.vesa.org
549 * 550 *
@@ -552,7 +553,8 @@ EXPORT_SYMBOL(drm_gtf_mode_complex);
552 * I also refer to the function of fb_get_mode in the file of 553 * I also refer to the function of fb_get_mode in the file of
553 * drivers/video/fbmon.c 554 * drivers/video/fbmon.c
554 * 555 *
555 * Standard GTF parameters: 556 * Standard GTF parameters::
557 *
556 * M = 600 558 * M = 600
557 * C = 40 559 * C = 40
558 * K = 128 560 * K = 128
diff --git a/drivers/gpu/drm/drm_modeset_lock.c b/drivers/gpu/drm/drm_modeset_lock.c
index f33ebe638a28..61146f5b4f56 100644
--- a/drivers/gpu/drm/drm_modeset_lock.c
+++ b/drivers/gpu/drm/drm_modeset_lock.c
@@ -37,7 +37,7 @@
37 * 37 *
38 * For basic principles of &ww_mutex, see: Documentation/locking/ww-mutex-design.txt 38 * For basic principles of &ww_mutex, see: Documentation/locking/ww-mutex-design.txt
39 * 39 *
40 * The basic usage pattern is to: 40 * The basic usage pattern is to::
41 * 41 *
42 * drm_modeset_acquire_init(&ctx) 42 * drm_modeset_acquire_init(&ctx)
43 * retry: 43 * retry:
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
index 369d2898ff9e..fc51306fe365 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -219,10 +219,12 @@ EXPORT_SYMBOL(drm_plane_helper_check_update);
219 * 219 *
220 * Note that we make some assumptions about hardware limitations that may not be 220 * Note that we make some assumptions about hardware limitations that may not be
221 * true for all hardware -- 221 * true for all hardware --
222 * 1) Primary plane cannot be repositioned. 222 *
223 * 2) Primary plane cannot be scaled. 223 * 1. Primary plane cannot be repositioned.
224 * 3) Primary plane must cover the entire CRTC. 224 * 2. Primary plane cannot be scaled.
225 * 4) Subpixel positioning is not supported. 225 * 3. Primary plane must cover the entire CRTC.
226 * 4. Subpixel positioning is not supported.
227 *
226 * Drivers for hardware that don't have these restrictions can provide their 228 * Drivers for hardware that don't have these restrictions can provide their
227 * own implementation rather than using this helper. 229 * own implementation rather than using this helper.
228 * 230 *
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
index 0329080d7f7c..a0df377d7d1c 100644
--- a/drivers/gpu/drm/drm_probe_helper.c
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -82,13 +82,30 @@ drm_mode_validate_flag(const struct drm_display_mode *mode,
82 82
83static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector) 83static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
84{ 84{
85 struct drm_cmdline_mode *cmdline_mode;
85 struct drm_display_mode *mode; 86 struct drm_display_mode *mode;
86 87
87 if (!connector->cmdline_mode.specified) 88 cmdline_mode = &connector->cmdline_mode;
89 if (!cmdline_mode->specified)
88 return 0; 90 return 0;
89 91
92 /* Only add a GTF mode if we find no matching probed modes */
93 list_for_each_entry(mode, &connector->probed_modes, head) {
94 if (mode->hdisplay != cmdline_mode->xres ||
95 mode->vdisplay != cmdline_mode->yres)
96 continue;
97
98 if (cmdline_mode->refresh_specified) {
99 /* The probed mode's vrefresh is set until later */
100 if (drm_mode_vrefresh(mode) != cmdline_mode->refresh)
101 continue;
102 }
103
104 return 0;
105 }
106
90 mode = drm_mode_create_from_cmdline_mode(connector->dev, 107 mode = drm_mode_create_from_cmdline_mode(connector->dev,
91 &connector->cmdline_mode); 108 cmdline_mode);
92 if (mode == NULL) 109 if (mode == NULL)
93 return 0; 110 return 0;
94 111
diff --git a/drivers/gpu/drm/drm_vma_manager.c b/drivers/gpu/drm/drm_vma_manager.c
index 2f2ecde8285b..f306c8855978 100644
--- a/drivers/gpu/drm/drm_vma_manager.c
+++ b/drivers/gpu/drm/drm_vma_manager.c
@@ -127,6 +127,9 @@ EXPORT_SYMBOL(drm_vma_offset_manager_destroy);
127 * used to implement weakly referenced lookups using kref_get_unless_zero(). 127 * used to implement weakly referenced lookups using kref_get_unless_zero().
128 * 128 *
129 * Example: 129 * Example:
130 *
131 * ::
132 *
130 * drm_vma_offset_lock_lookup(mgr); 133 * drm_vma_offset_lock_lookup(mgr);
131 * node = drm_vma_offset_lookup_locked(mgr); 134 * node = drm_vma_offset_lookup_locked(mgr);
132 * if (node) 135 * if (node)
diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
index f5321e2f25ff..a69cdd526bf8 100644
--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
+++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h
@@ -125,7 +125,7 @@ struct etnaviv_gpu {
125 u32 completed_fence; 125 u32 completed_fence;
126 u32 retired_fence; 126 u32 retired_fence;
127 wait_queue_head_t fence_event; 127 wait_queue_head_t fence_event;
128 unsigned int fence_context; 128 u64 fence_context;
129 spinlock_t fence_spinlock; 129 spinlock_t fence_spinlock;
130 130
131 /* worker for handling active-list retiring: */ 131 /* worker for handling active-list retiring: */
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index 2dd820e23b0c..843b21c540b3 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -267,6 +267,8 @@ int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
267{ 267{
268 struct exynos_drm_private *priv = dev->dev_private; 268 struct exynos_drm_private *priv = dev->dev_private;
269 struct exynos_atomic_commit *commit; 269 struct exynos_atomic_commit *commit;
270 struct drm_crtc *crtc;
271 struct drm_crtc_state *crtc_state;
270 int i, ret; 272 int i, ret;
271 273
272 commit = kzalloc(sizeof(*commit), GFP_KERNEL); 274 commit = kzalloc(sizeof(*commit), GFP_KERNEL);
@@ -288,10 +290,8 @@ int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
288 /* Wait until all affected CRTCs have completed previous commits and 290 /* Wait until all affected CRTCs have completed previous commits and
289 * mark them as pending. 291 * mark them as pending.
290 */ 292 */
291 for (i = 0; i < dev->mode_config.num_crtc; ++i) { 293 for_each_crtc_in_state(state, crtc, crtc_state, i)
292 if (state->crtcs[i]) 294 commit->crtcs |= drm_crtc_mask(crtc);
293 commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
294 }
295 295
296 wait_event(priv->wait, !commit_is_pending(priv, commit->crtcs)); 296 wait_event(priv->wait, !commit_is_pending(priv, commit->crtcs));
297 297
diff --git a/drivers/gpu/drm/gma500/gma_display.c b/drivers/gpu/drm/gma500/gma_display.c
index c95406e6f44d..5b636bf0b467 100644
--- a/drivers/gpu/drm/gma500/gma_display.c
+++ b/drivers/gpu/drm/gma500/gma_display.c
@@ -175,20 +175,21 @@ void gma_crtc_load_lut(struct drm_crtc *crtc)
175 } 175 }
176} 176}
177 177
178void gma_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue, 178int gma_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, u16 *blue,
179 u32 start, u32 size) 179 u32 size)
180{ 180{
181 struct gma_crtc *gma_crtc = to_gma_crtc(crtc); 181 struct gma_crtc *gma_crtc = to_gma_crtc(crtc);
182 int i; 182 int i;
183 int end = (start + size > 256) ? 256 : start + size;
184 183
185 for (i = start; i < end; i++) { 184 for (i = 0; i < size; i++) {
186 gma_crtc->lut_r[i] = red[i] >> 8; 185 gma_crtc->lut_r[i] = red[i] >> 8;
187 gma_crtc->lut_g[i] = green[i] >> 8; 186 gma_crtc->lut_g[i] = green[i] >> 8;
188 gma_crtc->lut_b[i] = blue[i] >> 8; 187 gma_crtc->lut_b[i] = blue[i] >> 8;
189 } 188 }
190 189
191 gma_crtc_load_lut(crtc); 190 gma_crtc_load_lut(crtc);
191
192 return 0;
192} 193}
193 194
194/** 195/**
diff --git a/drivers/gpu/drm/gma500/gma_display.h b/drivers/gpu/drm/gma500/gma_display.h
index b2491c65f053..e72dd08b701b 100644
--- a/drivers/gpu/drm/gma500/gma_display.h
+++ b/drivers/gpu/drm/gma500/gma_display.h
@@ -72,8 +72,8 @@ extern int gma_crtc_cursor_set(struct drm_crtc *crtc,
72 uint32_t width, uint32_t height); 72 uint32_t width, uint32_t height);
73extern int gma_crtc_cursor_move(struct drm_crtc *crtc, int x, int y); 73extern int gma_crtc_cursor_move(struct drm_crtc *crtc, int x, int y);
74extern void gma_crtc_load_lut(struct drm_crtc *crtc); 74extern void gma_crtc_load_lut(struct drm_crtc *crtc);
75extern void gma_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, 75extern int gma_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
76 u16 *blue, u32 start, u32 size); 76 u16 *blue, u32 size);
77extern void gma_crtc_dpms(struct drm_crtc *crtc, int mode); 77extern void gma_crtc_dpms(struct drm_crtc *crtc, int mode);
78extern void gma_crtc_prepare(struct drm_crtc *crtc); 78extern void gma_crtc_prepare(struct drm_crtc *crtc);
79extern void gma_crtc_commit(struct drm_crtc *crtc); 79extern void gma_crtc_commit(struct drm_crtc *crtc);
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index e3077259541a..482c10913ad6 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -886,7 +886,7 @@ enum skl_disp_power_wells {
886 * PLLs can be routed to any transcoder A/B/C. 886 * PLLs can be routed to any transcoder A/B/C.
887 * 887 *
888 * Note: DDI0 is digital port B, DD1 is digital port C, and DDI2 is 888 * Note: DDI0 is digital port B, DD1 is digital port C, and DDI2 is
889 * digital port D (CHV) or port A (BXT). 889 * digital port D (CHV) or port A (BXT). ::
890 * 890 *
891 * 891 *
892 * Dual channel PHY (VLV/CHV/BXT) 892 * Dual channel PHY (VLV/CHV/BXT)
diff --git a/drivers/gpu/drm/i915/i915_vgpu.c b/drivers/gpu/drm/i915/i915_vgpu.c
index d5a7a5e7ee7e..004326291854 100644
--- a/drivers/gpu/drm/i915/i915_vgpu.c
+++ b/drivers/gpu/drm/i915/i915_vgpu.c
@@ -150,28 +150,28 @@ static int vgt_balloon_space(struct drm_mm *mm,
150 * of its graphic space being zero. Yet there are some portions ballooned out( 150 * of its graphic space being zero. Yet there are some portions ballooned out(
151 * the shadow part, which are marked as reserved by drm allocator). From the 151 * the shadow part, which are marked as reserved by drm allocator). From the
152 * host point of view, the graphic address space is partitioned by multiple 152 * host point of view, the graphic address space is partitioned by multiple
153 * vGPUs in different VMs. 153 * vGPUs in different VMs. ::
154 * 154 *
155 * vGPU1 view Host view 155 * vGPU1 view Host view
156 * 0 ------> +-----------+ +-----------+ 156 * 0 ------> +-----------+ +-----------+
157 * ^ |///////////| | vGPU3 | 157 * ^ |###########| | vGPU3 |
158 * | |///////////| +-----------+ 158 * | |###########| +-----------+
159 * | |///////////| | vGPU2 | 159 * | |###########| | vGPU2 |
160 * | +-----------+ +-----------+ 160 * | +-----------+ +-----------+
161 * mappable GM | available | ==> | vGPU1 | 161 * mappable GM | available | ==> | vGPU1 |
162 * | +-----------+ +-----------+ 162 * | +-----------+ +-----------+
163 * | |///////////| | | 163 * | |###########| | |
164 * v |///////////| | Host | 164 * v |###########| | Host |
165 * +=======+===========+ +===========+ 165 * +=======+===========+ +===========+
166 * ^ |///////////| | vGPU3 | 166 * ^ |###########| | vGPU3 |
167 * | |///////////| +-----------+ 167 * | |###########| +-----------+
168 * | |///////////| | vGPU2 | 168 * | |###########| | vGPU2 |
169 * | +-----------+ +-----------+ 169 * | +-----------+ +-----------+
170 * unmappable GM | available | ==> | vGPU1 | 170 * unmappable GM | available | ==> | vGPU1 |
171 * | +-----------+ +-----------+ 171 * | +-----------+ +-----------+
172 * | |///////////| | | 172 * | |###########| | |
173 * | |///////////| | Host | 173 * | |###########| | Host |
174 * v |///////////| | | 174 * v |###########| | |
175 * total GM size ------> +-----------+ +-----------+ 175 * total GM size ------> +-----------+ +-----------+
176 * 176 *
177 * Returns: 177 * Returns:
diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c
index 50ff90aea721..c5a166752eda 100644
--- a/drivers/gpu/drm/i915/intel_atomic.c
+++ b/drivers/gpu/drm/i915/intel_atomic.c
@@ -191,7 +191,7 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
191 191
192 /* plane scaler case: assign as a plane scaler */ 192 /* plane scaler case: assign as a plane scaler */
193 /* find the plane that set the bit as scaler_user */ 193 /* find the plane that set the bit as scaler_user */
194 plane = drm_state->planes[i]; 194 plane = drm_state->planes[i].ptr;
195 195
196 /* 196 /*
197 * to enable/disable hq mode, add planes that are using scaler 197 * to enable/disable hq mode, add planes that are using scaler
@@ -223,7 +223,8 @@ int intel_atomic_setup_scalers(struct drm_device *dev,
223 continue; 223 continue;
224 } 224 }
225 225
226 plane_state = to_intel_plane_state(drm_state->plane_states[i]); 226 plane_state = intel_atomic_get_existing_plane_state(drm_state,
227 intel_plane);
227 scaler_id = &plane_state->scaler_id; 228 scaler_id = &plane_state->scaler_id;
228 } 229 }
229 230
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index cccf9bc7c7d6..2834ca5216b2 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -5214,14 +5214,14 @@ void intel_edp_drrs_flush(struct drm_device *dev,
5214 * 5214 *
5215 * DRRS saves power by switching to low RR based on usage scenarios. 5215 * DRRS saves power by switching to low RR based on usage scenarios.
5216 * 5216 *
5217 * eDP DRRS:- 5217 * The implementation is based on frontbuffer tracking implementation. When
5218 * The implementation is based on frontbuffer tracking implementation. 5218 * there is a disturbance on the screen triggered by user activity or a periodic
5219 * When there is a disturbance on the screen triggered by user activity or a 5219 * system activity, DRRS is disabled (RR is changed to high RR). When there is
5220 * periodic system activity, DRRS is disabled (RR is changed to high RR). 5220 * no movement on screen, after a timeout of 1 second, a switch to low RR is
5221 * When there is no movement on screen, after a timeout of 1 second, a switch 5221 * made.
5222 * to low RR is made. 5222 *
5223 * For integration with frontbuffer tracking code, 5223 * For integration with frontbuffer tracking code, intel_edp_drrs_invalidate()
5224 * intel_edp_drrs_invalidate() and intel_edp_drrs_flush() are called. 5224 * and intel_edp_drrs_flush() are called.
5225 * 5225 *
5226 * DRRS can be further extended to support other internal panels and also 5226 * DRRS can be further extended to support other internal panels and also
5227 * the scenario of video playback wherein RR is set based on the rate 5227 * the scenario of video playback wherein RR is set based on the rate
diff --git a/drivers/gpu/drm/i915/intel_fbc.c b/drivers/gpu/drm/i915/intel_fbc.c
index 0dea5fbcd8aa..45ee07b888a0 100644
--- a/drivers/gpu/drm/i915/intel_fbc.c
+++ b/drivers/gpu/drm/i915/intel_fbc.c
@@ -374,8 +374,9 @@ static void intel_fbc_hw_deactivate(struct drm_i915_private *dev_priv)
374 * @dev_priv: i915 device instance 374 * @dev_priv: i915 device instance
375 * 375 *
376 * This function is used to verify the current state of FBC. 376 * This function is used to verify the current state of FBC.
377 *
377 * FIXME: This should be tracked in the plane config eventually 378 * FIXME: This should be tracked in the plane config eventually
378 * instead of queried at runtime for most callers. 379 * instead of queried at runtime for most callers.
379 */ 380 */
380bool intel_fbc_is_active(struct drm_i915_private *dev_priv) 381bool intel_fbc_is_active(struct drm_i915_private *dev_priv)
381{ 382{
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c
index d347dca17267..6b21cb27e1cc 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -1352,19 +1352,20 @@ static void mga_crtc_commit(struct drm_crtc *crtc)
1352 * use this for 8-bit mode so can't perform smooth fades on deeper modes, 1352 * use this for 8-bit mode so can't perform smooth fades on deeper modes,
1353 * but it's a requirement that we provide the function 1353 * but it's a requirement that we provide the function
1354 */ 1354 */
1355static void mga_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, 1355static int mga_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
1356 u16 *blue, uint32_t start, uint32_t size) 1356 u16 *blue, uint32_t size)
1357{ 1357{
1358 struct mga_crtc *mga_crtc = to_mga_crtc(crtc); 1358 struct mga_crtc *mga_crtc = to_mga_crtc(crtc);
1359 int end = (start + size > MGAG200_LUT_SIZE) ? MGAG200_LUT_SIZE : start + size;
1360 int i; 1359 int i;
1361 1360
1362 for (i = start; i < end; i++) { 1361 for (i = 0; i < size; i++) {
1363 mga_crtc->lut_r[i] = red[i] >> 8; 1362 mga_crtc->lut_r[i] = red[i] >> 8;
1364 mga_crtc->lut_g[i] = green[i] >> 8; 1363 mga_crtc->lut_g[i] = green[i] >> 8;
1365 mga_crtc->lut_b[i] = blue[i] >> 8; 1364 mga_crtc->lut_b[i] = blue[i] >> 8;
1366 } 1365 }
1367 mga_crtc_load_lut(crtc); 1366 mga_crtc_load_lut(crtc);
1367
1368 return 0;
1368} 1369}
1369 1370
1370/* Simple cleanup function */ 1371/* Simple cleanup function */
diff --git a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
index 67442d50a6c2..f145d256e332 100644
--- a/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c
@@ -106,31 +106,27 @@ out:
106static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state) 106static void mdp4_prepare_commit(struct msm_kms *kms, struct drm_atomic_state *state)
107{ 107{
108 struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); 108 struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
109 int i, ncrtcs = state->dev->mode_config.num_crtc; 109 int i;
110 struct drm_crtc *crtc;
111 struct drm_crtc_state *crtc_state;
110 112
111 mdp4_enable(mdp4_kms); 113 mdp4_enable(mdp4_kms);
112 114
113 /* see 119ecb7fd */ 115 /* see 119ecb7fd */
114 for (i = 0; i < ncrtcs; i++) { 116 for_each_crtc_in_state(state, crtc, crtc_state, i)
115 struct drm_crtc *crtc = state->crtcs[i];
116 if (!crtc)
117 continue;
118 drm_crtc_vblank_get(crtc); 117 drm_crtc_vblank_get(crtc);
119 }
120} 118}
121 119
122static void mdp4_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state) 120static void mdp4_complete_commit(struct msm_kms *kms, struct drm_atomic_state *state)
123{ 121{
124 struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms)); 122 struct mdp4_kms *mdp4_kms = to_mdp4_kms(to_mdp_kms(kms));
125 int i, ncrtcs = state->dev->mode_config.num_crtc; 123 int i;
124 struct drm_crtc *crtc;
125 struct drm_crtc_state *crtc_state;
126 126
127 /* see 119ecb7fd */ 127 /* see 119ecb7fd */
128 for (i = 0; i < ncrtcs; i++) { 128 for_each_crtc_in_state(state, crtc, crtc_state, i)
129 struct drm_crtc *crtc = state->crtcs[i];
130 if (!crtc)
131 continue;
132 drm_crtc_vblank_put(crtc); 129 drm_crtc_vblank_put(crtc);
133 }
134 130
135 mdp4_disable(mdp4_kms); 131 mdp4_disable(mdp4_kms);
136} 132}
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
index 88fe256c1931..4e8ed739f558 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c
@@ -374,6 +374,7 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
374 struct drm_device *dev = crtc->dev; 374 struct drm_device *dev = crtc->dev;
375 struct plane_state pstates[STAGE_MAX + 1]; 375 struct plane_state pstates[STAGE_MAX + 1];
376 const struct mdp5_cfg_hw *hw_cfg; 376 const struct mdp5_cfg_hw *hw_cfg;
377 const struct drm_plane_state *pstate;
377 int cnt = 0, i; 378 int cnt = 0, i;
378 379
379 DBG("%s: check", mdp5_crtc->name); 380 DBG("%s: check", mdp5_crtc->name);
@@ -382,20 +383,13 @@ static int mdp5_crtc_atomic_check(struct drm_crtc *crtc,
382 * and that we don't have conflicting mixer stages: 383 * and that we don't have conflicting mixer stages:
383 */ 384 */
384 hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg); 385 hw_cfg = mdp5_cfg_get_hw_config(mdp5_kms->cfg);
385 drm_atomic_crtc_state_for_each_plane(plane, state) { 386 drm_atomic_crtc_state_for_each_plane_state(plane, pstate, state) {
386 struct drm_plane_state *pstate;
387 if (cnt >= (hw_cfg->lm.nb_stages)) { 387 if (cnt >= (hw_cfg->lm.nb_stages)) {
388 dev_err(dev->dev, "too many planes!\n"); 388 dev_err(dev->dev, "too many planes!\n");
389 return -EINVAL; 389 return -EINVAL;
390 } 390 }
391 391
392 pstate = state->state->plane_states[drm_plane_index(plane)];
393 392
394 /* plane might not have changed, in which case take
395 * current state:
396 */
397 if (!pstate)
398 pstate = plane->state;
399 pstates[cnt].plane = plane; 393 pstates[cnt].plane = plane;
400 pstates[cnt].state = to_mdp5_plane_state(pstate); 394 pstates[cnt].state = to_mdp5_plane_state(pstate);
401 395
diff --git a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
index 484b4d15e71d..f0c285b1c027 100644
--- a/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
+++ b/drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c
@@ -78,17 +78,11 @@ static void mdp5_complete_commit(struct msm_kms *kms, struct drm_atomic_state *s
78{ 78{
79 int i; 79 int i;
80 struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms)); 80 struct mdp5_kms *mdp5_kms = to_mdp5_kms(to_mdp_kms(kms));
81 int nplanes = mdp5_kms->dev->mode_config.num_total_plane; 81 struct drm_plane *plane;
82 82 struct drm_plane_state *plane_state;
83 for (i = 0; i < nplanes; i++) {
84 struct drm_plane *plane = state->planes[i];
85 struct drm_plane_state *plane_state = state->plane_states[i];
86
87 if (!plane)
88 continue;
89 83
84 for_each_plane_in_state(state, plane, plane_state, i)
90 mdp5_plane_complete_commit(plane, plane_state); 85 mdp5_plane_complete_commit(plane, plane_state);
91 }
92 86
93 mdp5_disable(mdp5_kms); 87 mdp5_disable(mdp5_kms);
94} 88}
diff --git a/drivers/gpu/drm/msm/msm_atomic.c b/drivers/gpu/drm/msm/msm_atomic.c
index e3892c263f27..8c3b463620bd 100644
--- a/drivers/gpu/drm/msm/msm_atomic.c
+++ b/drivers/gpu/drm/msm/msm_atomic.c
@@ -84,17 +84,12 @@ static void msm_atomic_wait_for_commit_done(struct drm_device *dev,
84 struct drm_atomic_state *old_state) 84 struct drm_atomic_state *old_state)
85{ 85{
86 struct drm_crtc *crtc; 86 struct drm_crtc *crtc;
87 struct drm_crtc_state *crtc_state;
87 struct msm_drm_private *priv = old_state->dev->dev_private; 88 struct msm_drm_private *priv = old_state->dev->dev_private;
88 struct msm_kms *kms = priv->kms; 89 struct msm_kms *kms = priv->kms;
89 int ncrtcs = old_state->dev->mode_config.num_crtc;
90 int i; 90 int i;
91 91
92 for (i = 0; i < ncrtcs; i++) { 92 for_each_crtc_in_state(old_state, crtc, crtc_state, i) {
93 crtc = old_state->crtcs[i];
94
95 if (!crtc)
96 continue;
97
98 if (!crtc->state->enable) 93 if (!crtc->state->enable)
99 continue; 94 continue;
100 95
@@ -192,9 +187,11 @@ int msm_atomic_commit(struct drm_device *dev,
192 struct drm_atomic_state *state, bool nonblock) 187 struct drm_atomic_state *state, bool nonblock)
193{ 188{
194 struct msm_drm_private *priv = dev->dev_private; 189 struct msm_drm_private *priv = dev->dev_private;
195 int nplanes = dev->mode_config.num_total_plane;
196 int ncrtcs = dev->mode_config.num_crtc;
197 struct msm_commit *c; 190 struct msm_commit *c;
191 struct drm_crtc *crtc;
192 struct drm_crtc_state *crtc_state;
193 struct drm_plane *plane;
194 struct drm_plane_state *plane_state;
198 int i, ret; 195 int i, ret;
199 196
200 ret = drm_atomic_helper_prepare_planes(dev, state); 197 ret = drm_atomic_helper_prepare_planes(dev, state);
@@ -210,28 +207,18 @@ int msm_atomic_commit(struct drm_device *dev,
210 /* 207 /*
211 * Figure out what crtcs we have: 208 * Figure out what crtcs we have:
212 */ 209 */
213 for (i = 0; i < ncrtcs; i++) { 210 for_each_crtc_in_state(state, crtc, crtc_state, i)
214 struct drm_crtc *crtc = state->crtcs[i]; 211 c->crtc_mask |= drm_crtc_mask(crtc);
215 if (!crtc)
216 continue;
217 c->crtc_mask |= (1 << drm_crtc_index(crtc));
218 }
219 212
220 /* 213 /*
221 * Figure out what fence to wait for: 214 * Figure out what fence to wait for:
222 */ 215 */
223 for (i = 0; i < nplanes; i++) { 216 for_each_plane_in_state(state, plane, plane_state, i) {
224 struct drm_plane *plane = state->planes[i]; 217 if ((plane->state->fb != plane_state->fb) && plane_state->fb) {
225 struct drm_plane_state *new_state = state->plane_states[i]; 218 struct drm_gem_object *obj = msm_framebuffer_bo(plane_state->fb, 0);
226
227 if (!plane)
228 continue;
229
230 if ((plane->state->fb != new_state->fb) && new_state->fb) {
231 struct drm_gem_object *obj = msm_framebuffer_bo(new_state->fb, 0);
232 struct msm_gem_object *msm_obj = to_msm_bo(obj); 219 struct msm_gem_object *msm_obj = to_msm_bo(obj);
233 220
234 new_state->fence = reservation_object_get_excl_rcu(msm_obj->resv); 221 plane_state->fence = reservation_object_get_excl_rcu(msm_obj->resv);
235 } 222 }
236 } 223 }
237 224
diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
index 6f318c54da33..0cb7a18cde26 100644
--- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c
+++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c
@@ -785,14 +785,14 @@ nv_crtc_disable(struct drm_crtc *crtc)
785 nouveau_bo_ref(NULL, &disp->image[nv_crtc->index]); 785 nouveau_bo_ref(NULL, &disp->image[nv_crtc->index]);
786} 786}
787 787
788static void 788static int
789nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, uint32_t start, 789nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
790 uint32_t size) 790 uint32_t size)
791{ 791{
792 int end = (start + size > 256) ? 256 : start + size, i;
793 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 792 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
793 int i;
794 794
795 for (i = start; i < end; i++) { 795 for (i = 0; i < size; i++) {
796 nv_crtc->lut.r[i] = r[i]; 796 nv_crtc->lut.r[i] = r[i];
797 nv_crtc->lut.g[i] = g[i]; 797 nv_crtc->lut.g[i] = g[i];
798 nv_crtc->lut.b[i] = b[i]; 798 nv_crtc->lut.b[i] = b[i];
@@ -805,10 +805,12 @@ nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, uint32_t start,
805 */ 805 */
806 if (!nv_crtc->base.primary->fb) { 806 if (!nv_crtc->base.primary->fb) {
807 nv_crtc->lut.depth = 0; 807 nv_crtc->lut.depth = 0;
808 return; 808 return 0;
809 } 809 }
810 810
811 nv_crtc_gamma_load(crtc); 811 nv_crtc_gamma_load(crtc);
812
813 return 0;
812} 814}
813 815
814static int 816static int
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.h b/drivers/gpu/drm/nouveau/nouveau_fence.h
index 2e3a62d38fe9..64c4ce7115ad 100644
--- a/drivers/gpu/drm/nouveau/nouveau_fence.h
+++ b/drivers/gpu/drm/nouveau/nouveau_fence.h
@@ -57,7 +57,8 @@ struct nouveau_fence_priv {
57 int (*context_new)(struct nouveau_channel *); 57 int (*context_new)(struct nouveau_channel *);
58 void (*context_del)(struct nouveau_channel *); 58 void (*context_del)(struct nouveau_channel *);
59 59
60 u32 contexts, context_base; 60 u32 contexts;
61 u64 context_base;
61 bool uevent; 62 bool uevent;
62}; 63};
63 64
diff --git a/drivers/gpu/drm/nouveau/nouveau_usif.c b/drivers/gpu/drm/nouveau/nouveau_usif.c
index 675e9e077a95..08f9c6fa0f7f 100644
--- a/drivers/gpu/drm/nouveau/nouveau_usif.c
+++ b/drivers/gpu/drm/nouveau/nouveau_usif.c
@@ -212,7 +212,6 @@ usif_notify_get(struct drm_file *f, void *data, u32 size, void *argv, u32 argc)
212 ntfy->p->base.event = &ntfy->p->e.base; 212 ntfy->p->base.event = &ntfy->p->e.base;
213 ntfy->p->base.file_priv = f; 213 ntfy->p->base.file_priv = f;
214 ntfy->p->base.pid = current->pid; 214 ntfy->p->base.pid = current->pid;
215 ntfy->p->base.destroy =(void(*)(struct drm_pending_event *))kfree;
216 ntfy->p->e.base.type = DRM_NOUVEAU_EVENT_NVIF; 215 ntfy->p->e.base.type = DRM_NOUVEAU_EVENT_NVIF;
217 ntfy->p->e.base.length = sizeof(ntfy->p->e.base) + ntfy->reply; 216 ntfy->p->e.base.length = sizeof(ntfy->p->e.base) + ntfy->reply;
218 217
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c
index 3ffc2b0057bf..7a7788212df7 100644
--- a/drivers/gpu/drm/nouveau/nv50_display.c
+++ b/drivers/gpu/drm/nouveau/nv50_display.c
@@ -1346,21 +1346,22 @@ nv50_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
1346 return 0; 1346 return 0;
1347} 1347}
1348 1348
1349static void 1349static int
1350nv50_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, 1350nv50_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
1351 uint32_t start, uint32_t size) 1351 uint32_t size)
1352{ 1352{
1353 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); 1353 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
1354 u32 end = min_t(u32, start + size, 256);
1355 u32 i; 1354 u32 i;
1356 1355
1357 for (i = start; i < end; i++) { 1356 for (i = 0; i < size; i++) {
1358 nv_crtc->lut.r[i] = r[i]; 1357 nv_crtc->lut.r[i] = r[i];
1359 nv_crtc->lut.g[i] = g[i]; 1358 nv_crtc->lut.g[i] = g[i];
1360 nv_crtc->lut.b[i] = b[i]; 1359 nv_crtc->lut.b[i] = b[i];
1361 } 1360 }
1362 1361
1363 nv50_crtc_lut_load(crtc); 1362 nv50_crtc_lut_load(crtc);
1363
1364 return 0;
1364} 1365}
1365 1366
1366static void 1367static void
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index d86f5479345b..d9848f1fc4e8 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -142,8 +142,9 @@ static int omap_atomic_commit(struct drm_device *dev,
142{ 142{
143 struct omap_drm_private *priv = dev->dev_private; 143 struct omap_drm_private *priv = dev->dev_private;
144 struct omap_atomic_state_commit *commit; 144 struct omap_atomic_state_commit *commit;
145 unsigned int i; 145 struct drm_crtc *crtc;
146 int ret; 146 struct drm_crtc_state *crtc_state;
147 int i, ret;
147 148
148 ret = drm_atomic_helper_prepare_planes(dev, state); 149 ret = drm_atomic_helper_prepare_planes(dev, state);
149 if (ret) 150 if (ret)
@@ -163,10 +164,8 @@ static int omap_atomic_commit(struct drm_device *dev,
163 /* Wait until all affected CRTCs have completed previous commits and 164 /* Wait until all affected CRTCs have completed previous commits and
164 * mark them as pending. 165 * mark them as pending.
165 */ 166 */
166 for (i = 0; i < dev->mode_config.num_crtc; ++i) { 167 for_each_crtc_in_state(state, crtc, crtc_state, i)
167 if (state->crtcs[i]) 168 commit->crtcs |= drm_crtc_mask(crtc);
168 commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
169 }
170 169
171 wait_event(priv->commit.wait, !omap_atomic_is_pending(priv, commit)); 170 wait_event(priv->commit.wait, !omap_atomic_is_pending(priv, commit));
172 171
diff --git a/drivers/gpu/drm/qxl/qxl_display.c b/drivers/gpu/drm/qxl/qxl_display.c
index 5bc36c4d4232..ad429683fef7 100644
--- a/drivers/gpu/drm/qxl/qxl_display.c
+++ b/drivers/gpu/drm/qxl/qxl_display.c
@@ -221,7 +221,6 @@ static int qxl_crtc_page_flip(struct drm_crtc *crtc,
221{ 221{
222 struct drm_device *dev = crtc->dev; 222 struct drm_device *dev = crtc->dev;
223 struct qxl_device *qdev = dev->dev_private; 223 struct qxl_device *qdev = dev->dev_private;
224 struct qxl_crtc *qcrtc = to_qxl_crtc(crtc);
225 struct qxl_framebuffer *qfb_src = to_qxl_framebuffer(fb); 224 struct qxl_framebuffer *qfb_src = to_qxl_framebuffer(fb);
226 struct qxl_framebuffer *qfb_old = to_qxl_framebuffer(crtc->primary->fb); 225 struct qxl_framebuffer *qfb_old = to_qxl_framebuffer(crtc->primary->fb);
227 struct qxl_bo *bo_old = gem_to_qxl_bo(qfb_old->obj); 226 struct qxl_bo *bo_old = gem_to_qxl_bo(qfb_old->obj);
@@ -252,14 +251,14 @@ static int qxl_crtc_page_flip(struct drm_crtc *crtc,
252 qxl_draw_dirty_fb(qdev, qfb_src, bo, 0, 0, 251 qxl_draw_dirty_fb(qdev, qfb_src, bo, 0, 0,
253 &norect, one_clip_rect, inc); 252 &norect, one_clip_rect, inc);
254 253
255 drm_vblank_get(dev, qcrtc->index); 254 drm_crtc_vblank_get(crtc);
256 255
257 if (event) { 256 if (event) {
258 spin_lock_irqsave(&dev->event_lock, flags); 257 spin_lock_irqsave(&dev->event_lock, flags);
259 drm_send_vblank_event(dev, qcrtc->index, event); 258 drm_crtc_send_vblank_event(crtc, event);
260 spin_unlock_irqrestore(&dev->event_lock, flags); 259 spin_unlock_irqrestore(&dev->event_lock, flags);
261 } 260 }
262 drm_vblank_put(dev, qcrtc->index); 261 drm_crtc_vblank_put(crtc);
263 262
264 ret = qxl_bo_reserve(bo, false); 263 ret = qxl_bo_reserve(bo, false);
265 if (!ret) { 264 if (!ret) {
diff --git a/drivers/gpu/drm/qxl/qxl_fb.c b/drivers/gpu/drm/qxl/qxl_fb.c
index 5ea57f6320b8..df2657051afd 100644
--- a/drivers/gpu/drm/qxl/qxl_fb.c
+++ b/drivers/gpu/drm/qxl/qxl_fb.c
@@ -131,10 +131,6 @@ static int qxlfb_create_pinned_object(struct qxl_fbdev *qfbdev,
131 int ret; 131 int ret;
132 int aligned_size, size; 132 int aligned_size, size;
133 int height = mode_cmd->height; 133 int height = mode_cmd->height;
134 int bpp;
135 int depth;
136
137 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &bpp, &depth);
138 134
139 size = mode_cmd->pitches[0] * height; 135 size = mode_cmd->pitches[0] * height;
140 aligned_size = ALIGN(size, PAGE_SIZE); 136 aligned_size = ALIGN(size, PAGE_SIZE);
diff --git a/drivers/gpu/drm/qxl/qxl_release.c b/drivers/gpu/drm/qxl/qxl_release.c
index 4efa8e261baf..f599cd073b72 100644
--- a/drivers/gpu/drm/qxl/qxl_release.c
+++ b/drivers/gpu/drm/qxl/qxl_release.c
@@ -96,7 +96,7 @@ retry:
96 return 0; 96 return 0;
97 97
98 if (have_drawable_releases && sc > 300) { 98 if (have_drawable_releases && sc > 300) {
99 FENCE_WARN(fence, "failed to wait on release %d " 99 FENCE_WARN(fence, "failed to wait on release %llu "
100 "after spincount %d\n", 100 "after spincount %d\n",
101 fence->context & ~0xf0000000, sc); 101 fence->context & ~0xf0000000, sc);
102 goto signaled; 102 goto signaled;
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index 80b24a495d6c..5633ee3eb46e 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -2386,7 +2386,7 @@ struct radeon_device {
2386 struct radeon_mman mman; 2386 struct radeon_mman mman;
2387 struct radeon_fence_driver fence_drv[RADEON_NUM_RINGS]; 2387 struct radeon_fence_driver fence_drv[RADEON_NUM_RINGS];
2388 wait_queue_head_t fence_queue; 2388 wait_queue_head_t fence_queue;
2389 unsigned fence_context; 2389 u64 fence_context;
2390 struct mutex ring_lock; 2390 struct mutex ring_lock;
2391 struct radeon_ring ring[RADEON_NUM_RINGS]; 2391 struct radeon_ring ring[RADEON_NUM_RINGS];
2392 bool ib_pool_ready; 2392 bool ib_pool_ready;
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 6a41b4982647..e85c7a2f565b 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -231,19 +231,21 @@ void radeon_crtc_fb_gamma_get(struct drm_crtc *crtc, u16 *red, u16 *green,
231 *blue = radeon_crtc->lut_b[regno] << 6; 231 *blue = radeon_crtc->lut_b[regno] << 6;
232} 232}
233 233
234static void radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, 234static int radeon_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green,
235 u16 *blue, uint32_t start, uint32_t size) 235 u16 *blue, uint32_t size)
236{ 236{
237 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); 237 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
238 int end = (start + size > 256) ? 256 : start + size, i; 238 int i;
239 239
240 /* userspace palettes are always correct as is */ 240 /* userspace palettes are always correct as is */
241 for (i = start; i < end; i++) { 241 for (i = 0; i < size; i++) {
242 radeon_crtc->lut_r[i] = red[i] >> 6; 242 radeon_crtc->lut_r[i] = red[i] >> 6;
243 radeon_crtc->lut_g[i] = green[i] >> 6; 243 radeon_crtc->lut_g[i] = green[i] >> 6;
244 radeon_crtc->lut_b[i] = blue[i] >> 6; 244 radeon_crtc->lut_b[i] = blue[i] >> 6;
245 } 245 }
246 radeon_crtc_load_lut(crtc); 246 radeon_crtc_load_lut(crtc);
247
248 return 0;
247} 249}
248 250
249static void radeon_crtc_destroy(struct drm_crtc *crtc) 251static void radeon_crtc_destroy(struct drm_crtc *crtc)
@@ -381,7 +383,7 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id)
381 383
382 spin_unlock_irqrestore(&rdev->ddev->event_lock, flags); 384 spin_unlock_irqrestore(&rdev->ddev->event_lock, flags);
383 385
384 drm_vblank_put(rdev->ddev, radeon_crtc->crtc_id); 386 drm_crtc_vblank_put(&radeon_crtc->base);
385 radeon_irq_kms_pflip_irq_put(rdev, work->crtc_id); 387 radeon_irq_kms_pflip_irq_put(rdev, work->crtc_id);
386 queue_work(radeon_crtc->flip_queue, &work->unpin_work); 388 queue_work(radeon_crtc->flip_queue, &work->unpin_work);
387} 389}
@@ -598,7 +600,7 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
598 } 600 }
599 work->base = base; 601 work->base = base;
600 602
601 r = drm_vblank_get(crtc->dev, radeon_crtc->crtc_id); 603 r = drm_crtc_vblank_get(crtc);
602 if (r) { 604 if (r) {
603 DRM_ERROR("failed to get vblank before flip\n"); 605 DRM_ERROR("failed to get vblank before flip\n");
604 goto pflip_cleanup; 606 goto pflip_cleanup;
@@ -625,7 +627,7 @@ static int radeon_crtc_page_flip(struct drm_crtc *crtc,
625 return 0; 627 return 0;
626 628
627vblank_cleanup: 629vblank_cleanup:
628 drm_vblank_put(crtc->dev, radeon_crtc->crtc_id); 630 drm_crtc_vblank_put(&radeon_crtc->base);
629 631
630pflip_cleanup: 632pflip_cleanup:
631 if (unlikely(radeon_bo_reserve(new_rbo, false) != 0)) { 633 if (unlikely(radeon_bo_reserve(new_rbo, false) != 0)) {
@@ -688,6 +690,7 @@ radeon_crtc_set_config(struct drm_mode_set *set)
688 pm_runtime_put_autosuspend(dev->dev); 690 pm_runtime_put_autosuspend(dev->dev);
689 return ret; 691 return ret;
690} 692}
693
691static const struct drm_crtc_funcs radeon_crtc_funcs = { 694static const struct drm_crtc_funcs radeon_crtc_funcs = {
692 .cursor_set2 = radeon_crtc_cursor_set2, 695 .cursor_set2 = radeon_crtc_cursor_set2,
693 .cursor_move = radeon_crtc_cursor_move, 696 .cursor_move = radeon_crtc_cursor_move,
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c
index 38226d925a5b..4b6542538ff9 100644
--- a/drivers/gpu/drm/radeon/radeon_pm.c
+++ b/drivers/gpu/drm/radeon/radeon_pm.c
@@ -246,6 +246,7 @@ static void radeon_set_power_state(struct radeon_device *rdev)
246 246
247static void radeon_pm_set_clocks(struct radeon_device *rdev) 247static void radeon_pm_set_clocks(struct radeon_device *rdev)
248{ 248{
249 struct drm_crtc *crtc;
249 int i, r; 250 int i, r;
250 251
251 /* no need to take locks, etc. if nothing's going to change */ 252 /* no need to take locks, etc. if nothing's going to change */
@@ -274,26 +275,30 @@ static void radeon_pm_set_clocks(struct radeon_device *rdev)
274 radeon_unmap_vram_bos(rdev); 275 radeon_unmap_vram_bos(rdev);
275 276
276 if (rdev->irq.installed) { 277 if (rdev->irq.installed) {
277 for (i = 0; i < rdev->num_crtc; i++) { 278 i = 0;
279 drm_for_each_crtc(crtc, rdev->ddev) {
278 if (rdev->pm.active_crtcs & (1 << i)) { 280 if (rdev->pm.active_crtcs & (1 << i)) {
279 /* This can fail if a modeset is in progress */ 281 /* This can fail if a modeset is in progress */
280 if (drm_vblank_get(rdev->ddev, i) == 0) 282 if (drm_crtc_vblank_get(crtc) == 0)
281 rdev->pm.req_vblank |= (1 << i); 283 rdev->pm.req_vblank |= (1 << i);
282 else 284 else
283 DRM_DEBUG_DRIVER("crtc %d no vblank, can glitch\n", 285 DRM_DEBUG_DRIVER("crtc %d no vblank, can glitch\n",
284 i); 286 i);
285 } 287 }
288 i++;
286 } 289 }
287 } 290 }
288 291
289 radeon_set_power_state(rdev); 292 radeon_set_power_state(rdev);
290 293
291 if (rdev->irq.installed) { 294 if (rdev->irq.installed) {
292 for (i = 0; i < rdev->num_crtc; i++) { 295 i = 0;
296 drm_for_each_crtc(crtc, rdev->ddev) {
293 if (rdev->pm.req_vblank & (1 << i)) { 297 if (rdev->pm.req_vblank & (1 << i)) {
294 rdev->pm.req_vblank &= ~(1 << i); 298 rdev->pm.req_vblank &= ~(1 << i);
295 drm_vblank_put(rdev->ddev, i); 299 drm_crtc_vblank_put(crtc);
296 } 300 }
301 i++;
297 } 302 }
298 } 303 }
299 304
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_kms.c b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
index e70a4f33d970..86c109b16876 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_kms.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_kms.c
@@ -288,6 +288,8 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
288{ 288{
289 struct rcar_du_device *rcdu = dev->dev_private; 289 struct rcar_du_device *rcdu = dev->dev_private;
290 struct rcar_du_commit *commit; 290 struct rcar_du_commit *commit;
291 struct drm_crtc *crtc;
292 struct drm_crtc_state *crtc_state;
291 unsigned int i; 293 unsigned int i;
292 int ret; 294 int ret;
293 295
@@ -309,10 +311,8 @@ static int rcar_du_atomic_commit(struct drm_device *dev,
309 /* Wait until all affected CRTCs have completed previous commits and 311 /* Wait until all affected CRTCs have completed previous commits and
310 * mark them as pending. 312 * mark them as pending.
311 */ 313 */
312 for (i = 0; i < dev->mode_config.num_crtc; ++i) { 314 for_each_crtc_in_state(state, crtc, crtc_state, i)
313 if (state->crtcs[i]) 315 commit->crtcs |= drm_crtc_mask(crtc);
314 commit->crtcs |= 1 << drm_crtc_index(state->crtcs[i]);
315 }
316 316
317 spin_lock(&rcdu->commit.wait.lock); 317 spin_lock(&rcdu->commit.wait.lock);
318 ret = wait_event_interruptible_locked(rcdu->commit.wait, 318 ret = wait_event_interruptible_locked(rcdu->commit.wait,
diff --git a/drivers/gpu/drm/rcar-du/rcar_du_plane.c b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
index d445e67f78e1..bfe31ca870cc 100644
--- a/drivers/gpu/drm/rcar-du/rcar_du_plane.c
+++ b/drivers/gpu/drm/rcar-du/rcar_du_plane.c
@@ -140,18 +140,17 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
140 bool needs_realloc = false; 140 bool needs_realloc = false;
141 unsigned int groups = 0; 141 unsigned int groups = 0;
142 unsigned int i; 142 unsigned int i;
143 struct drm_plane *drm_plane;
144 struct drm_plane_state *drm_plane_state;
143 145
144 /* Check if hardware planes need to be reallocated. */ 146 /* Check if hardware planes need to be reallocated. */
145 for (i = 0; i < dev->mode_config.num_total_plane; ++i) { 147 for_each_plane_in_state(state, drm_plane, drm_plane_state, i) {
146 struct rcar_du_plane_state *plane_state; 148 struct rcar_du_plane_state *plane_state;
147 struct rcar_du_plane *plane; 149 struct rcar_du_plane *plane;
148 unsigned int index; 150 unsigned int index;
149 151
150 if (!state->planes[i]) 152 plane = to_rcar_plane(drm_plane);
151 continue; 153 plane_state = to_rcar_plane_state(drm_plane_state);
152
153 plane = to_rcar_plane(state->planes[i]);
154 plane_state = to_rcar_plane_state(state->plane_states[i]);
155 154
156 dev_dbg(rcdu->dev, "%s: checking plane (%u,%tu)\n", __func__, 155 dev_dbg(rcdu->dev, "%s: checking plane (%u,%tu)\n", __func__,
157 plane->group->index, plane - plane->group->planes); 156 plane->group->index, plane - plane->group->planes);
@@ -247,18 +246,15 @@ int rcar_du_atomic_check_planes(struct drm_device *dev,
247 } 246 }
248 247
249 /* Reallocate hardware planes for each plane that needs it. */ 248 /* Reallocate hardware planes for each plane that needs it. */
250 for (i = 0; i < dev->mode_config.num_total_plane; ++i) { 249 for_each_plane_in_state(state, drm_plane, drm_plane_state, i) {
251 struct rcar_du_plane_state *plane_state; 250 struct rcar_du_plane_state *plane_state;
252 struct rcar_du_plane *plane; 251 struct rcar_du_plane *plane;
253 unsigned int crtc_planes; 252 unsigned int crtc_planes;
254 unsigned int free; 253 unsigned int free;
255 int idx; 254 int idx;
256 255
257 if (!state->planes[i]) 256 plane = to_rcar_plane(drm_plane);
258 continue; 257 plane_state = to_rcar_plane_state(drm_plane_state);
259
260 plane = to_rcar_plane(state->planes[i]);
261 plane_state = to_rcar_plane_state(state->plane_states[i]);
262 258
263 dev_dbg(rcdu->dev, "%s: allocating plane (%u,%tu)\n", __func__, 259 dev_dbg(rcdu->dev, "%s: allocating plane (%u,%tu)\n", __func__,
264 plane->group->index, plane - plane->group->planes); 260 plane->group->index, plane - plane->group->planes);
diff --git a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
index 1c4d5b5a70a2..5567fb43e674 100644
--- a/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
+++ b/drivers/gpu/drm/rockchip/rockchip_drm_vop.c
@@ -889,7 +889,7 @@ static void vop_crtc_cancel_pending_vblank(struct drm_crtc *crtc,
889 if (e && e->base.file_priv == file_priv) { 889 if (e && e->base.file_priv == file_priv) {
890 vop->event = NULL; 890 vop->event = NULL;
891 891
892 e->base.destroy(&e->base); 892 kfree(&e->base);
893 file_priv->event_space += sizeof(e->event); 893 file_priv->event_space += sizeof(e->event);
894 } 894 }
895 spin_unlock_irqrestore(&drm->event_lock, flags); 895 spin_unlock_irqrestore(&drm->event_lock, flags);
diff --git a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
index 1e154fc779d5..6547b1db460a 100644
--- a/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
+++ b/drivers/gpu/drm/shmobile/shmob_drm_crtc.c
@@ -441,7 +441,7 @@ void shmob_drm_crtc_finish_page_flip(struct shmob_drm_crtc *scrtc)
441 scrtc->event = NULL; 441 scrtc->event = NULL;
442 if (event) { 442 if (event) {
443 drm_crtc_send_vblank_event(&scrtc->crtc, event); 443 drm_crtc_send_vblank_event(&scrtc->crtc, event);
444 drm_vblank_put(dev, 0); 444 drm_crtc_vblank_put(&scrtc->crtc);
445 } 445 }
446 spin_unlock_irqrestore(&dev->event_lock, flags); 446 spin_unlock_irqrestore(&dev->event_lock, flags);
447} 447}
@@ -467,7 +467,7 @@ static int shmob_drm_crtc_page_flip(struct drm_crtc *crtc,
467 467
468 if (event) { 468 if (event) {
469 event->pipe = 0; 469 event->pipe = 0;
470 drm_vblank_get(dev, 0); 470 drm_crtc_vblank_get(&scrtc->crtc);
471 spin_lock_irqsave(&dev->event_lock, flags); 471 spin_lock_irqsave(&dev->event_lock, flags);
472 scrtc->event = event; 472 scrtc->event = event;
473 spin_unlock_irqrestore(&dev->event_lock, flags); 473 spin_unlock_irqrestore(&dev->event_lock, flags);
diff --git a/drivers/gpu/drm/udl/udl_modeset.c b/drivers/gpu/drm/udl/udl_modeset.c
index b87afee44995..f92ea9579674 100644
--- a/drivers/gpu/drm/udl/udl_modeset.c
+++ b/drivers/gpu/drm/udl/udl_modeset.c
@@ -376,7 +376,7 @@ static int udl_crtc_page_flip(struct drm_crtc *crtc,
376 376
377 spin_lock_irqsave(&dev->event_lock, flags); 377 spin_lock_irqsave(&dev->event_lock, flags);
378 if (event) 378 if (event)
379 drm_send_vblank_event(dev, 0, event); 379 drm_crtc_send_vblank_event(crtc, event);
380 spin_unlock_irqrestore(&dev->event_lock, flags); 380 spin_unlock_irqrestore(&dev->event_lock, flags);
381 crtc->primary->fb = fb; 381 crtc->primary->fb = fb;
382 382
diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c
index 904d0754ad78..4c0f26a644a3 100644
--- a/drivers/gpu/drm/vc4/vc4_crtc.c
+++ b/drivers/gpu/drm/vc4/vc4_crtc.c
@@ -175,20 +175,22 @@ vc4_crtc_lut_load(struct drm_crtc *crtc)
175 HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_b[i]); 175 HVS_WRITE(SCALER_GAMDATA, vc4_crtc->lut_b[i]);
176} 176}
177 177
178static void 178static int
179vc4_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, 179vc4_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
180 uint32_t start, uint32_t size) 180 uint32_t size)
181{ 181{
182 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); 182 struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
183 u32 i; 183 u32 i;
184 184
185 for (i = start; i < start + size; i++) { 185 for (i = 0; i < size; i++) {
186 vc4_crtc->lut_r[i] = r[i] >> 8; 186 vc4_crtc->lut_r[i] = r[i] >> 8;
187 vc4_crtc->lut_g[i] = g[i] >> 8; 187 vc4_crtc->lut_g[i] = g[i] >> 8;
188 vc4_crtc->lut_b[i] = b[i] >> 8; 188 vc4_crtc->lut_b[i] = b[i] >> 8;
189 } 189 }
190 190
191 vc4_crtc_lut_load(crtc); 191 vc4_crtc_lut_load(crtc);
192
193 return 0;
192} 194}
193 195
194static u32 vc4_get_fifo_full_level(u32 format) 196static u32 vc4_get_fifo_full_level(u32 format)
@@ -395,6 +397,7 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
395 struct vc4_dev *vc4 = to_vc4_dev(dev); 397 struct vc4_dev *vc4 = to_vc4_dev(dev);
396 struct drm_plane *plane; 398 struct drm_plane *plane;
397 unsigned long flags; 399 unsigned long flags;
400 const struct drm_plane_state *plane_state;
398 u32 dlist_count = 0; 401 u32 dlist_count = 0;
399 int ret; 402 int ret;
400 403
@@ -404,18 +407,8 @@ static int vc4_crtc_atomic_check(struct drm_crtc *crtc,
404 if (hweight32(state->connector_mask) > 1) 407 if (hweight32(state->connector_mask) > 1)
405 return -EINVAL; 408 return -EINVAL;
406 409
407 drm_atomic_crtc_state_for_each_plane(plane, state) { 410 drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, state)
408 struct drm_plane_state *plane_state =
409 state->state->plane_states[drm_plane_index(plane)];
410
411 /* plane might not have changed, in which case take
412 * current state:
413 */
414 if (!plane_state)
415 plane_state = plane->state;
416
417 dlist_count += vc4_plane_dlist_size(plane_state); 411 dlist_count += vc4_plane_dlist_size(plane_state);
418 }
419 412
420 dlist_count++; /* Account for SCALER_CTL0_END. */ 413 dlist_count++; /* Account for SCALER_CTL0_END. */
421 414
diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h
index 37cac59401d7..c799baabc008 100644
--- a/drivers/gpu/drm/vc4/vc4_drv.h
+++ b/drivers/gpu/drm/vc4/vc4_drv.h
@@ -469,7 +469,7 @@ int vc4_kms_load(struct drm_device *dev);
469struct drm_plane *vc4_plane_init(struct drm_device *dev, 469struct drm_plane *vc4_plane_init(struct drm_device *dev,
470 enum drm_plane_type type); 470 enum drm_plane_type type);
471u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist); 471u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
472u32 vc4_plane_dlist_size(struct drm_plane_state *state); 472u32 vc4_plane_dlist_size(const struct drm_plane_state *state);
473void vc4_plane_async_set_fb(struct drm_plane *plane, 473void vc4_plane_async_set_fb(struct drm_plane *plane,
474 struct drm_framebuffer *fb); 474 struct drm_framebuffer *fb);
475 475
diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c
index cb37751bc99f..39c0b2048bfd 100644
--- a/drivers/gpu/drm/vc4/vc4_kms.c
+++ b/drivers/gpu/drm/vc4/vc4_kms.c
@@ -111,6 +111,8 @@ static int vc4_atomic_commit(struct drm_device *dev,
111 int i; 111 int i;
112 uint64_t wait_seqno = 0; 112 uint64_t wait_seqno = 0;
113 struct vc4_commit *c; 113 struct vc4_commit *c;
114 struct drm_plane *plane;
115 struct drm_plane_state *new_state;
114 116
115 c = commit_init(state); 117 c = commit_init(state);
116 if (!c) 118 if (!c)
@@ -130,13 +132,7 @@ static int vc4_atomic_commit(struct drm_device *dev,
130 return ret; 132 return ret;
131 } 133 }
132 134
133 for (i = 0; i < dev->mode_config.num_total_plane; i++) { 135 for_each_plane_in_state(state, plane, new_state, i) {
134 struct drm_plane *plane = state->planes[i];
135 struct drm_plane_state *new_state = state->plane_states[i];
136
137 if (!plane)
138 continue;
139
140 if ((plane->state->fb != new_state->fb) && new_state->fb) { 136 if ((plane->state->fb != new_state->fb) && new_state->fb) {
141 struct drm_gem_cma_object *cma_bo = 137 struct drm_gem_cma_object *cma_bo =
142 drm_fb_cma_get_gem_obj(new_state->fb, 0); 138 drm_fb_cma_get_gem_obj(new_state->fb, 0);
diff --git a/drivers/gpu/drm/vc4/vc4_plane.c b/drivers/gpu/drm/vc4/vc4_plane.c
index 4037b52fde31..5d2c3d9fd17a 100644
--- a/drivers/gpu/drm/vc4/vc4_plane.c
+++ b/drivers/gpu/drm/vc4/vc4_plane.c
@@ -690,9 +690,10 @@ u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist)
690 return vc4_state->dlist_count; 690 return vc4_state->dlist_count;
691} 691}
692 692
693u32 vc4_plane_dlist_size(struct drm_plane_state *state) 693u32 vc4_plane_dlist_size(const struct drm_plane_state *state)
694{ 694{
695 struct vc4_plane_state *vc4_state = to_vc4_plane_state(state); 695 const struct vc4_plane_state *vc4_state =
696 container_of(state, typeof(*vc4_state), base);
696 697
697 return vc4_state->dlist_count; 698 return vc4_state->dlist_count;
698} 699}
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
index d4305da88f44..ba5e11ba9f3a 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -156,7 +156,7 @@ static int virtio_gpu_page_flip(struct drm_crtc *crtc,
156 156
157 if (event) { 157 if (event) {
158 spin_lock_irqsave(&crtc->dev->event_lock, irqflags); 158 spin_lock_irqsave(&crtc->dev->event_lock, irqflags);
159 drm_send_vblank_event(crtc->dev, -1, event); 159 drm_crtc_send_vblank_event(crtc, event);
160 spin_unlock_irqrestore(&crtc->dev->event_lock, irqflags); 160 spin_unlock_irqrestore(&crtc->dev->event_lock, irqflags);
161 } 161 }
162 162
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
index e959df6ede83..26ac8e80a478 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c
@@ -46,7 +46,7 @@ struct vmw_fence_manager {
46 bool goal_irq_on; /* Protected by @goal_irq_mutex */ 46 bool goal_irq_on; /* Protected by @goal_irq_mutex */
47 bool seqno_valid; /* Protected by @lock, and may not be set to true 47 bool seqno_valid; /* Protected by @lock, and may not be set to true
48 without the @goal_irq_mutex held. */ 48 without the @goal_irq_mutex held. */
49 unsigned ctx; 49 u64 ctx;
50}; 50};
51 51
52struct vmw_user_fence { 52struct vmw_user_fence {
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
index 55231cce73a0..8a69d4da40b5 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
@@ -1404,9 +1404,9 @@ static int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num,
1404 return 0; 1404 return 0;
1405} 1405}
1406 1406
1407void vmw_du_crtc_gamma_set(struct drm_crtc *crtc, 1407int vmw_du_crtc_gamma_set(struct drm_crtc *crtc,
1408 u16 *r, u16 *g, u16 *b, 1408 u16 *r, u16 *g, u16 *b,
1409 uint32_t start, uint32_t size) 1409 uint32_t size)
1410{ 1410{
1411 struct vmw_private *dev_priv = vmw_priv(crtc->dev); 1411 struct vmw_private *dev_priv = vmw_priv(crtc->dev);
1412 int i; 1412 int i;
@@ -1418,6 +1418,8 @@ void vmw_du_crtc_gamma_set(struct drm_crtc *crtc,
1418 vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 1, g[i] >> 8); 1418 vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 1, g[i] >> 8);
1419 vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 2, b[i] >> 8); 1419 vmw_write(dev_priv, SVGA_PALETTE_BASE + i * 3 + 2, b[i] >> 8);
1420 } 1420 }
1421
1422 return 0;
1421} 1423}
1422 1424
1423int vmw_du_connector_dpms(struct drm_connector *connector, int mode) 1425int vmw_du_connector_dpms(struct drm_connector *connector, int mode)
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
index 57203212c501..ff4803c107bc 100644
--- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
+++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
@@ -195,9 +195,9 @@ struct vmw_display_unit {
195void vmw_du_cleanup(struct vmw_display_unit *du); 195void vmw_du_cleanup(struct vmw_display_unit *du);
196void vmw_du_crtc_save(struct drm_crtc *crtc); 196void vmw_du_crtc_save(struct drm_crtc *crtc);
197void vmw_du_crtc_restore(struct drm_crtc *crtc); 197void vmw_du_crtc_restore(struct drm_crtc *crtc);
198void vmw_du_crtc_gamma_set(struct drm_crtc *crtc, 198int vmw_du_crtc_gamma_set(struct drm_crtc *crtc,
199 u16 *r, u16 *g, u16 *b, 199 u16 *r, u16 *g, u16 *b,
200 uint32_t start, uint32_t size); 200 uint32_t size);
201int vmw_du_crtc_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv, 201int vmw_du_crtc_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
202 uint32_t handle, uint32_t width, uint32_t height, 202 uint32_t handle, uint32_t width, uint32_t height,
203 int32_t hot_x, int32_t hot_y); 203 int32_t hot_x, int32_t hot_y);
diff --git a/drivers/staging/android/sync.h b/drivers/staging/android/sync.h
index b56885c14839..ebb34dca60df 100644
--- a/drivers/staging/android/sync.h
+++ b/drivers/staging/android/sync.h
@@ -68,7 +68,8 @@ struct sync_timeline {
68 68
69 /* protected by child_list_lock */ 69 /* protected by child_list_lock */
70 bool destroyed; 70 bool destroyed;
71 int context, value; 71 u64 context;
72 int value;
72 73
73 struct list_head child_list_head; 74 struct list_head child_list_head;
74 spinlock_t child_list_lock; 75 spinlock_t child_list_lock;
diff --git a/include/drm/drmP.h b/include/drm/drmP.h
index c5d29505f937..9e5eefd6f733 100644
--- a/include/drm/drmP.h
+++ b/include/drm/drmP.h
@@ -57,6 +57,7 @@
57#include <linux/types.h> 57#include <linux/types.h>
58#include <linux/vmalloc.h> 58#include <linux/vmalloc.h>
59#include <linux/workqueue.h> 59#include <linux/workqueue.h>
60#include <linux/fence.h>
60 61
61#include <asm/mman.h> 62#include <asm/mman.h>
62#include <asm/pgalloc.h> 63#include <asm/pgalloc.h>
@@ -283,12 +284,12 @@ struct drm_ioctl_desc {
283/* Event queued up for userspace to read */ 284/* Event queued up for userspace to read */
284struct drm_pending_event { 285struct drm_pending_event {
285 struct drm_event *event; 286 struct drm_event *event;
287 struct fence *fence;
286 struct list_head link; 288 struct list_head link;
287 struct list_head pending_link; 289 struct list_head pending_link;
288 struct drm_file *file_priv; 290 struct drm_file *file_priv;
289 pid_t pid; /* pid of requester, no guarantee it's valid by the time 291 pid_t pid; /* pid of requester, no guarantee it's valid by the time
290 we deliver the event, for tracing only */ 292 we deliver the event, for tracing only */
291 void (*destroy)(struct drm_pending_event *event);
292}; 293};
293 294
294/* initial implementaton using a linked list - todo hashtab */ 295/* initial implementaton using a linked list - todo hashtab */
@@ -430,7 +431,7 @@ struct drm_driver {
430 * 431 *
431 * Driver callback for fetching a raw hardware vblank counter for @crtc. 432 * Driver callback for fetching a raw hardware vblank counter for @crtc.
432 * If a device doesn't have a hardware counter, the driver can simply 433 * If a device doesn't have a hardware counter, the driver can simply
433 * return the value of drm_vblank_count. The DRM core will account for 434 * use drm_vblank_no_hw_counter() function. The DRM core will account for
434 * missed vblank events while interrupts where disabled based on system 435 * missed vblank events while interrupts where disabled based on system
435 * timestamps. 436 * timestamps.
436 * 437 *
@@ -448,8 +449,8 @@ struct drm_driver {
448 * @pipe: which irq to enable 449 * @pipe: which irq to enable
449 * 450 *
450 * Enable vblank interrupts for @crtc. If the device doesn't have 451 * Enable vblank interrupts for @crtc. If the device doesn't have
451 * a hardware vblank counter, this routine should be a no-op, since 452 * a hardware vblank counter, the driver should use the
452 * interrupts will have to stay on to keep the count accurate. 453 * drm_vblank_no_hw_counter() function that keeps a virtual counter.
453 * 454 *
454 * RETURNS 455 * RETURNS
455 * Zero on success, appropriate errno if the given @crtc's vblank 456 * Zero on success, appropriate errno if the given @crtc's vblank
@@ -463,8 +464,8 @@ struct drm_driver {
463 * @pipe: which irq to enable 464 * @pipe: which irq to enable
464 * 465 *
465 * Disable vblank interrupts for @crtc. If the device doesn't have 466 * Disable vblank interrupts for @crtc. If the device doesn't have
466 * a hardware vblank counter, this routine should be a no-op, since 467 * a hardware vblank counter, the driver should use the
467 * interrupts will have to stay on to keep the count accurate. 468 * drm_vblank_no_hw_counter() function that keeps a virtual counter.
468 */ 469 */
469 void (*disable_vblank) (struct drm_device *dev, unsigned int pipe); 470 void (*disable_vblank) (struct drm_device *dev, unsigned int pipe);
470 471
diff --git a/include/drm/drm_atomic.h b/include/drm/drm_atomic.h
index 92c84e9ab09a..d12cfb9c6062 100644
--- a/include/drm/drm_atomic.h
+++ b/include/drm/drm_atomic.h
@@ -71,7 +71,7 @@ static inline struct drm_crtc_state *
71drm_atomic_get_existing_crtc_state(struct drm_atomic_state *state, 71drm_atomic_get_existing_crtc_state(struct drm_atomic_state *state,
72 struct drm_crtc *crtc) 72 struct drm_crtc *crtc)
73{ 73{
74 return state->crtc_states[drm_crtc_index(crtc)]; 74 return state->crtcs[drm_crtc_index(crtc)].state;
75} 75}
76 76
77/** 77/**
@@ -86,7 +86,7 @@ static inline struct drm_plane_state *
86drm_atomic_get_existing_plane_state(struct drm_atomic_state *state, 86drm_atomic_get_existing_plane_state(struct drm_atomic_state *state,
87 struct drm_plane *plane) 87 struct drm_plane *plane)
88{ 88{
89 return state->plane_states[drm_plane_index(plane)]; 89 return state->planes[drm_plane_index(plane)].state;
90} 90}
91 91
92/** 92/**
@@ -106,7 +106,43 @@ drm_atomic_get_existing_connector_state(struct drm_atomic_state *state,
106 if (index >= state->num_connector) 106 if (index >= state->num_connector)
107 return NULL; 107 return NULL;
108 108
109 return state->connector_states[index]; 109 return state->connectors[index].state;
110}
111
112/**
113 * __drm_atomic_get_current_plane_state - get current plane state
114 * @state: global atomic state object
115 * @plane: plane to grab
116 *
117 * This function returns the plane state for the given plane, either from
118 * @state, or if the plane isn't part of the atomic state update, from @plane.
119 * This is useful in atomic check callbacks, when drivers need to peek at, but
120 * not change, state of other planes, since it avoids threading an error code
121 * back up the call chain.
122 *
123 * WARNING:
124 *
125 * Note that this function is in general unsafe since it doesn't check for the
126 * required locking for access state structures. Drivers must ensure that it is
127 * safe to access the returned state structure through other means. One common
128 * example is when planes are fixed to a single CRTC, and the driver knows that
129 * the CRTC lock is held already. In that case holding the CRTC lock gives a
130 * read-lock on all planes connected to that CRTC. But if planes can be
131 * reassigned things get more tricky. In that case it's better to use
132 * drm_atomic_get_plane_state and wire up full error handling.
133 *
134 * Returns:
135 *
136 * Read-only pointer to the current plane state.
137 */
138static inline const struct drm_plane_state *
139__drm_atomic_get_current_plane_state(struct drm_atomic_state *state,
140 struct drm_plane *plane)
141{
142 if (state->planes[drm_plane_index(plane)].state)
143 return state->planes[drm_plane_index(plane)].state;
144
145 return plane->state;
110} 146}
111 147
112int __must_check 148int __must_check
@@ -139,27 +175,27 @@ int __must_check drm_atomic_check_only(struct drm_atomic_state *state);
139int __must_check drm_atomic_commit(struct drm_atomic_state *state); 175int __must_check drm_atomic_commit(struct drm_atomic_state *state);
140int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state); 176int __must_check drm_atomic_nonblocking_commit(struct drm_atomic_state *state);
141 177
142#define for_each_connector_in_state(state, connector, connector_state, __i) \ 178#define for_each_connector_in_state(__state, connector, connector_state, __i) \
143 for ((__i) = 0; \ 179 for ((__i) = 0; \
144 (__i) < (state)->num_connector && \ 180 (__i) < (__state)->num_connector && \
145 ((connector) = (state)->connectors[__i], \ 181 ((connector) = (__state)->connectors[__i].ptr, \
146 (connector_state) = (state)->connector_states[__i], 1); \ 182 (connector_state) = (__state)->connectors[__i].state, 1); \
147 (__i)++) \ 183 (__i)++) \
148 for_each_if (connector) 184 for_each_if (connector)
149 185
150#define for_each_crtc_in_state(state, crtc, crtc_state, __i) \ 186#define for_each_crtc_in_state(__state, crtc, crtc_state, __i) \
151 for ((__i) = 0; \ 187 for ((__i) = 0; \
152 (__i) < (state)->dev->mode_config.num_crtc && \ 188 (__i) < (__state)->dev->mode_config.num_crtc && \
153 ((crtc) = (state)->crtcs[__i], \ 189 ((crtc) = (__state)->crtcs[__i].ptr, \
154 (crtc_state) = (state)->crtc_states[__i], 1); \ 190 (crtc_state) = (__state)->crtcs[__i].state, 1); \
155 (__i)++) \ 191 (__i)++) \
156 for_each_if (crtc_state) 192 for_each_if (crtc_state)
157 193
158#define for_each_plane_in_state(state, plane, plane_state, __i) \ 194#define for_each_plane_in_state(__state, plane, plane_state, __i) \
159 for ((__i) = 0; \ 195 for ((__i) = 0; \
160 (__i) < (state)->dev->mode_config.num_total_plane && \ 196 (__i) < (__state)->dev->mode_config.num_total_plane && \
161 ((plane) = (state)->planes[__i], \ 197 ((plane) = (__state)->planes[__i].ptr, \
162 (plane_state) = (state)->plane_states[__i], 1); \ 198 (plane_state) = (__state)->planes[__i].state, 1); \
163 (__i)++) \ 199 (__i)++) \
164 for_each_if (plane_state) 200 for_each_if (plane_state)
165static inline bool 201static inline bool
diff --git a/include/drm/drm_atomic_helper.h b/include/drm/drm_atomic_helper.h
index d473dcc91f54..1877a7c18d8e 100644
--- a/include/drm/drm_atomic_helper.h
+++ b/include/drm/drm_atomic_helper.h
@@ -147,9 +147,9 @@ void
147__drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state); 147__drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state);
148void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector, 148void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
149 struct drm_connector_state *state); 149 struct drm_connector_state *state);
150void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc, 150int drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
151 u16 *red, u16 *green, u16 *blue, 151 u16 *red, u16 *green, u16 *blue,
152 uint32_t start, uint32_t size); 152 uint32_t size);
153 153
154/** 154/**
155 * drm_atomic_crtc_for_each_plane - iterate over planes currently attached to CRTC 155 * drm_atomic_crtc_for_each_plane - iterate over planes currently attached to CRTC
@@ -159,7 +159,7 @@ void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
159 * This iterates over the current state, useful (for example) when applying 159 * This iterates over the current state, useful (for example) when applying
160 * atomic state after it has been checked and swapped. To iterate over the 160 * atomic state after it has been checked and swapped. To iterate over the
161 * planes which *will* be attached (for ->atomic_check()) see 161 * planes which *will* be attached (for ->atomic_check()) see
162 * drm_crtc_for_each_pending_plane() 162 * drm_crtc_for_each_pending_plane().
163 */ 163 */
164#define drm_atomic_crtc_for_each_plane(plane, crtc) \ 164#define drm_atomic_crtc_for_each_plane(plane, crtc) \
165 drm_for_each_plane_mask(plane, (crtc)->dev, (crtc)->state->plane_mask) 165 drm_for_each_plane_mask(plane, (crtc)->dev, (crtc)->state->plane_mask)
@@ -171,11 +171,31 @@ void drm_atomic_helper_legacy_gamma_set(struct drm_crtc *crtc,
171 * 171 *
172 * Similar to drm_crtc_for_each_plane(), but iterates the planes that will be 172 * Similar to drm_crtc_for_each_plane(), but iterates the planes that will be
173 * attached if the specified state is applied. Useful during (for example) 173 * attached if the specified state is applied. Useful during (for example)
174 * ->atomic_check() operations, to validate the incoming state 174 * ->atomic_check() operations, to validate the incoming state.
175 */ 175 */
176#define drm_atomic_crtc_state_for_each_plane(plane, crtc_state) \ 176#define drm_atomic_crtc_state_for_each_plane(plane, crtc_state) \
177 drm_for_each_plane_mask(plane, (crtc_state)->state->dev, (crtc_state)->plane_mask) 177 drm_for_each_plane_mask(plane, (crtc_state)->state->dev, (crtc_state)->plane_mask)
178 178
179/**
180 * drm_crtc_atomic_state_for_each_plane_state - iterate over attached planes in new state
181 * @plane: the loop cursor
182 * @plane_state: loop cursor for the plane's state, must be const
183 * @crtc_state: the incoming crtc-state
184 *
185 * Similar to drm_crtc_for_each_plane(), but iterates the planes that will be
186 * attached if the specified state is applied. Useful during (for example)
187 * ->atomic_check() operations, to validate the incoming state.
188 *
189 * Compared to just drm_atomic_crtc_state_for_each_plane() this also fills in a
190 * const plane_state. This is useful when a driver just wants to peek at other
191 * active planes on this crtc, but does not need to change it.
192 */
193#define drm_atomic_crtc_state_for_each_plane_state(plane, plane_state, crtc_state) \
194 drm_for_each_plane_mask(plane, (crtc_state)->state->dev, (crtc_state)->plane_mask) \
195 for_each_if ((plane_state = \
196 __drm_atomic_get_current_plane_state((crtc_state)->state, \
197 plane)))
198
179/* 199/*
180 * drm_atomic_plane_disabling - check whether a plane is being disabled 200 * drm_atomic_plane_disabling - check whether a plane is being disabled
181 * @plane: plane object 201 * @plane: plane object
diff --git a/include/drm/drm_crtc.h b/include/drm/drm_crtc.h
index d1559cd04e3d..411be4f45506 100644
--- a/include/drm/drm_crtc.h
+++ b/include/drm/drm_crtc.h
@@ -314,6 +314,7 @@ struct drm_plane_helper_funcs;
314 * update to ensure framebuffer cleanup isn't done too early 314 * update to ensure framebuffer cleanup isn't done too early
315 * @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings 315 * @adjusted_mode: for use by helpers and drivers to compute adjusted mode timings
316 * @mode: current mode timings 316 * @mode: current mode timings
317 * @mode_blob: &drm_property_blob for @mode
317 * @degamma_lut: Lookup table for converting framebuffer pixel data 318 * @degamma_lut: Lookup table for converting framebuffer pixel data
318 * before apply the conversion matrix 319 * before apply the conversion matrix
319 * @ctm: Transformation matrix 320 * @ctm: Transformation matrix
@@ -478,8 +479,8 @@ struct drm_crtc_funcs {
478 * going on, which should eventually be unified to just one set of 479 * going on, which should eventually be unified to just one set of
479 * hooks. 480 * hooks.
480 */ 481 */
481 void (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, 482 int (*gamma_set)(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b,
482 uint32_t start, uint32_t size); 483 uint32_t size);
483 484
484 /** 485 /**
485 * @destroy: 486 * @destroy:
@@ -708,6 +709,7 @@ struct drm_crtc_funcs {
708 * @dev: parent DRM device 709 * @dev: parent DRM device
709 * @port: OF node used by drm_of_find_possible_crtcs() 710 * @port: OF node used by drm_of_find_possible_crtcs()
710 * @head: list management 711 * @head: list management
712 * @name: human readable name, can be overwritten by the driver
711 * @mutex: per-CRTC locking 713 * @mutex: per-CRTC locking
712 * @base: base KMS object for ID tracking etc. 714 * @base: base KMS object for ID tracking etc.
713 * @primary: primary plane for this CRTC 715 * @primary: primary plane for this CRTC
@@ -738,12 +740,13 @@ struct drm_crtc {
738 740
739 char *name; 741 char *name;
740 742
741 /* 743 /**
742 * crtc mutex 744 * @mutex:
743 * 745 *
744 * This provides a read lock for the overall crtc state (mode, dpms 746 * This provides a read lock for the overall crtc state (mode, dpms
745 * state, ...) and a write lock for everything which can be update 747 * state, ...) and a write lock for everything which can be update
746 * without a full modeset (fb, cursor data, ...) 748 * without a full modeset (fb, cursor data, crtc properties ...). Full
749 * modeset also need to grab dev->mode_config.connection_mutex.
747 */ 750 */
748 struct drm_modeset_lock mutex; 751 struct drm_modeset_lock mutex;
749 752
@@ -753,6 +756,9 @@ struct drm_crtc {
753 struct drm_plane *primary; 756 struct drm_plane *primary;
754 struct drm_plane *cursor; 757 struct drm_plane *cursor;
755 758
759 /* position inside the mode_config.list, can be used as a [] idx */
760 unsigned index;
761
756 /* position of cursor plane on crtc */ 762 /* position of cursor plane on crtc */
757 int cursor_x; 763 int cursor_x;
758 int cursor_y; 764 int cursor_y;
@@ -1078,7 +1084,7 @@ struct drm_encoder_funcs {
1078 * @dev: parent DRM device 1084 * @dev: parent DRM device
1079 * @head: list management 1085 * @head: list management
1080 * @base: base KMS object 1086 * @base: base KMS object
1081 * @name: encoder name 1087 * @name: human readable name, can be overwritten by the driver
1082 * @encoder_type: one of the %DRM_MODE_ENCODER_<foo> types in drm_mode.h 1088 * @encoder_type: one of the %DRM_MODE_ENCODER_<foo> types in drm_mode.h
1083 * @possible_crtcs: bitmask of potential CRTC bindings 1089 * @possible_crtcs: bitmask of potential CRTC bindings
1084 * @possible_clones: bitmask of potential sibling encoders for cloning 1090 * @possible_clones: bitmask of potential sibling encoders for cloning
@@ -1097,6 +1103,10 @@ struct drm_encoder {
1097 struct drm_mode_object base; 1103 struct drm_mode_object base;
1098 char *name; 1104 char *name;
1099 int encoder_type; 1105 int encoder_type;
1106
1107 /* position inside the mode_config.list, can be used as a [] idx */
1108 unsigned index;
1109
1100 uint32_t possible_crtcs; 1110 uint32_t possible_crtcs;
1101 uint32_t possible_clones; 1111 uint32_t possible_clones;
1102 1112
@@ -1124,7 +1134,8 @@ struct drm_encoder {
1124 * @attr: sysfs attributes 1134 * @attr: sysfs attributes
1125 * @head: list management 1135 * @head: list management
1126 * @base: base KMS object 1136 * @base: base KMS object
1127 * @name: connector name 1137 * @name: human readable name, can be overwritten by the driver
1138 * @connector_id: compacted connector id useful indexing arrays
1128 * @connector_type: one of the %DRM_MODE_CONNECTOR_<foo> types from drm_mode.h 1139 * @connector_type: one of the %DRM_MODE_CONNECTOR_<foo> types from drm_mode.h
1129 * @connector_type_id: index into connector type enum 1140 * @connector_type_id: index into connector type enum
1130 * @interlace_allowed: can this connector handle interlaced modes? 1141 * @interlace_allowed: can this connector handle interlaced modes?
@@ -1137,7 +1148,6 @@ struct drm_encoder {
1137 * @funcs: connector control functions 1148 * @funcs: connector control functions
1138 * @edid_blob_ptr: DRM property containing EDID if present 1149 * @edid_blob_ptr: DRM property containing EDID if present
1139 * @properties: property tracking for this connector 1150 * @properties: property tracking for this connector
1140 * @path_blob_ptr: DRM blob property data for the DP MST path property
1141 * @polled: a %DRM_CONNECTOR_POLL_<foo> value for core driven polling 1151 * @polled: a %DRM_CONNECTOR_POLL_<foo> value for core driven polling
1142 * @dpms: current dpms state 1152 * @dpms: current dpms state
1143 * @helper_private: mid-layer private data 1153 * @helper_private: mid-layer private data
@@ -1200,8 +1210,23 @@ struct drm_connector {
1200 struct drm_property_blob *edid_blob_ptr; 1210 struct drm_property_blob *edid_blob_ptr;
1201 struct drm_object_properties properties; 1211 struct drm_object_properties properties;
1202 1212
1213 /**
1214 * @path_blob_ptr:
1215 *
1216 * DRM blob property data for the DP MST path property.
1217 */
1203 struct drm_property_blob *path_blob_ptr; 1218 struct drm_property_blob *path_blob_ptr;
1204 1219
1220 /**
1221 * @tile_blob_ptr:
1222 *
1223 * DRM blob property data for the tile property (used mostly by DP MST).
1224 * This is meant for screens which are driven through separate display
1225 * pipelines represented by &drm_crtc, which might not be running with
1226 * genlocked clocks. For tiled panels which are genlocked, like
1227 * dual-link LVDS or dual-link DSI, the driver should try to not expose
1228 * the tiling and virtualize both &drm_crtc and &drm_plane if needed.
1229 */
1205 struct drm_property_blob *tile_blob_ptr; 1230 struct drm_property_blob *tile_blob_ptr;
1206 1231
1207 uint8_t polled; /* DRM_CONNECTOR_POLL_* */ 1232 uint8_t polled; /* DRM_CONNECTOR_POLL_* */
@@ -1263,6 +1288,7 @@ struct drm_connector {
1263 * plane (in 16.16) 1288 * plane (in 16.16)
1264 * @src_w: width of visible portion of plane (in 16.16) 1289 * @src_w: width of visible portion of plane (in 16.16)
1265 * @src_h: height of visible portion of plane (in 16.16) 1290 * @src_h: height of visible portion of plane (in 16.16)
1291 * @rotation: rotation of the plane
1266 * @state: backpointer to global drm_atomic_state 1292 * @state: backpointer to global drm_atomic_state
1267 */ 1293 */
1268struct drm_plane_state { 1294struct drm_plane_state {
@@ -1503,6 +1529,7 @@ enum drm_plane_type {
1503 * struct drm_plane - central DRM plane control structure 1529 * struct drm_plane - central DRM plane control structure
1504 * @dev: DRM device this plane belongs to 1530 * @dev: DRM device this plane belongs to
1505 * @head: for list management 1531 * @head: for list management
1532 * @name: human readable name, can be overwritten by the driver
1506 * @base: base mode object 1533 * @base: base mode object
1507 * @possible_crtcs: pipes this plane can be bound to 1534 * @possible_crtcs: pipes this plane can be bound to
1508 * @format_types: array of formats supported by this plane 1535 * @format_types: array of formats supported by this plane
@@ -1516,6 +1543,7 @@ enum drm_plane_type {
1516 * @properties: property tracking for this plane 1543 * @properties: property tracking for this plane
1517 * @type: type of plane (overlay, primary, cursor) 1544 * @type: type of plane (overlay, primary, cursor)
1518 * @state: current atomic state for this plane 1545 * @state: current atomic state for this plane
1546 * @helper_private: mid-layer private data
1519 */ 1547 */
1520struct drm_plane { 1548struct drm_plane {
1521 struct drm_device *dev; 1549 struct drm_device *dev;
@@ -1523,6 +1551,13 @@ struct drm_plane {
1523 1551
1524 char *name; 1552 char *name;
1525 1553
1554 /**
1555 * @mutex:
1556 *
1557 * Protects modeset plane state, together with the mutex of &drm_crtc
1558 * this plane is linked to (when active, getting actived or getting
1559 * disabled).
1560 */
1526 struct drm_modeset_lock mutex; 1561 struct drm_modeset_lock mutex;
1527 1562
1528 struct drm_mode_object base; 1563 struct drm_mode_object base;
@@ -1543,6 +1578,9 @@ struct drm_plane {
1543 1578
1544 enum drm_plane_type type; 1579 enum drm_plane_type type;
1545 1580
1581 /* position inside the mode_config.list, can be used as a [] idx */
1582 unsigned index;
1583
1546 const struct drm_plane_helper_funcs *helper_private; 1584 const struct drm_plane_helper_funcs *helper_private;
1547 1585
1548 struct drm_plane_state *state; 1586 struct drm_plane_state *state;
@@ -1693,19 +1731,31 @@ struct drm_bridge {
1693 void *driver_private; 1731 void *driver_private;
1694}; 1732};
1695 1733
1734struct __drm_planes_state {
1735 struct drm_plane *ptr;
1736 struct drm_plane_state *state;
1737};
1738
1739struct __drm_crtcs_state {
1740 struct drm_crtc *ptr;
1741 struct drm_crtc_state *state;
1742};
1743
1744struct __drm_connnectors_state {
1745 struct drm_connector *ptr;
1746 struct drm_connector_state *state;
1747};
1748
1696/** 1749/**
1697 * struct drm_atomic_state - the global state object for atomic updates 1750 * struct drm_atomic_state - the global state object for atomic updates
1698 * @dev: parent DRM device 1751 * @dev: parent DRM device
1699 * @allow_modeset: allow full modeset 1752 * @allow_modeset: allow full modeset
1700 * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics 1753 * @legacy_cursor_update: hint to enforce legacy cursor IOCTL semantics
1701 * @legacy_set_config: Disable conflicting encoders instead of failing with -EINVAL. 1754 * @legacy_set_config: Disable conflicting encoders instead of failing with -EINVAL.
1702 * @planes: pointer to array of plane pointers 1755 * @planes: pointer to array of structures with per-plane data
1703 * @plane_states: pointer to array of plane states pointers
1704 * @crtcs: pointer to array of CRTC pointers 1756 * @crtcs: pointer to array of CRTC pointers
1705 * @crtc_states: pointer to array of CRTC states pointers
1706 * @num_connector: size of the @connectors and @connector_states arrays 1757 * @num_connector: size of the @connectors and @connector_states arrays
1707 * @connectors: pointer to array of connector pointers 1758 * @connectors: pointer to array of structures with per-connector data
1708 * @connector_states: pointer to array of connector states pointers
1709 * @acquire_ctx: acquire context for this atomic modeset state update 1759 * @acquire_ctx: acquire context for this atomic modeset state update
1710 */ 1760 */
1711struct drm_atomic_state { 1761struct drm_atomic_state {
@@ -1713,13 +1763,10 @@ struct drm_atomic_state {
1713 bool allow_modeset : 1; 1763 bool allow_modeset : 1;
1714 bool legacy_cursor_update : 1; 1764 bool legacy_cursor_update : 1;
1715 bool legacy_set_config : 1; 1765 bool legacy_set_config : 1;
1716 struct drm_plane **planes; 1766 struct __drm_planes_state *planes;
1717 struct drm_plane_state **plane_states; 1767 struct __drm_crtcs_state *crtcs;
1718 struct drm_crtc **crtcs;
1719 struct drm_crtc_state **crtc_states;
1720 int num_connector; 1768 int num_connector;
1721 struct drm_connector **connectors; 1769 struct __drm_connnectors_state *connectors;
1722 struct drm_connector_state **connector_states;
1723 1770
1724 struct drm_modeset_acquire_ctx *acquire_ctx; 1771 struct drm_modeset_acquire_ctx *acquire_ctx;
1725}; 1772};
@@ -2022,8 +2069,6 @@ struct drm_mode_config_funcs {
2022 * @connection_mutex: ww mutex protecting connector state and routing 2069 * @connection_mutex: ww mutex protecting connector state and routing
2023 * @acquire_ctx: global implicit acquire context used by atomic drivers for 2070 * @acquire_ctx: global implicit acquire context used by atomic drivers for
2024 * legacy IOCTLs 2071 * legacy IOCTLs
2025 * @idr_mutex: mutex for KMS ID allocation and management
2026 * @crtc_idr: main KMS ID tracking object
2027 * @fb_lock: mutex to protect fb state and lists 2072 * @fb_lock: mutex to protect fb state and lists
2028 * @num_fb: number of fbs available 2073 * @num_fb: number of fbs available
2029 * @fb_list: list of framebuffers available 2074 * @fb_list: list of framebuffers available
@@ -2045,6 +2090,7 @@ struct drm_mode_config_funcs {
2045 * @fb_base: base address of the framebuffer 2090 * @fb_base: base address of the framebuffer
2046 * @poll_enabled: track polling support for this device 2091 * @poll_enabled: track polling support for this device
2047 * @poll_running: track polling status for this device 2092 * @poll_running: track polling status for this device
2093 * @delayed_event: track delayed poll uevent deliver for this device
2048 * @output_poll_work: delayed work for polling in process context 2094 * @output_poll_work: delayed work for polling in process context
2049 * @property_blob_list: list of all the blob property objects 2095 * @property_blob_list: list of all the blob property objects
2050 * @blob_lock: mutex for blob property allocation and management 2096 * @blob_lock: mutex for blob property allocation and management
@@ -2072,10 +2118,30 @@ struct drm_mode_config {
2072 struct mutex mutex; /* protects configuration (mode lists etc.) */ 2118 struct mutex mutex; /* protects configuration (mode lists etc.) */
2073 struct drm_modeset_lock connection_mutex; /* protects connector->encoder and encoder->crtc links */ 2119 struct drm_modeset_lock connection_mutex; /* protects connector->encoder and encoder->crtc links */
2074 struct drm_modeset_acquire_ctx *acquire_ctx; /* for legacy _lock_all() / _unlock_all() */ 2120 struct drm_modeset_acquire_ctx *acquire_ctx; /* for legacy _lock_all() / _unlock_all() */
2075 struct mutex idr_mutex; /* for IDR management */ 2121
2076 struct idr crtc_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */ 2122 /**
2077 struct idr tile_idr; /* use this idr for all IDs, fb, crtc, connector, modes - just makes life easier */ 2123 * @idr_mutex:
2078 /* this is limited to one for now */ 2124 *
2125 * Mutex for KMS ID allocation and management. Protects both @crtc_idr
2126 * and @tile_idr.
2127 */
2128 struct mutex idr_mutex;
2129
2130 /**
2131 * @crtc_idr:
2132 *
2133 * Main KMS ID tracking object. Use this idr for all IDs, fb, crtc,
2134 * connector, modes - just makes life easier to have only one.
2135 */
2136 struct idr crtc_idr;
2137
2138 /**
2139 * @tile_idr:
2140 *
2141 * Use this idr for allocating new IDs for tiled sinks like use in some
2142 * high-res DP MST screens.
2143 */
2144 struct idr tile_idr;
2079 2145
2080 struct mutex fb_lock; /* proctects global and per-file fb lists */ 2146 struct mutex fb_lock; /* proctects global and per-file fb lists */
2081 int num_fb; 2147 int num_fb;
@@ -2177,7 +2243,11 @@ struct drm_mode_config {
2177 /* whether async page flip is supported or not */ 2243 /* whether async page flip is supported or not */
2178 bool async_page_flip; 2244 bool async_page_flip;
2179 2245
2180 /* whether the driver supports fb modifiers */ 2246 /**
2247 * @allow_fb_modifiers:
2248 *
2249 * Whether the driver supports fb modifiers in the ADDFB2.1 ioctl call.
2250 */
2181 bool allow_fb_modifiers; 2251 bool allow_fb_modifiers;
2182 2252
2183 /* cursor size */ 2253 /* cursor size */
@@ -2230,7 +2300,18 @@ int drm_crtc_init_with_planes(struct drm_device *dev,
2230 const struct drm_crtc_funcs *funcs, 2300 const struct drm_crtc_funcs *funcs,
2231 const char *name, ...); 2301 const char *name, ...);
2232extern void drm_crtc_cleanup(struct drm_crtc *crtc); 2302extern void drm_crtc_cleanup(struct drm_crtc *crtc);
2233extern unsigned int drm_crtc_index(struct drm_crtc *crtc); 2303
2304/**
2305 * drm_crtc_index - find the index of a registered CRTC
2306 * @crtc: CRTC to find index for
2307 *
2308 * Given a registered CRTC, return the index of that CRTC within a DRM
2309 * device's list of CRTCs.
2310 */
2311static inline unsigned int drm_crtc_index(struct drm_crtc *crtc)
2312{
2313 return crtc->index;
2314}
2234 2315
2235/** 2316/**
2236 * drm_crtc_mask - find the mask of a registered CRTC 2317 * drm_crtc_mask - find the mask of a registered CRTC
@@ -2284,7 +2365,18 @@ int drm_encoder_init(struct drm_device *dev,
2284 struct drm_encoder *encoder, 2365 struct drm_encoder *encoder,
2285 const struct drm_encoder_funcs *funcs, 2366 const struct drm_encoder_funcs *funcs,
2286 int encoder_type, const char *name, ...); 2367 int encoder_type, const char *name, ...);
2287extern unsigned int drm_encoder_index(struct drm_encoder *encoder); 2368
2369/**
2370 * drm_encoder_index - find the index of a registered encoder
2371 * @encoder: encoder to find index for
2372 *
2373 * Given a registered encoder, return the index of that encoder within a DRM
2374 * device's list of encoders.
2375 */
2376static inline unsigned int drm_encoder_index(struct drm_encoder *encoder)
2377{
2378 return encoder->index;
2379}
2288 2380
2289/** 2381/**
2290 * drm_encoder_crtc_ok - can a given crtc drive a given encoder? 2382 * drm_encoder_crtc_ok - can a given crtc drive a given encoder?
@@ -2315,7 +2407,18 @@ extern int drm_plane_init(struct drm_device *dev,
2315 const uint32_t *formats, unsigned int format_count, 2407 const uint32_t *formats, unsigned int format_count,
2316 bool is_primary); 2408 bool is_primary);
2317extern void drm_plane_cleanup(struct drm_plane *plane); 2409extern void drm_plane_cleanup(struct drm_plane *plane);
2318extern unsigned int drm_plane_index(struct drm_plane *plane); 2410
2411/**
2412 * drm_plane_index - find the index of a registered plane
2413 * @plane: plane to find index for
2414 *
2415 * Given a registered plane, return the index of that plane within a DRM
2416 * device's list of planes.
2417 */
2418static inline unsigned int drm_plane_index(struct drm_plane *plane)
2419{
2420 return plane->index;
2421}
2319extern struct drm_plane * drm_plane_from_index(struct drm_device *dev, int idx); 2422extern struct drm_plane * drm_plane_from_index(struct drm_device *dev, int idx);
2320extern void drm_plane_force_disable(struct drm_plane *plane); 2423extern void drm_plane_force_disable(struct drm_plane *plane);
2321extern int drm_plane_check_pixel_format(const struct drm_plane *plane, 2424extern int drm_plane_check_pixel_format(const struct drm_plane *plane,
diff --git a/include/drm/drm_mipi_dsi.h b/include/drm/drm_mipi_dsi.h
index 7a9840f8b38e..ec552854a8f8 100644
--- a/include/drm/drm_mipi_dsi.h
+++ b/include/drm/drm_mipi_dsi.h
@@ -263,6 +263,7 @@ int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start,
263 u16 end); 263 u16 end);
264int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start, 264int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start,
265 u16 end); 265 u16 end);
266int mipi_dsi_set_tear_scanline(struct mipi_dsi_device *dsi, u16 param);
266int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi); 267int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi);
267int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi, 268int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
268 enum mipi_dsi_dcs_tear_mode mode); 269 enum mipi_dsi_dcs_tear_mode mode);
diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h
index 625966a906f2..ff481770d76b 100644
--- a/include/drm/drm_modes.h
+++ b/include/drm/drm_modes.h
@@ -169,6 +169,8 @@ enum drm_mode_status {
169 * 169 *
170 * The horizontal and vertical timings are defined per the following diagram. 170 * The horizontal and vertical timings are defined per the following diagram.
171 * 171 *
172 * ::
173 *
172 * 174 *
173 * Active Front Sync Back 175 * Active Front Sync Back
174 * Region Porch Porch 176 * Region Porch Porch
diff --git a/include/drm/drm_modeset_helper_vtables.h b/include/drm/drm_modeset_helper_vtables.h
index d4619dc2eecb..4e7a53b12632 100644
--- a/include/drm/drm_modeset_helper_vtables.h
+++ b/include/drm/drm_modeset_helper_vtables.h
@@ -736,6 +736,11 @@ struct drm_connector_helper_funcs {
736 * inspect dynamic configuration state should instead use 736 * inspect dynamic configuration state should instead use
737 * @atomic_best_encoder. 737 * @atomic_best_encoder.
738 * 738 *
739 * You can leave this function to NULL if the connector is only
740 * attached to a single encoder and you are using the atomic helpers.
741 * In this case, the core will call drm_atomic_helper_best_encoder()
742 * for you.
743 *
739 * RETURNS: 744 * RETURNS:
740 * 745 *
741 * Encoder that should be used for the given connector and connector 746 * Encoder that should be used for the given connector and connector
@@ -752,8 +757,9 @@ struct drm_connector_helper_funcs {
752 * need to select the best encoder depending upon the desired 757 * need to select the best encoder depending upon the desired
753 * configuration and can't select it statically. 758 * configuration and can't select it statically.
754 * 759 *
755 * This function is used by drm_atomic_helper_check_modeset() and either 760 * This function is used by drm_atomic_helper_check_modeset().
756 * this or @best_encoder is required. 761 * If it is not implemented, the core will fallback to @best_encoder
762 * (or drm_atomic_helper_best_encoder() if @best_encoder is NULL).
757 * 763 *
758 * NOTE: 764 * NOTE:
759 * 765 *
diff --git a/include/linux/fence-array.h b/include/linux/fence-array.h
new file mode 100644
index 000000000000..86baaa45567c
--- /dev/null
+++ b/include/linux/fence-array.h
@@ -0,0 +1,73 @@
1/*
2 * fence-array: aggregates fence to be waited together
3 *
4 * Copyright (C) 2016 Collabora Ltd
5 * Copyright (C) 2016 Advanced Micro Devices, Inc.
6 * Authors:
7 * Gustavo Padovan <gustavo@padovan.org>
8 * Christian König <christian.koenig@amd.com>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License version 2 as published by
12 * the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 */
19
20#ifndef __LINUX_FENCE_ARRAY_H
21#define __LINUX_FENCE_ARRAY_H
22
23#include <linux/fence.h>
24
25/**
26 * struct fence_array_cb - callback helper for fence array
27 * @cb: fence callback structure for signaling
28 * @array: reference to the parent fence array object
29 */
30struct fence_array_cb {
31 struct fence_cb cb;
32 struct fence_array *array;
33};
34
35/**
36 * struct fence_array - fence to represent an array of fences
37 * @base: fence base class
38 * @lock: spinlock for fence handling
39 * @num_fences: number of fences in the array
40 * @num_pending: fences in the array still pending
41 * @fences: array of the fences
42 */
43struct fence_array {
44 struct fence base;
45
46 spinlock_t lock;
47 unsigned num_fences;
48 atomic_t num_pending;
49 struct fence **fences;
50};
51
52extern const struct fence_ops fence_array_ops;
53
54/**
55 * to_fence_array - cast a fence to a fence_array
56 * @fence: fence to cast to a fence_array
57 *
58 * Returns NULL if the fence is not a fence_array,
59 * or the fence_array otherwise.
60 */
61static inline struct fence_array *to_fence_array(struct fence *fence)
62{
63 if (fence->ops != &fence_array_ops)
64 return NULL;
65
66 return container_of(fence, struct fence_array, base);
67}
68
69struct fence_array *fence_array_create(int num_fences, struct fence **fences,
70 u64 context, unsigned seqno,
71 bool signal_on_any);
72
73#endif /* __LINUX_FENCE_ARRAY_H */
diff --git a/include/linux/fence.h b/include/linux/fence.h
index 2056e9fd0138..44d945e96473 100644
--- a/include/linux/fence.h
+++ b/include/linux/fence.h
@@ -77,7 +77,8 @@ struct fence {
77 struct rcu_head rcu; 77 struct rcu_head rcu;
78 struct list_head cb_list; 78 struct list_head cb_list;
79 spinlock_t *lock; 79 spinlock_t *lock;
80 unsigned context, seqno; 80 u64 context;
81 unsigned seqno;
81 unsigned long flags; 82 unsigned long flags;
82 ktime_t timestamp; 83 ktime_t timestamp;
83 int status; 84 int status;
@@ -180,7 +181,7 @@ struct fence_ops {
180}; 181};
181 182
182void fence_init(struct fence *fence, const struct fence_ops *ops, 183void fence_init(struct fence *fence, const struct fence_ops *ops,
183 spinlock_t *lock, unsigned context, unsigned seqno); 184 spinlock_t *lock, u64 context, unsigned seqno);
184 185
185void fence_release(struct kref *kref); 186void fence_release(struct kref *kref);
186void fence_free(struct fence *fence); 187void fence_free(struct fence *fence);
@@ -354,27 +355,27 @@ static inline signed long fence_wait(struct fence *fence, bool intr)
354 return ret < 0 ? ret : 0; 355 return ret < 0 ? ret : 0;
355} 356}
356 357
357unsigned fence_context_alloc(unsigned num); 358u64 fence_context_alloc(unsigned num);
358 359
359#define FENCE_TRACE(f, fmt, args...) \ 360#define FENCE_TRACE(f, fmt, args...) \
360 do { \ 361 do { \
361 struct fence *__ff = (f); \ 362 struct fence *__ff = (f); \
362 if (config_enabled(CONFIG_FENCE_TRACE)) \ 363 if (config_enabled(CONFIG_FENCE_TRACE)) \
363 pr_info("f %u#%u: " fmt, \ 364 pr_info("f %llu#%u: " fmt, \
364 __ff->context, __ff->seqno, ##args); \ 365 __ff->context, __ff->seqno, ##args); \
365 } while (0) 366 } while (0)
366 367
367#define FENCE_WARN(f, fmt, args...) \ 368#define FENCE_WARN(f, fmt, args...) \
368 do { \ 369 do { \
369 struct fence *__ff = (f); \ 370 struct fence *__ff = (f); \
370 pr_warn("f %u#%u: " fmt, __ff->context, __ff->seqno, \ 371 pr_warn("f %llu#%u: " fmt, __ff->context, __ff->seqno, \
371 ##args); \ 372 ##args); \
372 } while (0) 373 } while (0)
373 374
374#define FENCE_ERR(f, fmt, args...) \ 375#define FENCE_ERR(f, fmt, args...) \
375 do { \ 376 do { \
376 struct fence *__ff = (f); \ 377 struct fence *__ff = (f); \
377 pr_err("f %u#%u: " fmt, __ff->context, __ff->seqno, \ 378 pr_err("f %llu#%u: " fmt, __ff->context, __ff->seqno, \
378 ##args); \ 379 ##args); \
379 } while (0) 380 } while (0)
380 381