GNU Linux-libre 4.9.337-gnu1
[releases.git] / drivers / gpu / drm / i915 / intel_sprite.c
1 /*
2  * Copyright © 2011 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  *
23  * Authors:
24  *   Jesse Barnes <jbarnes@virtuousgeek.org>
25  *
26  * New plane/sprite handling.
27  *
28  * The older chips had a separate interface for programming plane related
29  * registers; newer ones are much simpler and we can use the new DRM plane
30  * support.
31  */
32 #include <drm/drmP.h>
33 #include <drm/drm_crtc.h>
34 #include <drm/drm_fourcc.h>
35 #include <drm/drm_rect.h>
36 #include <drm/drm_atomic.h>
37 #include <drm/drm_plane_helper.h>
38 #include "intel_drv.h"
39 #include "intel_frontbuffer.h"
40 #include <drm/i915_drm.h>
41 #include "i915_drv.h"
42
43 static bool
44 format_is_yuv(uint32_t format)
45 {
46         switch (format) {
47         case DRM_FORMAT_YUYV:
48         case DRM_FORMAT_UYVY:
49         case DRM_FORMAT_VYUY:
50         case DRM_FORMAT_YVYU:
51                 return true;
52         default:
53                 return false;
54         }
55 }
56
57 int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
58                              int usecs)
59 {
60         /* paranoia */
61         if (!adjusted_mode->crtc_htotal)
62                 return 1;
63
64         return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock,
65                             1000 * adjusted_mode->crtc_htotal);
66 }
67
68 /**
69  * intel_pipe_update_start() - start update of a set of display registers
70  * @crtc: the crtc of which the registers are going to be updated
71  * @start_vbl_count: vblank counter return pointer used for error checking
72  *
73  * Mark the start of an update to pipe registers that should be updated
74  * atomically regarding vblank. If the next vblank will happens within
75  * the next 100 us, this function waits until the vblank passes.
76  *
77  * After a successful call to this function, interrupts will be disabled
78  * until a subsequent call to intel_pipe_update_end(). That is done to
79  * avoid random delays. The value written to @start_vbl_count should be
80  * supplied to intel_pipe_update_end() for error checking.
81  */
82 void intel_pipe_update_start(struct intel_crtc *crtc)
83 {
84         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
85         const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode;
86         long timeout = msecs_to_jiffies_timeout(1);
87         int scanline, min, max, vblank_start;
88         wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
89         bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
90                 intel_crtc_has_type(crtc->config, INTEL_OUTPUT_DSI);
91         DEFINE_WAIT(wait);
92
93         vblank_start = adjusted_mode->crtc_vblank_start;
94         if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
95                 vblank_start = DIV_ROUND_UP(vblank_start, 2);
96
97         /* FIXME needs to be calibrated sensibly */
98         min = vblank_start - intel_usecs_to_scanlines(adjusted_mode, 100);
99         max = vblank_start - 1;
100
101         local_irq_disable();
102
103         if (min <= 0 || max <= 0)
104                 return;
105
106         if (WARN_ON(drm_crtc_vblank_get(&crtc->base)))
107                 return;
108
109         crtc->debug.min_vbl = min;
110         crtc->debug.max_vbl = max;
111         trace_i915_pipe_update_start(crtc);
112
113         for (;;) {
114                 /*
115                  * prepare_to_wait() has a memory barrier, which guarantees
116                  * other CPUs can see the task state update by the time we
117                  * read the scanline.
118                  */
119                 prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
120
121                 scanline = intel_get_crtc_scanline(crtc);
122                 if (scanline < min || scanline > max)
123                         break;
124
125                 if (timeout <= 0) {
126                         DRM_ERROR("Potential atomic update failure on pipe %c\n",
127                                   pipe_name(crtc->pipe));
128                         break;
129                 }
130
131                 local_irq_enable();
132
133                 timeout = schedule_timeout(timeout);
134
135                 local_irq_disable();
136         }
137
138         finish_wait(wq, &wait);
139
140         drm_crtc_vblank_put(&crtc->base);
141
142         /*
143          * On VLV/CHV DSI the scanline counter would appear to
144          * increment approx. 1/3 of a scanline before start of vblank.
145          * The registers still get latched at start of vblank however.
146          * This means we must not write any registers on the first
147          * line of vblank (since not the whole line is actually in
148          * vblank). And unfortunately we can't use the interrupt to
149          * wait here since it will fire too soon. We could use the
150          * frame start interrupt instead since it will fire after the
151          * critical scanline, but that would require more changes
152          * in the interrupt code. So for now we'll just do the nasty
153          * thing and poll for the bad scanline to pass us by.
154          *
155          * FIXME figure out if BXT+ DSI suffers from this as well
156          */
157         while (need_vlv_dsi_wa && scanline == vblank_start)
158                 scanline = intel_get_crtc_scanline(crtc);
159
160         crtc->debug.scanline_start = scanline;
161         crtc->debug.start_vbl_time = ktime_get();
162         crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc);
163
164         trace_i915_pipe_update_vblank_evaded(crtc);
165 }
166
167 /**
168  * intel_pipe_update_end() - end update of a set of display registers
169  * @crtc: the crtc of which the registers were updated
170  * @start_vbl_count: start vblank counter (used for error checking)
171  *
172  * Mark the end of an update started with intel_pipe_update_start(). This
173  * re-enables interrupts and verifies the update was actually completed
174  * before a vblank using the value of @start_vbl_count.
175  */
176 void intel_pipe_update_end(struct intel_crtc *crtc, struct intel_flip_work *work)
177 {
178         enum pipe pipe = crtc->pipe;
179         int scanline_end = intel_get_crtc_scanline(crtc);
180         u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc);
181         ktime_t end_vbl_time = ktime_get();
182
183         if (work) {
184                 work->flip_queued_vblank = end_vbl_count;
185                 smp_mb__before_atomic();
186                 atomic_set(&work->pending, 1);
187         }
188
189         trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end);
190
191         /* We're still in the vblank-evade critical section, this can't race.
192          * Would be slightly nice to just grab the vblank count and arm the
193          * event outside of the critical section - the spinlock might spin for a
194          * while ... */
195         if (crtc->base.state->event) {
196                 WARN_ON(drm_crtc_vblank_get(&crtc->base) != 0);
197
198                 spin_lock(&crtc->base.dev->event_lock);
199                 drm_crtc_arm_vblank_event(&crtc->base, crtc->base.state->event);
200                 spin_unlock(&crtc->base.dev->event_lock);
201
202                 crtc->base.state->event = NULL;
203         }
204
205         local_irq_enable();
206
207         if (crtc->debug.start_vbl_count &&
208             crtc->debug.start_vbl_count != end_vbl_count) {
209                 DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u) time %lld us, min %d, max %d, scanline start %d, end %d\n",
210                           pipe_name(pipe), crtc->debug.start_vbl_count,
211                           end_vbl_count,
212                           ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
213                           crtc->debug.min_vbl, crtc->debug.max_vbl,
214                           crtc->debug.scanline_start, scanline_end);
215         }
216 }
217
218 static void
219 skl_update_plane(struct drm_plane *drm_plane,
220                  const struct intel_crtc_state *crtc_state,
221                  const struct intel_plane_state *plane_state)
222 {
223         struct drm_device *dev = drm_plane->dev;
224         struct drm_i915_private *dev_priv = to_i915(dev);
225         struct intel_plane *intel_plane = to_intel_plane(drm_plane);
226         struct drm_framebuffer *fb = plane_state->base.fb;
227         const struct skl_wm_values *wm = &dev_priv->wm.skl_results;
228         struct drm_crtc *crtc = crtc_state->base.crtc;
229         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
230         const int pipe = intel_plane->pipe;
231         const int plane = intel_plane->plane + 1;
232         u32 plane_ctl;
233         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
234         u32 surf_addr = plane_state->main.offset;
235         unsigned int rotation = plane_state->base.rotation;
236         u32 stride = skl_plane_stride(fb, 0, rotation);
237         int crtc_x = plane_state->base.dst.x1;
238         int crtc_y = plane_state->base.dst.y1;
239         uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
240         uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
241         uint32_t x = plane_state->main.x;
242         uint32_t y = plane_state->main.y;
243         uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
244         uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
245
246         plane_ctl = PLANE_CTL_ENABLE |
247                 PLANE_CTL_PIPE_GAMMA_ENABLE |
248                 PLANE_CTL_PIPE_CSC_ENABLE;
249
250         plane_ctl |= skl_plane_ctl_format(fb->pixel_format);
251         plane_ctl |= skl_plane_ctl_tiling(fb->modifier[0]);
252
253         plane_ctl |= skl_plane_ctl_rotation(rotation);
254
255         if (wm->dirty_pipes & drm_crtc_mask(crtc))
256                 skl_write_plane_wm(intel_crtc, wm, plane);
257
258         if (key->flags) {
259                 I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value);
260                 I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value);
261                 I915_WRITE(PLANE_KEYMSK(pipe, plane), key->channel_mask);
262         }
263
264         if (key->flags & I915_SET_COLORKEY_DESTINATION)
265                 plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION;
266         else if (key->flags & I915_SET_COLORKEY_SOURCE)
267                 plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE;
268
269         /* Sizes are 0 based */
270         src_w--;
271         src_h--;
272         crtc_w--;
273         crtc_h--;
274
275         I915_WRITE(PLANE_OFFSET(pipe, plane), (y << 16) | x);
276         I915_WRITE(PLANE_STRIDE(pipe, plane), stride);
277         I915_WRITE(PLANE_SIZE(pipe, plane), (src_h << 16) | src_w);
278
279         /* program plane scaler */
280         if (plane_state->scaler_id >= 0) {
281                 int scaler_id = plane_state->scaler_id;
282                 const struct intel_scaler *scaler;
283
284                 DRM_DEBUG_KMS("plane = %d PS_PLANE_SEL(plane) = 0x%x\n", plane,
285                         PS_PLANE_SEL(plane));
286
287                 scaler = &crtc_state->scaler_state.scalers[scaler_id];
288
289                 I915_WRITE(SKL_PS_CTRL(pipe, scaler_id),
290                            PS_SCALER_EN | PS_PLANE_SEL(plane) | scaler->mode);
291                 I915_WRITE(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
292                 I915_WRITE(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
293                 I915_WRITE(SKL_PS_WIN_SZ(pipe, scaler_id),
294                         ((crtc_w + 1) << 16)|(crtc_h + 1));
295
296                 I915_WRITE(PLANE_POS(pipe, plane), 0);
297         } else {
298                 I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
299         }
300
301         I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
302         I915_WRITE(PLANE_SURF(pipe, plane),
303                    intel_fb_gtt_offset(fb, rotation) + surf_addr);
304         POSTING_READ(PLANE_SURF(pipe, plane));
305 }
306
307 static void
308 skl_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
309 {
310         struct drm_device *dev = dplane->dev;
311         struct drm_i915_private *dev_priv = to_i915(dev);
312         struct intel_plane *intel_plane = to_intel_plane(dplane);
313         const int pipe = intel_plane->pipe;
314         const int plane = intel_plane->plane + 1;
315
316         /*
317          * We only populate skl_results on watermark updates, and if the
318          * plane's visiblity isn't actually changing neither is its watermarks.
319          */
320         if (!dplane->state->visible)
321                 skl_write_plane_wm(to_intel_crtc(crtc),
322                                    &dev_priv->wm.skl_results, plane);
323
324         I915_WRITE(PLANE_CTL(pipe, plane), 0);
325
326         I915_WRITE(PLANE_SURF(pipe, plane), 0);
327         POSTING_READ(PLANE_SURF(pipe, plane));
328 }
329
330 static void
331 chv_update_csc(struct intel_plane *intel_plane, uint32_t format)
332 {
333         struct drm_i915_private *dev_priv = to_i915(intel_plane->base.dev);
334         int plane = intel_plane->plane;
335
336         /* Seems RGB data bypasses the CSC always */
337         if (!format_is_yuv(format))
338                 return;
339
340         /*
341          * BT.601 limited range YCbCr -> full range RGB
342          *
343          * |r|   | 6537 4769     0|   |cr  |
344          * |g| = |-3330 4769 -1605| x |y-64|
345          * |b|   |    0 4769  8263|   |cb  |
346          *
347          * Cb and Cr apparently come in as signed already, so no
348          * need for any offset. For Y we need to remove the offset.
349          */
350         I915_WRITE(SPCSCYGOFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(-64));
351         I915_WRITE(SPCSCCBOFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(0));
352         I915_WRITE(SPCSCCROFF(plane), SPCSC_OOFF(0) | SPCSC_IOFF(0));
353
354         I915_WRITE(SPCSCC01(plane), SPCSC_C1(4769) | SPCSC_C0(6537));
355         I915_WRITE(SPCSCC23(plane), SPCSC_C1(-3330) | SPCSC_C0(0));
356         I915_WRITE(SPCSCC45(plane), SPCSC_C1(-1605) | SPCSC_C0(4769));
357         I915_WRITE(SPCSCC67(plane), SPCSC_C1(4769) | SPCSC_C0(0));
358         I915_WRITE(SPCSCC8(plane), SPCSC_C0(8263));
359
360         I915_WRITE(SPCSCYGICLAMP(plane), SPCSC_IMAX(940) | SPCSC_IMIN(64));
361         I915_WRITE(SPCSCCBICLAMP(plane), SPCSC_IMAX(448) | SPCSC_IMIN(-448));
362         I915_WRITE(SPCSCCRICLAMP(plane), SPCSC_IMAX(448) | SPCSC_IMIN(-448));
363
364         I915_WRITE(SPCSCYGOCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
365         I915_WRITE(SPCSCCBOCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
366         I915_WRITE(SPCSCCROCLAMP(plane), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
367 }
368
369 static void
370 vlv_update_plane(struct drm_plane *dplane,
371                  const struct intel_crtc_state *crtc_state,
372                  const struct intel_plane_state *plane_state)
373 {
374         struct drm_device *dev = dplane->dev;
375         struct drm_i915_private *dev_priv = to_i915(dev);
376         struct intel_plane *intel_plane = to_intel_plane(dplane);
377         struct drm_framebuffer *fb = plane_state->base.fb;
378         int pipe = intel_plane->pipe;
379         int plane = intel_plane->plane;
380         u32 sprctl;
381         u32 sprsurf_offset, linear_offset;
382         unsigned int rotation = plane_state->base.rotation;
383         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
384         int crtc_x = plane_state->base.dst.x1;
385         int crtc_y = plane_state->base.dst.y1;
386         uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
387         uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
388         uint32_t x = plane_state->base.src.x1 >> 16;
389         uint32_t y = plane_state->base.src.y1 >> 16;
390         uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
391         uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
392
393         sprctl = SP_ENABLE;
394
395         switch (fb->pixel_format) {
396         case DRM_FORMAT_YUYV:
397                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
398                 break;
399         case DRM_FORMAT_YVYU:
400                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
401                 break;
402         case DRM_FORMAT_UYVY:
403                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
404                 break;
405         case DRM_FORMAT_VYUY:
406                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
407                 break;
408         case DRM_FORMAT_RGB565:
409                 sprctl |= SP_FORMAT_BGR565;
410                 break;
411         case DRM_FORMAT_XRGB8888:
412                 sprctl |= SP_FORMAT_BGRX8888;
413                 break;
414         case DRM_FORMAT_ARGB8888:
415                 sprctl |= SP_FORMAT_BGRA8888;
416                 break;
417         case DRM_FORMAT_XBGR2101010:
418                 sprctl |= SP_FORMAT_RGBX1010102;
419                 break;
420         case DRM_FORMAT_ABGR2101010:
421                 sprctl |= SP_FORMAT_RGBA1010102;
422                 break;
423         case DRM_FORMAT_XBGR8888:
424                 sprctl |= SP_FORMAT_RGBX8888;
425                 break;
426         case DRM_FORMAT_ABGR8888:
427                 sprctl |= SP_FORMAT_RGBA8888;
428                 break;
429         default:
430                 /*
431                  * If we get here one of the upper layers failed to filter
432                  * out the unsupported plane formats
433                  */
434                 BUG();
435                 break;
436         }
437
438         /*
439          * Enable gamma to match primary/cursor plane behaviour.
440          * FIXME should be user controllable via propertiesa.
441          */
442         sprctl |= SP_GAMMA_ENABLE;
443
444         if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
445                 sprctl |= SP_TILED;
446
447         /* Sizes are 0 based */
448         src_w--;
449         src_h--;
450         crtc_w--;
451         crtc_h--;
452
453         intel_add_fb_offsets(&x, &y, plane_state, 0);
454         sprsurf_offset = intel_compute_tile_offset(&x, &y, plane_state, 0);
455
456         if (rotation == DRM_ROTATE_180) {
457                 sprctl |= SP_ROTATE_180;
458
459                 x += src_w;
460                 y += src_h;
461         }
462
463         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
464
465         if (key->flags) {
466                 I915_WRITE(SPKEYMINVAL(pipe, plane), key->min_value);
467                 I915_WRITE(SPKEYMAXVAL(pipe, plane), key->max_value);
468                 I915_WRITE(SPKEYMSK(pipe, plane), key->channel_mask);
469         }
470
471         if (key->flags & I915_SET_COLORKEY_SOURCE)
472                 sprctl |= SP_SOURCE_KEY;
473
474         if (IS_CHERRYVIEW(dev) && pipe == PIPE_B)
475                 chv_update_csc(intel_plane, fb->pixel_format);
476
477         I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]);
478         I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x);
479
480         if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
481                 I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x);
482         else
483                 I915_WRITE(SPLINOFF(pipe, plane), linear_offset);
484
485         I915_WRITE(SPCONSTALPHA(pipe, plane), 0);
486
487         I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w);
488         I915_WRITE(SPCNTR(pipe, plane), sprctl);
489         I915_WRITE(SPSURF(pipe, plane),
490                    intel_fb_gtt_offset(fb, rotation) + sprsurf_offset);
491         POSTING_READ(SPSURF(pipe, plane));
492 }
493
494 static void
495 vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
496 {
497         struct drm_device *dev = dplane->dev;
498         struct drm_i915_private *dev_priv = to_i915(dev);
499         struct intel_plane *intel_plane = to_intel_plane(dplane);
500         int pipe = intel_plane->pipe;
501         int plane = intel_plane->plane;
502
503         I915_WRITE(SPCNTR(pipe, plane), 0);
504
505         I915_WRITE(SPSURF(pipe, plane), 0);
506         POSTING_READ(SPSURF(pipe, plane));
507 }
508
509 static void
510 ivb_update_plane(struct drm_plane *plane,
511                  const struct intel_crtc_state *crtc_state,
512                  const struct intel_plane_state *plane_state)
513 {
514         struct drm_device *dev = plane->dev;
515         struct drm_i915_private *dev_priv = to_i915(dev);
516         struct intel_plane *intel_plane = to_intel_plane(plane);
517         struct drm_framebuffer *fb = plane_state->base.fb;
518         enum pipe pipe = intel_plane->pipe;
519         u32 sprctl, sprscale = 0;
520         u32 sprsurf_offset, linear_offset;
521         unsigned int rotation = plane_state->base.rotation;
522         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
523         int crtc_x = plane_state->base.dst.x1;
524         int crtc_y = plane_state->base.dst.y1;
525         uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
526         uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
527         uint32_t x = plane_state->base.src.x1 >> 16;
528         uint32_t y = plane_state->base.src.y1 >> 16;
529         uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
530         uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
531
532         sprctl = SPRITE_ENABLE;
533
534         switch (fb->pixel_format) {
535         case DRM_FORMAT_XBGR8888:
536                 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
537                 break;
538         case DRM_FORMAT_XRGB8888:
539                 sprctl |= SPRITE_FORMAT_RGBX888;
540                 break;
541         case DRM_FORMAT_YUYV:
542                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
543                 break;
544         case DRM_FORMAT_YVYU:
545                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
546                 break;
547         case DRM_FORMAT_UYVY:
548                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
549                 break;
550         case DRM_FORMAT_VYUY:
551                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
552                 break;
553         default:
554                 BUG();
555         }
556
557         /*
558          * Enable gamma to match primary/cursor plane behaviour.
559          * FIXME should be user controllable via propertiesa.
560          */
561         sprctl |= SPRITE_GAMMA_ENABLE;
562
563         if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
564                 sprctl |= SPRITE_TILED;
565
566         if (IS_HASWELL(dev) || IS_BROADWELL(dev))
567                 sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE;
568         else
569                 sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
570
571         if (IS_HASWELL(dev) || IS_BROADWELL(dev))
572                 sprctl |= SPRITE_PIPE_CSC_ENABLE;
573
574         /* Sizes are 0 based */
575         src_w--;
576         src_h--;
577         crtc_w--;
578         crtc_h--;
579
580         if (crtc_w != src_w || crtc_h != src_h)
581                 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
582
583         intel_add_fb_offsets(&x, &y, plane_state, 0);
584         sprsurf_offset = intel_compute_tile_offset(&x, &y, plane_state, 0);
585
586         if (rotation == DRM_ROTATE_180) {
587                 sprctl |= SPRITE_ROTATE_180;
588
589                 /* HSW and BDW does this automagically in hardware */
590                 if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
591                         x += src_w;
592                         y += src_h;
593                 }
594         }
595
596         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
597
598         if (key->flags) {
599                 I915_WRITE(SPRKEYVAL(pipe), key->min_value);
600                 I915_WRITE(SPRKEYMAX(pipe), key->max_value);
601                 I915_WRITE(SPRKEYMSK(pipe), key->channel_mask);
602         }
603
604         if (key->flags & I915_SET_COLORKEY_DESTINATION)
605                 sprctl |= SPRITE_DEST_KEY;
606         else if (key->flags & I915_SET_COLORKEY_SOURCE)
607                 sprctl |= SPRITE_SOURCE_KEY;
608
609         I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
610         I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
611
612         /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
613          * register */
614         if (IS_HASWELL(dev) || IS_BROADWELL(dev))
615                 I915_WRITE(SPROFFSET(pipe), (y << 16) | x);
616         else if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
617                 I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
618         else
619                 I915_WRITE(SPRLINOFF(pipe), linear_offset);
620
621         I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
622         if (intel_plane->can_scale)
623                 I915_WRITE(SPRSCALE(pipe), sprscale);
624         I915_WRITE(SPRCTL(pipe), sprctl);
625         I915_WRITE(SPRSURF(pipe),
626                    intel_fb_gtt_offset(fb, rotation) + sprsurf_offset);
627         POSTING_READ(SPRSURF(pipe));
628 }
629
630 static void
631 ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
632 {
633         struct drm_device *dev = plane->dev;
634         struct drm_i915_private *dev_priv = to_i915(dev);
635         struct intel_plane *intel_plane = to_intel_plane(plane);
636         int pipe = intel_plane->pipe;
637
638         I915_WRITE(SPRCTL(pipe), 0);
639         /* Can't leave the scaler enabled... */
640         if (intel_plane->can_scale)
641                 I915_WRITE(SPRSCALE(pipe), 0);
642
643         I915_WRITE(SPRSURF(pipe), 0);
644         POSTING_READ(SPRSURF(pipe));
645 }
646
647 static void
648 ilk_update_plane(struct drm_plane *plane,
649                  const struct intel_crtc_state *crtc_state,
650                  const struct intel_plane_state *plane_state)
651 {
652         struct drm_device *dev = plane->dev;
653         struct drm_i915_private *dev_priv = to_i915(dev);
654         struct intel_plane *intel_plane = to_intel_plane(plane);
655         struct drm_framebuffer *fb = plane_state->base.fb;
656         int pipe = intel_plane->pipe;
657         u32 dvscntr, dvsscale;
658         u32 dvssurf_offset, linear_offset;
659         unsigned int rotation = plane_state->base.rotation;
660         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
661         int crtc_x = plane_state->base.dst.x1;
662         int crtc_y = plane_state->base.dst.y1;
663         uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
664         uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
665         uint32_t x = plane_state->base.src.x1 >> 16;
666         uint32_t y = plane_state->base.src.y1 >> 16;
667         uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
668         uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
669
670         dvscntr = DVS_ENABLE;
671
672         switch (fb->pixel_format) {
673         case DRM_FORMAT_XBGR8888:
674                 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
675                 break;
676         case DRM_FORMAT_XRGB8888:
677                 dvscntr |= DVS_FORMAT_RGBX888;
678                 break;
679         case DRM_FORMAT_YUYV:
680                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
681                 break;
682         case DRM_FORMAT_YVYU:
683                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
684                 break;
685         case DRM_FORMAT_UYVY:
686                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
687                 break;
688         case DRM_FORMAT_VYUY:
689                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
690                 break;
691         default:
692                 BUG();
693         }
694
695         /*
696          * Enable gamma to match primary/cursor plane behaviour.
697          * FIXME should be user controllable via propertiesa.
698          */
699         dvscntr |= DVS_GAMMA_ENABLE;
700
701         if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
702                 dvscntr |= DVS_TILED;
703
704         if (IS_GEN6(dev))
705                 dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */
706
707         /* Sizes are 0 based */
708         src_w--;
709         src_h--;
710         crtc_w--;
711         crtc_h--;
712
713         dvsscale = 0;
714         if (crtc_w != src_w || crtc_h != src_h)
715                 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
716
717         intel_add_fb_offsets(&x, &y, plane_state, 0);
718         dvssurf_offset = intel_compute_tile_offset(&x, &y, plane_state, 0);
719
720         if (rotation == DRM_ROTATE_180) {
721                 dvscntr |= DVS_ROTATE_180;
722
723                 x += src_w;
724                 y += src_h;
725         }
726
727         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
728
729         if (key->flags) {
730                 I915_WRITE(DVSKEYVAL(pipe), key->min_value);
731                 I915_WRITE(DVSKEYMAX(pipe), key->max_value);
732                 I915_WRITE(DVSKEYMSK(pipe), key->channel_mask);
733         }
734
735         if (key->flags & I915_SET_COLORKEY_DESTINATION)
736                 dvscntr |= DVS_DEST_KEY;
737         else if (key->flags & I915_SET_COLORKEY_SOURCE)
738                 dvscntr |= DVS_SOURCE_KEY;
739
740         I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);
741         I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
742
743         if (fb->modifier[0] == I915_FORMAT_MOD_X_TILED)
744                 I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x);
745         else
746                 I915_WRITE(DVSLINOFF(pipe), linear_offset);
747
748         I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
749         I915_WRITE(DVSSCALE(pipe), dvsscale);
750         I915_WRITE(DVSCNTR(pipe), dvscntr);
751         I915_WRITE(DVSSURF(pipe),
752                    intel_fb_gtt_offset(fb, rotation) + dvssurf_offset);
753         POSTING_READ(DVSSURF(pipe));
754 }
755
756 static void
757 ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
758 {
759         struct drm_device *dev = plane->dev;
760         struct drm_i915_private *dev_priv = to_i915(dev);
761         struct intel_plane *intel_plane = to_intel_plane(plane);
762         int pipe = intel_plane->pipe;
763
764         I915_WRITE(DVSCNTR(pipe), 0);
765         /* Disable the scaler */
766         I915_WRITE(DVSSCALE(pipe), 0);
767
768         I915_WRITE(DVSSURF(pipe), 0);
769         POSTING_READ(DVSSURF(pipe));
770 }
771
772 static int
773 intel_check_sprite_plane(struct drm_plane *plane,
774                          struct intel_crtc_state *crtc_state,
775                          struct intel_plane_state *state)
776 {
777         struct drm_device *dev = plane->dev;
778         struct drm_crtc *crtc = state->base.crtc;
779         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
780         struct intel_plane *intel_plane = to_intel_plane(plane);
781         struct drm_framebuffer *fb = state->base.fb;
782         int crtc_x, crtc_y;
783         unsigned int crtc_w, crtc_h;
784         uint32_t src_x, src_y, src_w, src_h;
785         struct drm_rect *src = &state->base.src;
786         struct drm_rect *dst = &state->base.dst;
787         const struct drm_rect *clip = &state->clip;
788         int hscale, vscale;
789         int max_scale, min_scale;
790         bool can_scale;
791         int ret;
792
793         src->x1 = state->base.src_x;
794         src->y1 = state->base.src_y;
795         src->x2 = state->base.src_x + state->base.src_w;
796         src->y2 = state->base.src_y + state->base.src_h;
797
798         dst->x1 = state->base.crtc_x;
799         dst->y1 = state->base.crtc_y;
800         dst->x2 = state->base.crtc_x + state->base.crtc_w;
801         dst->y2 = state->base.crtc_y + state->base.crtc_h;
802
803         if (!fb) {
804                 state->base.visible = false;
805                 return 0;
806         }
807
808         /* Don't modify another pipe's plane */
809         if (intel_plane->pipe != intel_crtc->pipe) {
810                 DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
811                 return -EINVAL;
812         }
813
814         /* FIXME check all gen limits */
815         if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384) {
816                 DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n");
817                 return -EINVAL;
818         }
819
820         /* setup can_scale, min_scale, max_scale */
821         if (INTEL_INFO(dev)->gen >= 9) {
822                 /* use scaler when colorkey is not required */
823                 if (state->ckey.flags == I915_SET_COLORKEY_NONE) {
824                         can_scale = 1;
825                         min_scale = 1;
826                         max_scale = skl_max_scale(intel_crtc, crtc_state);
827                 } else {
828                         can_scale = 0;
829                         min_scale = DRM_PLANE_HELPER_NO_SCALING;
830                         max_scale = DRM_PLANE_HELPER_NO_SCALING;
831                 }
832         } else {
833                 can_scale = intel_plane->can_scale;
834                 max_scale = intel_plane->max_downscale << 16;
835                 min_scale = intel_plane->can_scale ? 1 : (1 << 16);
836         }
837
838         /*
839          * FIXME the following code does a bunch of fuzzy adjustments to the
840          * coordinates and sizes. We probably need some way to decide whether
841          * more strict checking should be done instead.
842          */
843         drm_rect_rotate(src, fb->width << 16, fb->height << 16,
844                         state->base.rotation);
845
846         hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale);
847         BUG_ON(hscale < 0);
848
849         vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale);
850         BUG_ON(vscale < 0);
851
852         state->base.visible = drm_rect_clip_scaled(src, dst, clip, hscale, vscale);
853
854         crtc_x = dst->x1;
855         crtc_y = dst->y1;
856         crtc_w = drm_rect_width(dst);
857         crtc_h = drm_rect_height(dst);
858
859         if (state->base.visible) {
860                 /* check again in case clipping clamped the results */
861                 hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
862                 if (hscale < 0) {
863                         DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
864                         drm_rect_debug_print("src: ", src, true);
865                         drm_rect_debug_print("dst: ", dst, false);
866
867                         return hscale;
868                 }
869
870                 vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
871                 if (vscale < 0) {
872                         DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
873                         drm_rect_debug_print("src: ", src, true);
874                         drm_rect_debug_print("dst: ", dst, false);
875
876                         return vscale;
877                 }
878
879                 /* Make the source viewport size an exact multiple of the scaling factors. */
880                 drm_rect_adjust_size(src,
881                                      drm_rect_width(dst) * hscale - drm_rect_width(src),
882                                      drm_rect_height(dst) * vscale - drm_rect_height(src));
883
884                 drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16,
885                                     state->base.rotation);
886
887                 /* sanity check to make sure the src viewport wasn't enlarged */
888                 WARN_ON(src->x1 < (int) state->base.src_x ||
889                         src->y1 < (int) state->base.src_y ||
890                         src->x2 > (int) state->base.src_x + state->base.src_w ||
891                         src->y2 > (int) state->base.src_y + state->base.src_h);
892
893                 /*
894                  * Hardware doesn't handle subpixel coordinates.
895                  * Adjust to (macro)pixel boundary, but be careful not to
896                  * increase the source viewport size, because that could
897                  * push the downscaling factor out of bounds.
898                  */
899                 src_x = src->x1 >> 16;
900                 src_w = drm_rect_width(src) >> 16;
901                 src_y = src->y1 >> 16;
902                 src_h = drm_rect_height(src) >> 16;
903
904                 if (format_is_yuv(fb->pixel_format)) {
905                         src_x &= ~1;
906                         src_w &= ~1;
907
908                         /*
909                          * Must keep src and dst the
910                          * same if we can't scale.
911                          */
912                         if (!can_scale)
913                                 crtc_w &= ~1;
914
915                         if (crtc_w == 0)
916                                 state->base.visible = false;
917                 }
918         }
919
920         /* Check size restrictions when scaling */
921         if (state->base.visible && (src_w != crtc_w || src_h != crtc_h)) {
922                 unsigned int width_bytes;
923                 int cpp = drm_format_plane_cpp(fb->pixel_format, 0);
924
925                 WARN_ON(!can_scale);
926
927                 /* FIXME interlacing min height is 6 */
928
929                 if (crtc_w < 3 || crtc_h < 3)
930                         state->base.visible = false;
931
932                 if (src_w < 3 || src_h < 3)
933                         state->base.visible = false;
934
935                 width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
936
937                 if (INTEL_INFO(dev)->gen < 9 && (src_w > 2048 || src_h > 2048 ||
938                     width_bytes > 4096 || fb->pitches[0] > 4096)) {
939                         DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
940                         return -EINVAL;
941                 }
942         }
943
944         if (state->base.visible) {
945                 src->x1 = src_x << 16;
946                 src->x2 = (src_x + src_w) << 16;
947                 src->y1 = src_y << 16;
948                 src->y2 = (src_y + src_h) << 16;
949         }
950
951         dst->x1 = crtc_x;
952         dst->x2 = crtc_x + crtc_w;
953         dst->y1 = crtc_y;
954         dst->y2 = crtc_y + crtc_h;
955
956         if (INTEL_GEN(dev) >= 9) {
957                 ret = skl_check_plane_surface(state);
958                 if (ret)
959                         return ret;
960         }
961
962         return 0;
963 }
964
965 int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
966                               struct drm_file *file_priv)
967 {
968         struct drm_intel_sprite_colorkey *set = data;
969         struct drm_plane *plane;
970         struct drm_plane_state *plane_state;
971         struct drm_atomic_state *state;
972         struct drm_modeset_acquire_ctx ctx;
973         int ret = 0;
974
975         /* Make sure we don't try to enable both src & dest simultaneously */
976         if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
977                 return -EINVAL;
978
979         if ((IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) &&
980             set->flags & I915_SET_COLORKEY_DESTINATION)
981                 return -EINVAL;
982
983         plane = drm_plane_find(dev, set->plane_id);
984         if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
985                 return -ENOENT;
986
987         drm_modeset_acquire_init(&ctx, 0);
988
989         state = drm_atomic_state_alloc(plane->dev);
990         if (!state) {
991                 ret = -ENOMEM;
992                 goto out;
993         }
994         state->acquire_ctx = &ctx;
995
996         while (1) {
997                 plane_state = drm_atomic_get_plane_state(state, plane);
998                 ret = PTR_ERR_OR_ZERO(plane_state);
999                 if (!ret) {
1000                         to_intel_plane_state(plane_state)->ckey = *set;
1001                         ret = drm_atomic_commit(state);
1002                 }
1003
1004                 if (ret != -EDEADLK)
1005                         break;
1006
1007                 drm_atomic_state_clear(state);
1008                 drm_modeset_backoff(&ctx);
1009         }
1010
1011         if (ret)
1012                 drm_atomic_state_free(state);
1013
1014 out:
1015         drm_modeset_drop_locks(&ctx);
1016         drm_modeset_acquire_fini(&ctx);
1017         return ret;
1018 }
1019
1020 static const uint32_t ilk_plane_formats[] = {
1021         DRM_FORMAT_XRGB8888,
1022         DRM_FORMAT_YUYV,
1023         DRM_FORMAT_YVYU,
1024         DRM_FORMAT_UYVY,
1025         DRM_FORMAT_VYUY,
1026 };
1027
1028 static const uint32_t snb_plane_formats[] = {
1029         DRM_FORMAT_XBGR8888,
1030         DRM_FORMAT_XRGB8888,
1031         DRM_FORMAT_YUYV,
1032         DRM_FORMAT_YVYU,
1033         DRM_FORMAT_UYVY,
1034         DRM_FORMAT_VYUY,
1035 };
1036
1037 static const uint32_t vlv_plane_formats[] = {
1038         DRM_FORMAT_RGB565,
1039         DRM_FORMAT_ABGR8888,
1040         DRM_FORMAT_ARGB8888,
1041         DRM_FORMAT_XBGR8888,
1042         DRM_FORMAT_XRGB8888,
1043         DRM_FORMAT_XBGR2101010,
1044         DRM_FORMAT_ABGR2101010,
1045         DRM_FORMAT_YUYV,
1046         DRM_FORMAT_YVYU,
1047         DRM_FORMAT_UYVY,
1048         DRM_FORMAT_VYUY,
1049 };
1050
1051 static uint32_t skl_plane_formats[] = {
1052         DRM_FORMAT_RGB565,
1053         DRM_FORMAT_ABGR8888,
1054         DRM_FORMAT_ARGB8888,
1055         DRM_FORMAT_XBGR8888,
1056         DRM_FORMAT_XRGB8888,
1057         DRM_FORMAT_YUYV,
1058         DRM_FORMAT_YVYU,
1059         DRM_FORMAT_UYVY,
1060         DRM_FORMAT_VYUY,
1061 };
1062
1063 int
1064 intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
1065 {
1066         struct intel_plane *intel_plane = NULL;
1067         struct intel_plane_state *state = NULL;
1068         unsigned long possible_crtcs;
1069         const uint32_t *plane_formats;
1070         int num_plane_formats;
1071         int ret;
1072
1073         if (INTEL_INFO(dev)->gen < 5)
1074                 return -ENODEV;
1075
1076         intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL);
1077         if (!intel_plane) {
1078                 ret = -ENOMEM;
1079                 goto fail;
1080         }
1081
1082         state = intel_create_plane_state(&intel_plane->base);
1083         if (!state) {
1084                 ret = -ENOMEM;
1085                 goto fail;
1086         }
1087         intel_plane->base.state = &state->base;
1088
1089         switch (INTEL_INFO(dev)->gen) {
1090         case 5:
1091         case 6:
1092                 intel_plane->can_scale = true;
1093                 intel_plane->max_downscale = 16;
1094                 intel_plane->update_plane = ilk_update_plane;
1095                 intel_plane->disable_plane = ilk_disable_plane;
1096
1097                 if (IS_GEN6(dev)) {
1098                         plane_formats = snb_plane_formats;
1099                         num_plane_formats = ARRAY_SIZE(snb_plane_formats);
1100                 } else {
1101                         plane_formats = ilk_plane_formats;
1102                         num_plane_formats = ARRAY_SIZE(ilk_plane_formats);
1103                 }
1104                 break;
1105
1106         case 7:
1107         case 8:
1108                 if (IS_IVYBRIDGE(dev)) {
1109                         intel_plane->can_scale = true;
1110                         intel_plane->max_downscale = 2;
1111                 } else {
1112                         intel_plane->can_scale = false;
1113                         intel_plane->max_downscale = 1;
1114                 }
1115
1116                 if (IS_VALLEYVIEW(dev) || IS_CHERRYVIEW(dev)) {
1117                         intel_plane->update_plane = vlv_update_plane;
1118                         intel_plane->disable_plane = vlv_disable_plane;
1119
1120                         plane_formats = vlv_plane_formats;
1121                         num_plane_formats = ARRAY_SIZE(vlv_plane_formats);
1122                 } else {
1123                         intel_plane->update_plane = ivb_update_plane;
1124                         intel_plane->disable_plane = ivb_disable_plane;
1125
1126                         plane_formats = snb_plane_formats;
1127                         num_plane_formats = ARRAY_SIZE(snb_plane_formats);
1128                 }
1129                 break;
1130         case 9:
1131                 intel_plane->can_scale = true;
1132                 intel_plane->update_plane = skl_update_plane;
1133                 intel_plane->disable_plane = skl_disable_plane;
1134                 state->scaler_id = -1;
1135
1136                 plane_formats = skl_plane_formats;
1137                 num_plane_formats = ARRAY_SIZE(skl_plane_formats);
1138                 break;
1139         default:
1140                 MISSING_CASE(INTEL_INFO(dev)->gen);
1141                 ret = -ENODEV;
1142                 goto fail;
1143         }
1144
1145         intel_plane->pipe = pipe;
1146         intel_plane->plane = plane;
1147         intel_plane->frontbuffer_bit = INTEL_FRONTBUFFER_SPRITE(pipe, plane);
1148         intel_plane->check_plane = intel_check_sprite_plane;
1149
1150         possible_crtcs = (1 << pipe);
1151
1152         if (INTEL_INFO(dev)->gen >= 9)
1153                 ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs,
1154                                                &intel_plane_funcs,
1155                                                plane_formats, num_plane_formats,
1156                                                DRM_PLANE_TYPE_OVERLAY,
1157                                                "plane %d%c", plane + 2, pipe_name(pipe));
1158         else
1159                 ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs,
1160                                                &intel_plane_funcs,
1161                                                plane_formats, num_plane_formats,
1162                                                DRM_PLANE_TYPE_OVERLAY,
1163                                                "sprite %c", sprite_name(pipe, plane));
1164         if (ret)
1165                 goto fail;
1166
1167         intel_create_rotation_property(dev, intel_plane);
1168
1169         drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs);
1170
1171         return 0;
1172
1173 fail:
1174         kfree(state);
1175         kfree(intel_plane);
1176
1177         return ret;
1178 }