aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/sti
diff options
context:
space:
mode:
authorBenjamin Gaignard <benjamin.gaignard@linaro.org>2015-03-19 08:35:16 -0400
committerBenjamin Gaignard <benjamin.gaignard@linaro.org>2015-03-19 08:35:16 -0400
commitde4b00b0937aba99b7099afc6ed17a81163faab3 (patch)
tree44eed007fbc8f17027d502ebba039533fc01965e /drivers/gpu/drm/sti
parent03be70050c85768e9ce7c0d0887110d1b629e127 (diff)
drm: sti: convert driver to atomic modeset
v1: This patch does the minimum to make sti driver use atomic helpers. No big bang, only adapt some functions to new call order. v2: Use dpms and page flip atomic helpers Signed-off-by: Benjamin Gaignard <benjamin.gaignard@linaro.org>
Diffstat (limited to 'drivers/gpu/drm/sti')
-rw-r--r--drivers/gpu/drm/sti/sti_drm_crtc.c175
-rw-r--r--drivers/gpu/drm/sti/sti_drm_drv.c86
-rw-r--r--drivers/gpu/drm/sti/sti_drm_drv.h6
-rw-r--r--drivers/gpu/drm/sti/sti_drm_plane.c66
-rw-r--r--drivers/gpu/drm/sti/sti_dvo.c6
-rw-r--r--drivers/gpu/drm/sti/sti_hda.c6
-rw-r--r--drivers/gpu/drm/sti/sti_hdmi.c6
7 files changed, 205 insertions, 146 deletions
diff --git a/drivers/gpu/drm/sti/sti_drm_crtc.c b/drivers/gpu/drm/sti/sti_drm_crtc.c
index e6f6ef7c4866..6b641c5a2ec7 100644
--- a/drivers/gpu/drm/sti/sti_drm_crtc.c
+++ b/drivers/gpu/drm/sti/sti_drm_crtc.c
@@ -9,6 +9,8 @@
9#include <linux/clk.h> 9#include <linux/clk.h>
10 10
11#include <drm/drmP.h> 11#include <drm/drmP.h>
12#include <drm/drm_atomic.h>
13#include <drm/drm_atomic_helper.h>
12#include <drm/drm_crtc_helper.h> 14#include <drm/drm_crtc_helper.h>
13#include <drm/drm_plane_helper.h> 15#include <drm/drm_plane_helper.h>
14 16
@@ -77,22 +79,18 @@ static bool sti_drm_crtc_mode_fixup(struct drm_crtc *crtc,
77} 79}
78 80
79static int 81static int
80sti_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode, 82sti_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode)
81 struct drm_display_mode *adjusted_mode, int x, int y,
82 struct drm_framebuffer *old_fb)
83{ 83{
84 struct sti_mixer *mixer = to_sti_mixer(crtc); 84 struct sti_mixer *mixer = to_sti_mixer(crtc);
85 struct device *dev = mixer->dev; 85 struct device *dev = mixer->dev;
86 struct sti_compositor *compo = dev_get_drvdata(dev); 86 struct sti_compositor *compo = dev_get_drvdata(dev);
87 struct sti_layer *layer;
88 struct clk *clk; 87 struct clk *clk;
89 int rate = mode->clock * 1000; 88 int rate = mode->clock * 1000;
90 int res; 89 int res;
91 unsigned int w, h;
92 90
93 DRM_DEBUG_KMS("CRTC:%d (%s) fb:%d mode:%d (%s)\n", 91 DRM_DEBUG_KMS("CRTC:%d (%s) mode:%d (%s)\n",
94 crtc->base.id, sti_mixer_to_str(mixer), 92 crtc->base.id, sti_mixer_to_str(mixer),
95 crtc->primary->fb->base.id, mode->base.id, mode->name); 93 mode->base.id, mode->name);
96 94
97 DRM_DEBUG_KMS("%d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n", 95 DRM_DEBUG_KMS("%d %d %d %d %d %d %d %d %d %d 0x%x 0x%x\n",
98 mode->vrefresh, mode->clock, 96 mode->vrefresh, mode->clock,
@@ -122,72 +120,13 @@ sti_drm_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
122 sti_vtg_set_config(mixer->id == STI_MIXER_MAIN ? 120 sti_vtg_set_config(mixer->id == STI_MIXER_MAIN ?
123 compo->vtg_main : compo->vtg_aux, &crtc->mode); 121 compo->vtg_main : compo->vtg_aux, &crtc->mode);
124 122
125 /* a GDP is reserved to the CRTC FB */
126 layer = to_sti_layer(crtc->primary);
127 if (!layer) {
128 DRM_ERROR("Can not find GDP0)\n");
129 return -EINVAL;
130 }
131
132 /* copy the mode data adjusted by mode_fixup() into crtc->mode
133 * so that hardware can be set to proper mode
134 */
135 memcpy(&crtc->mode, adjusted_mode, sizeof(*adjusted_mode));
136
137 res = sti_mixer_set_layer_depth(mixer, layer);
138 if (res) {
139 DRM_ERROR("Can not set layer depth\n");
140 return -EINVAL;
141 }
142 res = sti_mixer_active_video_area(mixer, &crtc->mode); 123 res = sti_mixer_active_video_area(mixer, &crtc->mode);
143 if (res) { 124 if (res) {
144 DRM_ERROR("Can not set active video area\n"); 125 DRM_ERROR("Can not set active video area\n");
145 return -EINVAL; 126 return -EINVAL;
146 } 127 }
147 128
148 w = crtc->primary->fb->width - x; 129 return res;
149 h = crtc->primary->fb->height - y;
150
151 return sti_layer_prepare(layer, crtc,
152 crtc->primary->fb, &crtc->mode,
153 mixer->id, 0, 0, w, h, x, y, w, h);
154}
155
156static int sti_drm_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
157 struct drm_framebuffer *old_fb)
158{
159 struct sti_mixer *mixer = to_sti_mixer(crtc);
160 struct sti_layer *layer;
161 unsigned int w, h;
162 int ret;
163
164 DRM_DEBUG_KMS("CRTC:%d (%s) fb:%d (%d,%d)\n",
165 crtc->base.id, sti_mixer_to_str(mixer),
166 crtc->primary->fb->base.id, x, y);
167
168 /* GDP is reserved to the CRTC FB */
169 layer = to_sti_layer(crtc->primary);
170 if (!layer) {
171 DRM_ERROR("Can not find GDP0)\n");
172 ret = -EINVAL;
173 goto out;
174 }
175
176 w = crtc->primary->fb->width - crtc->x;
177 h = crtc->primary->fb->height - crtc->y;
178
179 ret = sti_layer_prepare(layer, crtc,
180 crtc->primary->fb, &crtc->mode,
181 mixer->id, 0, 0, w, h,
182 crtc->x, crtc->y, w, h);
183 if (ret) {
184 DRM_ERROR("Can not prepare layer\n");
185 goto out;
186 }
187
188 sti_drm_crtc_commit(crtc);
189out:
190 return ret;
191} 130}
192 131
193static void sti_drm_crtc_disable(struct drm_crtc *crtc) 132static void sti_drm_crtc_disable(struct drm_crtc *crtc)
@@ -195,7 +134,6 @@ static void sti_drm_crtc_disable(struct drm_crtc *crtc)
195 struct sti_mixer *mixer = to_sti_mixer(crtc); 134 struct sti_mixer *mixer = to_sti_mixer(crtc);
196 struct device *dev = mixer->dev; 135 struct device *dev = mixer->dev;
197 struct sti_compositor *compo = dev_get_drvdata(dev); 136 struct sti_compositor *compo = dev_get_drvdata(dev);
198 struct sti_layer *layer;
199 137
200 if (!mixer->enabled) 138 if (!mixer->enabled)
201 return; 139 return;
@@ -205,24 +143,6 @@ static void sti_drm_crtc_disable(struct drm_crtc *crtc)
205 /* Disable Background */ 143 /* Disable Background */
206 sti_mixer_set_background_status(mixer, false); 144 sti_mixer_set_background_status(mixer, false);
207 145
208 /* Disable GDP */
209 layer = to_sti_layer(crtc->primary);
210 if (!layer) {
211 DRM_ERROR("Cannot find GDP0\n");
212 return;
213 }
214
215 /* Disable layer at mixer level */
216 if (sti_mixer_set_layer_status(mixer, layer, false))
217 DRM_ERROR("Can not disable %s layer at mixer\n",
218 sti_layer_to_str(layer));
219
220 /* Wait a while to be sure that a Vsync event is received */
221 msleep(WAIT_NEXT_VSYNC_MS);
222
223 /* Then disable layer itself */
224 sti_layer_disable(layer);
225
226 drm_crtc_vblank_off(crtc); 146 drm_crtc_vblank_off(crtc);
227 147
228 /* Disable pixel clock and compo IP clocks */ 148 /* Disable pixel clock and compo IP clocks */
@@ -237,64 +157,44 @@ static void sti_drm_crtc_disable(struct drm_crtc *crtc)
237 mixer->enabled = false; 157 mixer->enabled = false;
238} 158}
239 159
240static struct drm_crtc_helper_funcs sti_crtc_helper_funcs = { 160static void
241 .dpms = sti_drm_crtc_dpms, 161sti_drm_crtc_mode_set_nofb(struct drm_crtc *crtc)
242 .prepare = sti_drm_crtc_prepare, 162{
243 .commit = sti_drm_crtc_commit, 163 sti_drm_crtc_prepare(crtc);
244 .mode_fixup = sti_drm_crtc_mode_fixup, 164 sti_drm_crtc_mode_set(crtc, &crtc->state->adjusted_mode);
245 .mode_set = sti_drm_crtc_mode_set, 165}
246 .mode_set_base = sti_drm_crtc_mode_set_base,
247 .disable = sti_drm_crtc_disable,
248};
249 166
250static int sti_drm_crtc_page_flip(struct drm_crtc *crtc, 167static void sti_drm_atomic_begin(struct drm_crtc *crtc)
251 struct drm_framebuffer *fb,
252 struct drm_pending_vblank_event *event,
253 uint32_t page_flip_flags)
254{ 168{
255 struct drm_device *drm_dev = crtc->dev;
256 struct drm_framebuffer *old_fb;
257 struct sti_mixer *mixer = to_sti_mixer(crtc); 169 struct sti_mixer *mixer = to_sti_mixer(crtc);
258 unsigned long flags;
259 int ret;
260 170
261 DRM_DEBUG_KMS("fb %d --> fb %d\n", 171 if (crtc->state->event) {
262 crtc->primary->fb->base.id, fb->base.id); 172 crtc->state->event->pipe = drm_crtc_index(crtc);
263 173
264 mutex_lock(&drm_dev->struct_mutex); 174 WARN_ON(drm_crtc_vblank_get(crtc) != 0);
265 175
266 old_fb = crtc->primary->fb; 176 mixer->pending_event = crtc->state->event;
267 crtc->primary->fb = fb; 177 crtc->state->event = NULL;
268 ret = sti_drm_crtc_mode_set_base(crtc, crtc->x, crtc->y, old_fb);
269 if (ret) {
270 DRM_ERROR("failed\n");
271 crtc->primary->fb = old_fb;
272 goto out;
273 } 178 }
179}
274 180
275 if (event) { 181static void sti_drm_atomic_flush(struct drm_crtc *crtc)
276 event->pipe = mixer->id; 182{
277
278 ret = drm_vblank_get(drm_dev, event->pipe);
279 if (ret) {
280 DRM_ERROR("Cannot get vblank\n");
281 goto out;
282 }
283
284 spin_lock_irqsave(&drm_dev->event_lock, flags);
285 if (mixer->pending_event) {
286 drm_vblank_put(drm_dev, event->pipe);
287 ret = -EBUSY;
288 } else {
289 mixer->pending_event = event;
290 }
291 spin_unlock_irqrestore(&drm_dev->event_lock, flags);
292 }
293out:
294 mutex_unlock(&drm_dev->struct_mutex);
295 return ret;
296} 183}
297 184
185static struct drm_crtc_helper_funcs sti_crtc_helper_funcs = {
186 .dpms = sti_drm_crtc_dpms,
187 .prepare = sti_drm_crtc_prepare,
188 .commit = sti_drm_crtc_commit,
189 .mode_fixup = sti_drm_crtc_mode_fixup,
190 .mode_set = drm_helper_crtc_mode_set,
191 .mode_set_nofb = sti_drm_crtc_mode_set_nofb,
192 .mode_set_base = drm_helper_crtc_mode_set_base,
193 .disable = sti_drm_crtc_disable,
194 .atomic_begin = sti_drm_atomic_begin,
195 .atomic_flush = sti_drm_atomic_flush,
196};
197
298static void sti_drm_crtc_destroy(struct drm_crtc *crtc) 198static void sti_drm_crtc_destroy(struct drm_crtc *crtc)
299{ 199{
300 DRM_DEBUG_KMS("\n"); 200 DRM_DEBUG_KMS("\n");
@@ -380,10 +280,13 @@ void sti_drm_crtc_disable_vblank(struct drm_device *dev, int crtc)
380EXPORT_SYMBOL(sti_drm_crtc_disable_vblank); 280EXPORT_SYMBOL(sti_drm_crtc_disable_vblank);
381 281
382static struct drm_crtc_funcs sti_crtc_funcs = { 282static struct drm_crtc_funcs sti_crtc_funcs = {
383 .set_config = drm_crtc_helper_set_config, 283 .set_config = drm_atomic_helper_set_config,
384 .page_flip = sti_drm_crtc_page_flip, 284 .page_flip = drm_atomic_helper_page_flip,
385 .destroy = sti_drm_crtc_destroy, 285 .destroy = sti_drm_crtc_destroy,
386 .set_property = sti_drm_crtc_set_property, 286 .set_property = sti_drm_crtc_set_property,
287 .reset = drm_atomic_helper_crtc_reset,
288 .atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
289 .atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
387}; 290};
388 291
389bool sti_drm_crtc_is_main(struct drm_crtc *crtc) 292bool sti_drm_crtc_is_main(struct drm_crtc *crtc)
diff --git a/drivers/gpu/drm/sti/sti_drm_drv.c b/drivers/gpu/drm/sti/sti_drm_drv.c
index 5239fa121726..59d558b400b3 100644
--- a/drivers/gpu/drm/sti/sti_drm_drv.c
+++ b/drivers/gpu/drm/sti/sti_drm_drv.c
@@ -12,6 +12,8 @@
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/of_platform.h> 13#include <linux/of_platform.h>
14 14
15#include <drm/drm_atomic.h>
16#include <drm/drm_atomic_helper.h>
15#include <drm/drm_crtc_helper.h> 17#include <drm/drm_crtc_helper.h>
16#include <drm/drm_gem_cma_helper.h> 18#include <drm/drm_gem_cma_helper.h>
17#include <drm/drm_fb_cma_helper.h> 19#include <drm/drm_fb_cma_helper.h>
@@ -28,8 +30,87 @@
28#define STI_MAX_FB_HEIGHT 4096 30#define STI_MAX_FB_HEIGHT 4096
29#define STI_MAX_FB_WIDTH 4096 31#define STI_MAX_FB_WIDTH 4096
30 32
33static void sti_drm_atomic_schedule(struct sti_drm_private *private,
34 struct drm_atomic_state *state)
35{
36 private->commit.state = state;
37 schedule_work(&private->commit.work);
38}
39
40static void sti_drm_atomic_complete(struct sti_drm_private *private,
41 struct drm_atomic_state *state)
42{
43 struct drm_device *drm = private->drm_dev;
44
45 /*
46 * Everything below can be run asynchronously without the need to grab
47 * any modeset locks at all under one condition: It must be guaranteed
48 * that the asynchronous work has either been cancelled (if the driver
49 * supports it, which at least requires that the framebuffers get
50 * cleaned up with drm_atomic_helper_cleanup_planes()) or completed
51 * before the new state gets committed on the software side with
52 * drm_atomic_helper_swap_state().
53 *
54 * This scheme allows new atomic state updates to be prepared and
55 * checked in parallel to the asynchronous completion of the previous
56 * update. Which is important since compositors need to figure out the
57 * composition of the next frame right after having submitted the
58 * current layout.
59 */
60
61 drm_atomic_helper_commit_modeset_disables(drm, state);
62 drm_atomic_helper_commit_planes(drm, state);
63 drm_atomic_helper_commit_modeset_enables(drm, state);
64
65 drm_atomic_helper_wait_for_vblanks(drm, state);
66
67 drm_atomic_helper_cleanup_planes(drm, state);
68 drm_atomic_state_free(state);
69}
70
71static void sti_drm_atomic_work(struct work_struct *work)
72{
73 struct sti_drm_private *private = container_of(work,
74 struct sti_drm_private, commit.work);
75
76 sti_drm_atomic_complete(private, private->commit.state);
77}
78
79static int sti_drm_atomic_commit(struct drm_device *drm,
80 struct drm_atomic_state *state, bool async)
81{
82 struct sti_drm_private *private = drm->dev_private;
83 int err;
84
85 err = drm_atomic_helper_prepare_planes(drm, state);
86 if (err)
87 return err;
88
89 /* serialize outstanding asynchronous commits */
90 mutex_lock(&private->commit.lock);
91 flush_work(&private->commit.work);
92
93 /*
94 * This is the point of no return - everything below never fails except
95 * when the hw goes bonghits. Which means we can commit the new state on
96 * the software side now.
97 */
98
99 drm_atomic_helper_swap_state(drm, state);
100
101 if (async)
102 sti_drm_atomic_schedule(private, state);
103 else
104 sti_drm_atomic_complete(private, state);
105
106 mutex_unlock(&private->commit.lock);
107 return 0;
108}
109
31static struct drm_mode_config_funcs sti_drm_mode_config_funcs = { 110static struct drm_mode_config_funcs sti_drm_mode_config_funcs = {
32 .fb_create = drm_fb_cma_create, 111 .fb_create = drm_fb_cma_create,
112 .atomic_check = drm_atomic_helper_check,
113 .atomic_commit = sti_drm_atomic_commit,
33}; 114};
34 115
35static void sti_drm_mode_config_init(struct drm_device *dev) 116static void sti_drm_mode_config_init(struct drm_device *dev)
@@ -61,6 +142,9 @@ static int sti_drm_load(struct drm_device *dev, unsigned long flags)
61 dev->dev_private = (void *)private; 142 dev->dev_private = (void *)private;
62 private->drm_dev = dev; 143 private->drm_dev = dev;
63 144
145 mutex_init(&private->commit.lock);
146 INIT_WORK(&private->commit.work, sti_drm_atomic_work);
147
64 drm_mode_config_init(dev); 148 drm_mode_config_init(dev);
65 drm_kms_helper_poll_init(dev); 149 drm_kms_helper_poll_init(dev);
66 150
@@ -74,7 +158,7 @@ static int sti_drm_load(struct drm_device *dev, unsigned long flags)
74 return ret; 158 return ret;
75 } 159 }
76 160
77 drm_helper_disable_unused_functions(dev); 161 drm_mode_config_reset(dev);
78 162
79#ifdef CONFIG_DRM_STI_FBDEV 163#ifdef CONFIG_DRM_STI_FBDEV
80 drm_fbdev_cma_init(dev, 32, 164 drm_fbdev_cma_init(dev, 32,
diff --git a/drivers/gpu/drm/sti/sti_drm_drv.h b/drivers/gpu/drm/sti/sti_drm_drv.h
index ec5e2eb8dff9..c413aa3ff402 100644
--- a/drivers/gpu/drm/sti/sti_drm_drv.h
+++ b/drivers/gpu/drm/sti/sti_drm_drv.h
@@ -24,6 +24,12 @@ struct sti_drm_private {
24 struct sti_compositor *compo; 24 struct sti_compositor *compo;
25 struct drm_property *plane_zorder_property; 25 struct drm_property *plane_zorder_property;
26 struct drm_device *drm_dev; 26 struct drm_device *drm_dev;
27
28 struct {
29 struct drm_atomic_state *state;
30 struct work_struct work;
31 struct mutex lock;
32 } commit;
27}; 33};
28 34
29#endif 35#endif
diff --git a/drivers/gpu/drm/sti/sti_drm_plane.c b/drivers/gpu/drm/sti/sti_drm_plane.c
index bb6a29339e10..64d4ed43dda3 100644
--- a/drivers/gpu/drm/sti/sti_drm_plane.c
+++ b/drivers/gpu/drm/sti/sti_drm_plane.c
@@ -6,6 +6,10 @@
6 * License terms: GNU General Public License (GPL), version 2 6 * License terms: GNU General Public License (GPL), version 2
7 */ 7 */
8 8
9#include <drm/drmP.h>
10#include <drm/drm_atomic_helper.h>
11#include <drm/drm_plane_helper.h>
12
9#include "sti_compositor.h" 13#include "sti_compositor.h"
10#include "sti_drm_drv.h" 14#include "sti_drm_drv.h"
11#include "sti_drm_plane.h" 15#include "sti_drm_plane.h"
@@ -33,9 +37,9 @@ sti_drm_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
33 struct sti_mixer *mixer = to_sti_mixer(crtc); 37 struct sti_mixer *mixer = to_sti_mixer(crtc);
34 int res; 38 int res;
35 39
36 DRM_DEBUG_KMS("CRTC:%d (%s) drm plane:%d (%s) drm fb:%d\n", 40 DRM_DEBUG_KMS("CRTC:%d (%s) drm plane:%d (%s)\n",
37 crtc->base.id, sti_mixer_to_str(mixer), 41 crtc->base.id, sti_mixer_to_str(mixer),
38 plane->base.id, sti_layer_to_str(layer), fb->base.id); 42 plane->base.id, sti_layer_to_str(layer));
39 DRM_DEBUG_KMS("(%dx%d)@(%d,%d)\n", crtc_w, crtc_h, crtc_x, crtc_y); 43 DRM_DEBUG_KMS("(%dx%d)@(%d,%d)\n", crtc_w, crtc_h, crtc_x, crtc_y);
40 44
41 res = sti_mixer_set_layer_depth(mixer, layer); 45 res = sti_mixer_set_layer_depth(mixer, layer);
@@ -110,7 +114,7 @@ static void sti_drm_plane_destroy(struct drm_plane *plane)
110{ 114{
111 DRM_DEBUG_DRIVER("\n"); 115 DRM_DEBUG_DRIVER("\n");
112 116
113 sti_drm_disable_plane(plane); 117 drm_plane_helper_disable(plane);
114 drm_plane_cleanup(plane); 118 drm_plane_cleanup(plane);
115} 119}
116 120
@@ -133,10 +137,58 @@ static int sti_drm_plane_set_property(struct drm_plane *plane,
133} 137}
134 138
135static struct drm_plane_funcs sti_drm_plane_funcs = { 139static struct drm_plane_funcs sti_drm_plane_funcs = {
136 .update_plane = sti_drm_update_plane, 140 .update_plane = drm_atomic_helper_update_plane,
137 .disable_plane = sti_drm_disable_plane, 141 .disable_plane = drm_atomic_helper_disable_plane,
138 .destroy = sti_drm_plane_destroy, 142 .destroy = sti_drm_plane_destroy,
139 .set_property = sti_drm_plane_set_property, 143 .set_property = sti_drm_plane_set_property,
144 .reset = drm_atomic_helper_plane_reset,
145 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
146 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
147};
148
149static int sti_drm_plane_prepare_fb(struct drm_plane *plane,
150 struct drm_framebuffer *fb,
151 const struct drm_plane_state *new_state)
152{
153 return 0;
154}
155
156static void sti_drm_plane_cleanup_fb(struct drm_plane *plane,
157 struct drm_framebuffer *fb,
158 const struct drm_plane_state *old_fb)
159{
160}
161
162static int sti_drm_plane_atomic_check(struct drm_plane *plane,
163 struct drm_plane_state *state)
164{
165 return 0;
166}
167
168static void sti_drm_plane_atomic_update(struct drm_plane *plane,
169 struct drm_plane_state *oldstate)
170{
171 struct drm_plane_state *state = plane->state;
172
173 sti_drm_update_plane(plane, state->crtc, state->fb,
174 state->crtc_x, state->crtc_y,
175 state->crtc_w, state->crtc_h,
176 state->src_x, state->src_y,
177 state->src_w, state->src_h);
178}
179
180static void sti_drm_plane_atomic_disable(struct drm_plane *plane,
181 struct drm_plane_state *oldstate)
182{
183 sti_drm_disable_plane(plane);
184}
185
186static const struct drm_plane_helper_funcs sti_drm_plane_helpers_funcs = {
187 .prepare_fb = sti_drm_plane_prepare_fb,
188 .cleanup_fb = sti_drm_plane_cleanup_fb,
189 .atomic_check = sti_drm_plane_atomic_check,
190 .atomic_update = sti_drm_plane_atomic_update,
191 .atomic_disable = sti_drm_plane_atomic_disable,
140}; 192};
141 193
142static void sti_drm_plane_attach_zorder_property(struct drm_plane *plane, 194static void sti_drm_plane_attach_zorder_property(struct drm_plane *plane,
@@ -178,11 +230,13 @@ struct drm_plane *sti_drm_plane_init(struct drm_device *dev,
178 return NULL; 230 return NULL;
179 } 231 }
180 232
233 drm_plane_helper_add(&layer->plane, &sti_drm_plane_helpers_funcs);
234
181 for (i = 0; i < ARRAY_SIZE(sti_layer_default_zorder); i++) 235 for (i = 0; i < ARRAY_SIZE(sti_layer_default_zorder); i++)
182 if (sti_layer_default_zorder[i] == layer->desc) 236 if (sti_layer_default_zorder[i] == layer->desc)
183 break; 237 break;
184 238
185 default_zorder = i; 239 default_zorder = i + 1;
186 240
187 if (type == DRM_PLANE_TYPE_OVERLAY) 241 if (type == DRM_PLANE_TYPE_OVERLAY)
188 sti_drm_plane_attach_zorder_property(&layer->plane, 242 sti_drm_plane_attach_zorder_property(&layer->plane,
diff --git a/drivers/gpu/drm/sti/sti_dvo.c b/drivers/gpu/drm/sti/sti_dvo.c
index aeb5070c8363..a9b678af85a6 100644
--- a/drivers/gpu/drm/sti/sti_dvo.c
+++ b/drivers/gpu/drm/sti/sti_dvo.c
@@ -11,6 +11,7 @@
11#include <linux/platform_device.h> 11#include <linux/platform_device.h>
12 12
13#include <drm/drmP.h> 13#include <drm/drmP.h>
14#include <drm/drm_atomic_helper.h>
14#include <drm/drm_crtc_helper.h> 15#include <drm/drm_crtc_helper.h>
15#include <drm/drm_panel.h> 16#include <drm/drm_panel.h>
16 17
@@ -364,10 +365,13 @@ static void sti_dvo_connector_destroy(struct drm_connector *connector)
364} 365}
365 366
366static struct drm_connector_funcs sti_dvo_connector_funcs = { 367static struct drm_connector_funcs sti_dvo_connector_funcs = {
367 .dpms = drm_helper_connector_dpms, 368 .dpms = drm_atomic_helper_connector_dpms,
368 .fill_modes = drm_helper_probe_single_connector_modes, 369 .fill_modes = drm_helper_probe_single_connector_modes,
369 .detect = sti_dvo_connector_detect, 370 .detect = sti_dvo_connector_detect,
370 .destroy = sti_dvo_connector_destroy, 371 .destroy = sti_dvo_connector_destroy,
372 .reset = drm_atomic_helper_connector_reset,
373 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
374 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
371}; 375};
372 376
373static struct drm_encoder *sti_dvo_find_encoder(struct drm_device *dev) 377static struct drm_encoder *sti_dvo_find_encoder(struct drm_device *dev)
diff --git a/drivers/gpu/drm/sti/sti_hda.c b/drivers/gpu/drm/sti/sti_hda.c
index a9bbb081ecad..598cd78b0b16 100644
--- a/drivers/gpu/drm/sti/sti_hda.c
+++ b/drivers/gpu/drm/sti/sti_hda.c
@@ -10,6 +10,7 @@
10#include <linux/platform_device.h> 10#include <linux/platform_device.h>
11 11
12#include <drm/drmP.h> 12#include <drm/drmP.h>
13#include <drm/drm_atomic_helper.h>
13#include <drm/drm_crtc_helper.h> 14#include <drm/drm_crtc_helper.h>
14 15
15/* HDformatter registers */ 16/* HDformatter registers */
@@ -611,10 +612,13 @@ static void sti_hda_connector_destroy(struct drm_connector *connector)
611} 612}
612 613
613static struct drm_connector_funcs sti_hda_connector_funcs = { 614static struct drm_connector_funcs sti_hda_connector_funcs = {
614 .dpms = drm_helper_connector_dpms, 615 .dpms = drm_atomic_helper_connector_dpms,
615 .fill_modes = drm_helper_probe_single_connector_modes, 616 .fill_modes = drm_helper_probe_single_connector_modes,
616 .detect = sti_hda_connector_detect, 617 .detect = sti_hda_connector_detect,
617 .destroy = sti_hda_connector_destroy, 618 .destroy = sti_hda_connector_destroy,
619 .reset = drm_atomic_helper_connector_reset,
620 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
621 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
618}; 622};
619 623
620static struct drm_encoder *sti_hda_find_encoder(struct drm_device *dev) 624static struct drm_encoder *sti_hda_find_encoder(struct drm_device *dev)
diff --git a/drivers/gpu/drm/sti/sti_hdmi.c b/drivers/gpu/drm/sti/sti_hdmi.c
index 1485ade98710..ae5424bd6b4c 100644
--- a/drivers/gpu/drm/sti/sti_hdmi.c
+++ b/drivers/gpu/drm/sti/sti_hdmi.c
@@ -13,6 +13,7 @@
13#include <linux/reset.h> 13#include <linux/reset.h>
14 14
15#include <drm/drmP.h> 15#include <drm/drmP.h>
16#include <drm/drm_atomic_helper.h>
16#include <drm/drm_crtc_helper.h> 17#include <drm/drm_crtc_helper.h>
17#include <drm/drm_edid.h> 18#include <drm/drm_edid.h>
18 19
@@ -663,10 +664,13 @@ static void sti_hdmi_connector_destroy(struct drm_connector *connector)
663} 664}
664 665
665static struct drm_connector_funcs sti_hdmi_connector_funcs = { 666static struct drm_connector_funcs sti_hdmi_connector_funcs = {
666 .dpms = drm_helper_connector_dpms, 667 .dpms = drm_atomic_helper_connector_dpms,
667 .fill_modes = drm_helper_probe_single_connector_modes, 668 .fill_modes = drm_helper_probe_single_connector_modes,
668 .detect = sti_hdmi_connector_detect, 669 .detect = sti_hdmi_connector_detect,
669 .destroy = sti_hdmi_connector_destroy, 670 .destroy = sti_hdmi_connector_destroy,
671 .reset = drm_atomic_helper_connector_reset,
672 .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
673 .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
670}; 674};
671 675
672static struct drm_encoder *sti_hdmi_find_encoder(struct drm_device *dev) 676static struct drm_encoder *sti_hdmi_find_encoder(struct drm_device *dev)