]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/gpu/drm/i915/intel_sprite.c
af147e7a9a3cb581b8b680e1594ef038f27be480
[linux.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/drm_atomic_helper.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 #include <drm/drm_color_mgmt.h>
43
44 bool is_planar_yuv_format(u32 pixelformat)
45 {
46         switch (pixelformat) {
47         case DRM_FORMAT_NV12:
48         case DRM_FORMAT_P010:
49         case DRM_FORMAT_P012:
50         case DRM_FORMAT_P016:
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 /* FIXME: We should instead only take spinlocks once for the entire update
69  * instead of once per mmio. */
70 #if IS_ENABLED(CONFIG_PROVE_LOCKING)
71 #define VBLANK_EVASION_TIME_US 250
72 #else
73 #define VBLANK_EVASION_TIME_US 100
74 #endif
75
76 /**
77  * intel_pipe_update_start() - start update of a set of display registers
78  * @new_crtc_state: the new crtc state
79  *
80  * Mark the start of an update to pipe registers that should be updated
81  * atomically regarding vblank. If the next vblank will happens within
82  * the next 100 us, this function waits until the vblank passes.
83  *
84  * After a successful call to this function, interrupts will be disabled
85  * until a subsequent call to intel_pipe_update_end(). That is done to
86  * avoid random delays.
87  */
88 void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
89 {
90         struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
91         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
92         const struct drm_display_mode *adjusted_mode = &new_crtc_state->base.adjusted_mode;
93         long timeout = msecs_to_jiffies_timeout(1);
94         int scanline, min, max, vblank_start;
95         wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
96         bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
97                 intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI);
98         DEFINE_WAIT(wait);
99         u32 psr_status;
100
101         vblank_start = adjusted_mode->crtc_vblank_start;
102         if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
103                 vblank_start = DIV_ROUND_UP(vblank_start, 2);
104
105         /* FIXME needs to be calibrated sensibly */
106         min = vblank_start - intel_usecs_to_scanlines(adjusted_mode,
107                                                       VBLANK_EVASION_TIME_US);
108         max = vblank_start - 1;
109
110         if (min <= 0 || max <= 0)
111                 goto irq_disable;
112
113         if (WARN_ON(drm_crtc_vblank_get(&crtc->base)))
114                 goto irq_disable;
115
116         /*
117          * Wait for psr to idle out after enabling the VBL interrupts
118          * VBL interrupts will start the PSR exit and prevent a PSR
119          * re-entry as well.
120          */
121         if (intel_psr_wait_for_idle(new_crtc_state, &psr_status))
122                 DRM_ERROR("PSR idle timed out 0x%x, atomic update may fail\n",
123                           psr_status);
124
125         local_irq_disable();
126
127         crtc->debug.min_vbl = min;
128         crtc->debug.max_vbl = max;
129         trace_i915_pipe_update_start(crtc);
130
131         for (;;) {
132                 /*
133                  * prepare_to_wait() has a memory barrier, which guarantees
134                  * other CPUs can see the task state update by the time we
135                  * read the scanline.
136                  */
137                 prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
138
139                 scanline = intel_get_crtc_scanline(crtc);
140                 if (scanline < min || scanline > max)
141                         break;
142
143                 if (!timeout) {
144                         DRM_ERROR("Potential atomic update failure on pipe %c\n",
145                                   pipe_name(crtc->pipe));
146                         break;
147                 }
148
149                 local_irq_enable();
150
151                 timeout = schedule_timeout(timeout);
152
153                 local_irq_disable();
154         }
155
156         finish_wait(wq, &wait);
157
158         drm_crtc_vblank_put(&crtc->base);
159
160         /*
161          * On VLV/CHV DSI the scanline counter would appear to
162          * increment approx. 1/3 of a scanline before start of vblank.
163          * The registers still get latched at start of vblank however.
164          * This means we must not write any registers on the first
165          * line of vblank (since not the whole line is actually in
166          * vblank). And unfortunately we can't use the interrupt to
167          * wait here since it will fire too soon. We could use the
168          * frame start interrupt instead since it will fire after the
169          * critical scanline, but that would require more changes
170          * in the interrupt code. So for now we'll just do the nasty
171          * thing and poll for the bad scanline to pass us by.
172          *
173          * FIXME figure out if BXT+ DSI suffers from this as well
174          */
175         while (need_vlv_dsi_wa && scanline == vblank_start)
176                 scanline = intel_get_crtc_scanline(crtc);
177
178         crtc->debug.scanline_start = scanline;
179         crtc->debug.start_vbl_time = ktime_get();
180         crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc);
181
182         trace_i915_pipe_update_vblank_evaded(crtc);
183         return;
184
185 irq_disable:
186         local_irq_disable();
187 }
188
189 /**
190  * intel_pipe_update_end() - end update of a set of display registers
191  * @new_crtc_state: the new crtc state
192  *
193  * Mark the end of an update started with intel_pipe_update_start(). This
194  * re-enables interrupts and verifies the update was actually completed
195  * before a vblank.
196  */
197 void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
198 {
199         struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
200         enum pipe pipe = crtc->pipe;
201         int scanline_end = intel_get_crtc_scanline(crtc);
202         u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc);
203         ktime_t end_vbl_time = ktime_get();
204         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
205
206         trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end);
207
208         /* We're still in the vblank-evade critical section, this can't race.
209          * Would be slightly nice to just grab the vblank count and arm the
210          * event outside of the critical section - the spinlock might spin for a
211          * while ... */
212         if (new_crtc_state->base.event) {
213                 WARN_ON(drm_crtc_vblank_get(&crtc->base) != 0);
214
215                 spin_lock(&crtc->base.dev->event_lock);
216                 drm_crtc_arm_vblank_event(&crtc->base, new_crtc_state->base.event);
217                 spin_unlock(&crtc->base.dev->event_lock);
218
219                 new_crtc_state->base.event = NULL;
220         }
221
222         local_irq_enable();
223
224         if (intel_vgpu_active(dev_priv))
225                 return;
226
227         if (crtc->debug.start_vbl_count &&
228             crtc->debug.start_vbl_count != end_vbl_count) {
229                 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",
230                           pipe_name(pipe), crtc->debug.start_vbl_count,
231                           end_vbl_count,
232                           ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
233                           crtc->debug.min_vbl, crtc->debug.max_vbl,
234                           crtc->debug.scanline_start, scanline_end);
235         }
236 #ifdef CONFIG_DRM_I915_DEBUG_VBLANK_EVADE
237         else if (ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time) >
238                  VBLANK_EVASION_TIME_US)
239                 DRM_WARN("Atomic update on pipe (%c) took %lld us, max time under evasion is %u us\n",
240                          pipe_name(pipe),
241                          ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
242                          VBLANK_EVASION_TIME_US);
243 #endif
244 }
245
246 int intel_plane_check_stride(const struct intel_plane_state *plane_state)
247 {
248         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
249         const struct drm_framebuffer *fb = plane_state->base.fb;
250         unsigned int rotation = plane_state->base.rotation;
251         u32 stride, max_stride;
252
253         /* FIXME other color planes? */
254         stride = plane_state->color_plane[0].stride;
255         max_stride = plane->max_stride(plane, fb->format->format,
256                                        fb->modifier, rotation);
257
258         if (stride > max_stride) {
259                 DRM_DEBUG_KMS("[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n",
260                               fb->base.id, stride,
261                               plane->base.base.id, plane->base.name, max_stride);
262                 return -EINVAL;
263         }
264
265         return 0;
266 }
267
268 int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
269 {
270         const struct drm_framebuffer *fb = plane_state->base.fb;
271         struct drm_rect *src = &plane_state->base.src;
272         u32 src_x, src_y, src_w, src_h;
273
274         /*
275          * Hardware doesn't handle subpixel coordinates.
276          * Adjust to (macro)pixel boundary, but be careful not to
277          * increase the source viewport size, because that could
278          * push the downscaling factor out of bounds.
279          */
280         src_x = src->x1 >> 16;
281         src_w = drm_rect_width(src) >> 16;
282         src_y = src->y1 >> 16;
283         src_h = drm_rect_height(src) >> 16;
284
285         src->x1 = src_x << 16;
286         src->x2 = (src_x + src_w) << 16;
287         src->y1 = src_y << 16;
288         src->y2 = (src_y + src_h) << 16;
289
290         if (fb->format->is_yuv &&
291             (src_x & 1 || src_w & 1)) {
292                 DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of 2 for YUV planes\n",
293                               src_x, src_w);
294                 return -EINVAL;
295         }
296
297         if (fb->format->is_yuv &&
298             fb->format->num_planes > 1 &&
299             (src_y & 1 || src_h & 1)) {
300                 DRM_DEBUG_KMS("src y/h (%u, %u) must be a multiple of 2 for planar YUV planes\n",
301                               src_y, src_h);
302                 return -EINVAL;
303         }
304
305         return 0;
306 }
307
308 static unsigned int
309 skl_plane_max_stride(struct intel_plane *plane,
310                      u32 pixel_format, u64 modifier,
311                      unsigned int rotation)
312 {
313         int cpp = drm_format_plane_cpp(pixel_format, 0);
314
315         /*
316          * "The stride in bytes must not exceed the
317          * of the size of 8K pixels and 32K bytes."
318          */
319         if (drm_rotation_90_or_270(rotation))
320                 return min(8192, 32768 / cpp);
321         else
322                 return min(8192 * cpp, 32768);
323 }
324
325 static void
326 skl_program_scaler(struct intel_plane *plane,
327                    const struct intel_crtc_state *crtc_state,
328                    const struct intel_plane_state *plane_state)
329 {
330         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
331         enum pipe pipe = plane->pipe;
332         int scaler_id = plane_state->scaler_id;
333         const struct intel_scaler *scaler =
334                 &crtc_state->scaler_state.scalers[scaler_id];
335         int crtc_x = plane_state->base.dst.x1;
336         int crtc_y = plane_state->base.dst.y1;
337         u32 crtc_w = drm_rect_width(&plane_state->base.dst);
338         u32 crtc_h = drm_rect_height(&plane_state->base.dst);
339         u16 y_hphase, uv_rgb_hphase;
340         u16 y_vphase, uv_rgb_vphase;
341         int hscale, vscale;
342
343         hscale = drm_rect_calc_hscale(&plane_state->base.src,
344                                       &plane_state->base.dst,
345                                       0, INT_MAX);
346         vscale = drm_rect_calc_vscale(&plane_state->base.src,
347                                       &plane_state->base.dst,
348                                       0, INT_MAX);
349
350         /* TODO: handle sub-pixel coordinates */
351         if (is_planar_yuv_format(plane_state->base.fb->format->format) &&
352             !icl_is_hdr_plane(plane)) {
353                 y_hphase = skl_scaler_calc_phase(1, hscale, false);
354                 y_vphase = skl_scaler_calc_phase(1, vscale, false);
355
356                 /* MPEG2 chroma siting convention */
357                 uv_rgb_hphase = skl_scaler_calc_phase(2, hscale, true);
358                 uv_rgb_vphase = skl_scaler_calc_phase(2, vscale, false);
359         } else {
360                 /* not used */
361                 y_hphase = 0;
362                 y_vphase = 0;
363
364                 uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false);
365                 uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false);
366         }
367
368         I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
369                       PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode);
370         I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
371                       PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
372         I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
373                       PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
374         I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
375         I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), (crtc_w << 16) | crtc_h);
376 }
377
378 /* Preoffset values for YUV to RGB Conversion */
379 #define PREOFF_YUV_TO_RGB_HI            0x1800
380 #define PREOFF_YUV_TO_RGB_ME            0x1F00
381 #define PREOFF_YUV_TO_RGB_LO            0x1800
382
383 #define  ROFF(x)          (((x) & 0xffff) << 16)
384 #define  GOFF(x)          (((x) & 0xffff) << 0)
385 #define  BOFF(x)          (((x) & 0xffff) << 16)
386
387 static void
388 icl_program_input_csc(struct intel_plane *plane,
389                       const struct intel_crtc_state *crtc_state,
390                       const struct intel_plane_state *plane_state)
391 {
392         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
393         enum pipe pipe = plane->pipe;
394         enum plane_id plane_id = plane->id;
395
396         static const u16 input_csc_matrix[][9] = {
397                 /*
398                  * BT.601 full range YCbCr -> full range RGB
399                  * The matrix required is :
400                  * [1.000, 0.000, 1.371,
401                  *  1.000, -0.336, -0.698,
402                  *  1.000, 1.732, 0.0000]
403                  */
404                 [DRM_COLOR_YCBCR_BT601] = {
405                         0x7AF8, 0x7800, 0x0,
406                         0x8B28, 0x7800, 0x9AC0,
407                         0x0, 0x7800, 0x7DD8,
408                 },
409                 /*
410                  * BT.709 full range YCbCr -> full range RGB
411                  * The matrix required is :
412                  * [1.000, 0.000, 1.574,
413                  *  1.000, -0.187, -0.468,
414                  *  1.000, 1.855, 0.0000]
415                  */
416                 [DRM_COLOR_YCBCR_BT709] = {
417                         0x7C98, 0x7800, 0x0,
418                         0x9EF8, 0x7800, 0xABF8,
419                         0x0, 0x7800,  0x7ED8,
420                 },
421         };
422
423         /* Matrix for Limited Range to Full Range Conversion */
424         static const u16 input_csc_matrix_lr[][9] = {
425                 /*
426                  * BT.601 Limted range YCbCr -> full range RGB
427                  * The matrix required is :
428                  * [1.164384, 0.000, 1.596370,
429                  *  1.138393, -0.382500, -0.794598,
430                  *  1.138393, 1.971696, 0.0000]
431                  */
432                 [DRM_COLOR_YCBCR_BT601] = {
433                         0x7CC8, 0x7950, 0x0,
434                         0x8CB8, 0x7918, 0x9C40,
435                         0x0, 0x7918, 0x7FC8,
436                 },
437                 /*
438                  * BT.709 Limited range YCbCr -> full range RGB
439                  * The matrix required is :
440                  * [1.164, 0.000, 1.833671,
441                  *  1.138393, -0.213249, -0.532909,
442                  *  1.138393, 2.112402, 0.0000]
443                  */
444                 [DRM_COLOR_YCBCR_BT709] = {
445                         0x7EA8, 0x7950, 0x0,
446                         0x8888, 0x7918, 0xADA8,
447                         0x0, 0x7918,  0x6870,
448                 },
449         };
450         const u16 *csc;
451
452         if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
453                 csc = input_csc_matrix[plane_state->base.color_encoding];
454         else
455                 csc = input_csc_matrix_lr[plane_state->base.color_encoding];
456
457         I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0), ROFF(csc[0]) |
458                       GOFF(csc[1]));
459         I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1), BOFF(csc[2]));
460         I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2), ROFF(csc[3]) |
461                       GOFF(csc[4]));
462         I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3), BOFF(csc[5]));
463         I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4), ROFF(csc[6]) |
464                       GOFF(csc[7]));
465         I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5), BOFF(csc[8]));
466
467         I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0),
468                       PREOFF_YUV_TO_RGB_HI);
469         I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
470                       PREOFF_YUV_TO_RGB_ME);
471         I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2),
472                       PREOFF_YUV_TO_RGB_LO);
473         I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0);
474         I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0);
475         I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0);
476 }
477
478 static void
479 skl_program_plane(struct intel_plane *plane,
480                   const struct intel_crtc_state *crtc_state,
481                   const struct intel_plane_state *plane_state,
482                   int color_plane, bool slave, u32 plane_ctl)
483 {
484         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
485         enum plane_id plane_id = plane->id;
486         enum pipe pipe = plane->pipe;
487         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
488         u32 surf_addr = plane_state->color_plane[color_plane].offset;
489         u32 stride = skl_plane_stride(plane_state, color_plane);
490         u32 aux_stride = skl_plane_stride(plane_state, 1);
491         int crtc_x = plane_state->base.dst.x1;
492         int crtc_y = plane_state->base.dst.y1;
493         u32 x = plane_state->color_plane[color_plane].x;
494         u32 y = plane_state->color_plane[color_plane].y;
495         u32 src_w = drm_rect_width(&plane_state->base.src) >> 16;
496         u32 src_h = drm_rect_height(&plane_state->base.src) >> 16;
497         struct intel_plane *linked = plane_state->linked_plane;
498         const struct drm_framebuffer *fb = plane_state->base.fb;
499         u8 alpha = plane_state->base.alpha >> 8;
500         u32 plane_color_ctl = 0;
501         unsigned long irqflags;
502         u32 keymsk, keymax;
503
504         plane_ctl |= skl_plane_ctl_crtc(crtc_state);
505
506         if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
507                 plane_color_ctl = plane_state->color_ctl |
508                         glk_plane_color_ctl_crtc(crtc_state);
509
510         /* Sizes are 0 based */
511         src_w--;
512         src_h--;
513
514         keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
515
516         keymsk = key->channel_mask & 0x7ffffff;
517         if (alpha < 0xff)
518                 keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
519
520         /* The scaler will handle the output position */
521         if (plane_state->scaler_id >= 0) {
522                 crtc_x = 0;
523                 crtc_y = 0;
524         }
525
526         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
527
528         I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
529         I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
530         I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
531         I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
532                       (plane_state->color_plane[1].offset - surf_addr) | aux_stride);
533
534         if (icl_is_hdr_plane(plane)) {
535                 u32 cus_ctl = 0;
536
537                 if (linked) {
538                         /* Enable and use MPEG-2 chroma siting */
539                         cus_ctl = PLANE_CUS_ENABLE |
540                                 PLANE_CUS_HPHASE_0 |
541                                 PLANE_CUS_VPHASE_SIGN_NEGATIVE |
542                                 PLANE_CUS_VPHASE_0_25;
543
544                         if (linked->id == PLANE_SPRITE5)
545                                 cus_ctl |= PLANE_CUS_PLANE_7;
546                         else if (linked->id == PLANE_SPRITE4)
547                                 cus_ctl |= PLANE_CUS_PLANE_6;
548                         else
549                                 MISSING_CASE(linked->id);
550                 }
551
552                 I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
553         }
554
555         if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
556                 I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl);
557
558         if (fb->format->is_yuv && icl_is_hdr_plane(plane))
559                 icl_program_input_csc(plane, crtc_state, plane_state);
560
561         skl_write_plane_wm(plane, crtc_state);
562
563         I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
564         I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
565         I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
566
567         I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
568
569         if (INTEL_GEN(dev_priv) < 11)
570                 I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
571                               (plane_state->color_plane[1].y << 16) |
572                               plane_state->color_plane[1].x);
573
574         /*
575          * The control register self-arms if the plane was previously
576          * disabled. Try to make the plane enable atomic by writing
577          * the control register just before the surface register.
578          */
579         I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
580         I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
581                       intel_plane_ggtt_offset(plane_state) + surf_addr);
582
583         if (!slave && plane_state->scaler_id >= 0)
584                 skl_program_scaler(plane, crtc_state, plane_state);
585
586         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
587 }
588
589 static void
590 skl_update_plane(struct intel_plane *plane,
591                  const struct intel_crtc_state *crtc_state,
592                  const struct intel_plane_state *plane_state)
593 {
594         int color_plane = 0;
595
596         if (plane_state->linked_plane) {
597                 /* Program the UV plane */
598                 color_plane = 1;
599         }
600
601         skl_program_plane(plane, crtc_state, plane_state,
602                           color_plane, false, plane_state->ctl);
603 }
604
605 static void
606 icl_update_slave(struct intel_plane *plane,
607                  const struct intel_crtc_state *crtc_state,
608                  const struct intel_plane_state *plane_state)
609 {
610         skl_program_plane(plane, crtc_state, plane_state, 0, true,
611                           plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE);
612 }
613
614 static void
615 skl_disable_plane(struct intel_plane *plane,
616                   const struct intel_crtc_state *crtc_state)
617 {
618         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
619         enum plane_id plane_id = plane->id;
620         enum pipe pipe = plane->pipe;
621         unsigned long irqflags;
622
623         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
624
625         skl_write_plane_wm(plane, crtc_state);
626
627         I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0);
628         I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0);
629
630         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
631 }
632
633 static bool
634 skl_plane_get_hw_state(struct intel_plane *plane,
635                        enum pipe *pipe)
636 {
637         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
638         enum intel_display_power_domain power_domain;
639         enum plane_id plane_id = plane->id;
640         intel_wakeref_t wakeref;
641         bool ret;
642
643         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
644         wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
645         if (!wakeref)
646                 return false;
647
648         ret = I915_READ(PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE;
649
650         *pipe = plane->pipe;
651
652         intel_display_power_put(dev_priv, power_domain, wakeref);
653
654         return ret;
655 }
656
657 static void
658 chv_update_csc(const struct intel_plane_state *plane_state)
659 {
660         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
661         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
662         const struct drm_framebuffer *fb = plane_state->base.fb;
663         enum plane_id plane_id = plane->id;
664         /*
665          * |r|   | c0 c1 c2 |   |cr|
666          * |g| = | c3 c4 c5 | x |y |
667          * |b|   | c6 c7 c8 |   |cb|
668          *
669          * Coefficients are s3.12.
670          *
671          * Cb and Cr apparently come in as signed already, and
672          * we always get full range data in on account of CLRC0/1.
673          */
674         static const s16 csc_matrix[][9] = {
675                 /* BT.601 full range YCbCr -> full range RGB */
676                 [DRM_COLOR_YCBCR_BT601] = {
677                          5743, 4096,     0,
678                         -2925, 4096, -1410,
679                             0, 4096,  7258,
680                 },
681                 /* BT.709 full range YCbCr -> full range RGB */
682                 [DRM_COLOR_YCBCR_BT709] = {
683                          6450, 4096,     0,
684                         -1917, 4096,  -767,
685                             0, 4096,  7601,
686                 },
687         };
688         const s16 *csc = csc_matrix[plane_state->base.color_encoding];
689
690         /* Seems RGB data bypasses the CSC always */
691         if (!fb->format->is_yuv)
692                 return;
693
694         I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
695         I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
696         I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
697
698         I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(csc[1]) | SPCSC_C0(csc[0]));
699         I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(csc[3]) | SPCSC_C0(csc[2]));
700         I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(csc[5]) | SPCSC_C0(csc[4]));
701         I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(csc[7]) | SPCSC_C0(csc[6]));
702         I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(csc[8]));
703
704         I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(1023) | SPCSC_IMIN(0));
705         I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
706         I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
707
708         I915_WRITE_FW(SPCSCYGOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
709         I915_WRITE_FW(SPCSCCBOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
710         I915_WRITE_FW(SPCSCCROCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
711 }
712
713 #define SIN_0 0
714 #define COS_0 1
715
716 static void
717 vlv_update_clrc(const struct intel_plane_state *plane_state)
718 {
719         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
720         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
721         const struct drm_framebuffer *fb = plane_state->base.fb;
722         enum pipe pipe = plane->pipe;
723         enum plane_id plane_id = plane->id;
724         int contrast, brightness, sh_scale, sh_sin, sh_cos;
725
726         if (fb->format->is_yuv &&
727             plane_state->base.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) {
728                 /*
729                  * Expand limited range to full range:
730                  * Contrast is applied first and is used to expand Y range.
731                  * Brightness is applied second and is used to remove the
732                  * offset from Y. Saturation/hue is used to expand CbCr range.
733                  */
734                 contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16);
735                 brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16);
736                 sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128);
737                 sh_sin = SIN_0 * sh_scale;
738                 sh_cos = COS_0 * sh_scale;
739         } else {
740                 /* Pass-through everything. */
741                 contrast = 1 << 6;
742                 brightness = 0;
743                 sh_scale = 1 << 7;
744                 sh_sin = SIN_0 * sh_scale;
745                 sh_cos = COS_0 * sh_scale;
746         }
747
748         /* FIXME these register are single buffered :( */
749         I915_WRITE_FW(SPCLRC0(pipe, plane_id),
750                       SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness));
751         I915_WRITE_FW(SPCLRC1(pipe, plane_id),
752                       SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos));
753 }
754
755 static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
756 {
757         return SP_GAMMA_ENABLE;
758 }
759
760 static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state,
761                           const struct intel_plane_state *plane_state)
762 {
763         const struct drm_framebuffer *fb = plane_state->base.fb;
764         unsigned int rotation = plane_state->base.rotation;
765         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
766         u32 sprctl;
767
768         sprctl = SP_ENABLE;
769
770         switch (fb->format->format) {
771         case DRM_FORMAT_YUYV:
772                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
773                 break;
774         case DRM_FORMAT_YVYU:
775                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
776                 break;
777         case DRM_FORMAT_UYVY:
778                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
779                 break;
780         case DRM_FORMAT_VYUY:
781                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
782                 break;
783         case DRM_FORMAT_RGB565:
784                 sprctl |= SP_FORMAT_BGR565;
785                 break;
786         case DRM_FORMAT_XRGB8888:
787                 sprctl |= SP_FORMAT_BGRX8888;
788                 break;
789         case DRM_FORMAT_ARGB8888:
790                 sprctl |= SP_FORMAT_BGRA8888;
791                 break;
792         case DRM_FORMAT_XBGR2101010:
793                 sprctl |= SP_FORMAT_RGBX1010102;
794                 break;
795         case DRM_FORMAT_ABGR2101010:
796                 sprctl |= SP_FORMAT_RGBA1010102;
797                 break;
798         case DRM_FORMAT_XBGR8888:
799                 sprctl |= SP_FORMAT_RGBX8888;
800                 break;
801         case DRM_FORMAT_ABGR8888:
802                 sprctl |= SP_FORMAT_RGBA8888;
803                 break;
804         default:
805                 MISSING_CASE(fb->format->format);
806                 return 0;
807         }
808
809         if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
810                 sprctl |= SP_YUV_FORMAT_BT709;
811
812         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
813                 sprctl |= SP_TILED;
814
815         if (rotation & DRM_MODE_ROTATE_180)
816                 sprctl |= SP_ROTATE_180;
817
818         if (rotation & DRM_MODE_REFLECT_X)
819                 sprctl |= SP_MIRROR;
820
821         if (key->flags & I915_SET_COLORKEY_SOURCE)
822                 sprctl |= SP_SOURCE_KEY;
823
824         return sprctl;
825 }
826
827 static void
828 vlv_update_plane(struct intel_plane *plane,
829                  const struct intel_crtc_state *crtc_state,
830                  const struct intel_plane_state *plane_state)
831 {
832         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
833         enum pipe pipe = plane->pipe;
834         enum plane_id plane_id = plane->id;
835         u32 sprsurf_offset = plane_state->color_plane[0].offset;
836         u32 linear_offset;
837         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
838         int crtc_x = plane_state->base.dst.x1;
839         int crtc_y = plane_state->base.dst.y1;
840         u32 crtc_w = drm_rect_width(&plane_state->base.dst);
841         u32 crtc_h = drm_rect_height(&plane_state->base.dst);
842         u32 x = plane_state->color_plane[0].x;
843         u32 y = plane_state->color_plane[0].y;
844         unsigned long irqflags;
845         u32 sprctl;
846
847         sprctl = plane_state->ctl | vlv_sprite_ctl_crtc(crtc_state);
848
849         /* Sizes are 0 based */
850         crtc_w--;
851         crtc_h--;
852
853         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
854
855         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
856
857         I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
858                       plane_state->color_plane[0].stride);
859         I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
860         I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
861         I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
862
863         if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
864                 chv_update_csc(plane_state);
865
866         if (key->flags) {
867                 I915_WRITE_FW(SPKEYMINVAL(pipe, plane_id), key->min_value);
868                 I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask);
869                 I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value);
870         }
871
872         I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
873         I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
874
875         /*
876          * The control register self-arms if the plane was previously
877          * disabled. Try to make the plane enable atomic by writing
878          * the control register just before the surface register.
879          */
880         I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl);
881         I915_WRITE_FW(SPSURF(pipe, plane_id),
882                       intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
883
884         vlv_update_clrc(plane_state);
885
886         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
887 }
888
889 static void
890 vlv_disable_plane(struct intel_plane *plane,
891                   const struct intel_crtc_state *crtc_state)
892 {
893         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
894         enum pipe pipe = plane->pipe;
895         enum plane_id plane_id = plane->id;
896         unsigned long irqflags;
897
898         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
899
900         I915_WRITE_FW(SPCNTR(pipe, plane_id), 0);
901         I915_WRITE_FW(SPSURF(pipe, plane_id), 0);
902
903         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
904 }
905
906 static bool
907 vlv_plane_get_hw_state(struct intel_plane *plane,
908                        enum pipe *pipe)
909 {
910         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
911         enum intel_display_power_domain power_domain;
912         enum plane_id plane_id = plane->id;
913         intel_wakeref_t wakeref;
914         bool ret;
915
916         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
917         wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
918         if (!wakeref)
919                 return false;
920
921         ret = I915_READ(SPCNTR(plane->pipe, plane_id)) & SP_ENABLE;
922
923         *pipe = plane->pipe;
924
925         intel_display_power_put(dev_priv, power_domain, wakeref);
926
927         return ret;
928 }
929
930 static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
931 {
932         struct drm_i915_private *dev_priv = to_i915(crtc_state->base.crtc->dev);
933         u32 sprctl = 0;
934
935         sprctl |= SPRITE_GAMMA_ENABLE;
936
937         if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
938                 sprctl |= SPRITE_PIPE_CSC_ENABLE;
939
940         return sprctl;
941 }
942
943 static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
944                           const struct intel_plane_state *plane_state)
945 {
946         struct drm_i915_private *dev_priv =
947                 to_i915(plane_state->base.plane->dev);
948         const struct drm_framebuffer *fb = plane_state->base.fb;
949         unsigned int rotation = plane_state->base.rotation;
950         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
951         u32 sprctl;
952
953         sprctl = SPRITE_ENABLE;
954
955         if (IS_IVYBRIDGE(dev_priv))
956                 sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
957
958         switch (fb->format->format) {
959         case DRM_FORMAT_XBGR8888:
960                 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
961                 break;
962         case DRM_FORMAT_XRGB8888:
963                 sprctl |= SPRITE_FORMAT_RGBX888;
964                 break;
965         case DRM_FORMAT_YUYV:
966                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
967                 break;
968         case DRM_FORMAT_YVYU:
969                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
970                 break;
971         case DRM_FORMAT_UYVY:
972                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
973                 break;
974         case DRM_FORMAT_VYUY:
975                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
976                 break;
977         default:
978                 MISSING_CASE(fb->format->format);
979                 return 0;
980         }
981
982         if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
983                 sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
984
985         if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
986                 sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE;
987
988         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
989                 sprctl |= SPRITE_TILED;
990
991         if (rotation & DRM_MODE_ROTATE_180)
992                 sprctl |= SPRITE_ROTATE_180;
993
994         if (key->flags & I915_SET_COLORKEY_DESTINATION)
995                 sprctl |= SPRITE_DEST_KEY;
996         else if (key->flags & I915_SET_COLORKEY_SOURCE)
997                 sprctl |= SPRITE_SOURCE_KEY;
998
999         return sprctl;
1000 }
1001
1002 static void
1003 ivb_update_plane(struct intel_plane *plane,
1004                  const struct intel_crtc_state *crtc_state,
1005                  const struct intel_plane_state *plane_state)
1006 {
1007         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1008         enum pipe pipe = plane->pipe;
1009         u32 sprsurf_offset = plane_state->color_plane[0].offset;
1010         u32 linear_offset;
1011         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1012         int crtc_x = plane_state->base.dst.x1;
1013         int crtc_y = plane_state->base.dst.y1;
1014         u32 crtc_w = drm_rect_width(&plane_state->base.dst);
1015         u32 crtc_h = drm_rect_height(&plane_state->base.dst);
1016         u32 x = plane_state->color_plane[0].x;
1017         u32 y = plane_state->color_plane[0].y;
1018         u32 src_w = drm_rect_width(&plane_state->base.src) >> 16;
1019         u32 src_h = drm_rect_height(&plane_state->base.src) >> 16;
1020         u32 sprctl, sprscale = 0;
1021         unsigned long irqflags;
1022
1023         sprctl = plane_state->ctl | ivb_sprite_ctl_crtc(crtc_state);
1024
1025         /* Sizes are 0 based */
1026         src_w--;
1027         src_h--;
1028         crtc_w--;
1029         crtc_h--;
1030
1031         if (crtc_w != src_w || crtc_h != src_h)
1032                 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
1033
1034         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
1035
1036         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1037
1038         I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
1039         I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
1040         I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
1041         if (IS_IVYBRIDGE(dev_priv))
1042                 I915_WRITE_FW(SPRSCALE(pipe), sprscale);
1043
1044         if (key->flags) {
1045                 I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value);
1046                 I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask);
1047                 I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value);
1048         }
1049
1050         /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
1051          * register */
1052         if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
1053                 I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x);
1054         } else {
1055                 I915_WRITE_FW(SPRLINOFF(pipe), linear_offset);
1056                 I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x);
1057         }
1058
1059         /*
1060          * The control register self-arms if the plane was previously
1061          * disabled. Try to make the plane enable atomic by writing
1062          * the control register just before the surface register.
1063          */
1064         I915_WRITE_FW(SPRCTL(pipe), sprctl);
1065         I915_WRITE_FW(SPRSURF(pipe),
1066                       intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
1067
1068         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1069 }
1070
1071 static void
1072 ivb_disable_plane(struct intel_plane *plane,
1073                   const struct intel_crtc_state *crtc_state)
1074 {
1075         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1076         enum pipe pipe = plane->pipe;
1077         unsigned long irqflags;
1078
1079         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1080
1081         I915_WRITE_FW(SPRCTL(pipe), 0);
1082         /* Disable the scaler */
1083         if (IS_IVYBRIDGE(dev_priv))
1084                 I915_WRITE_FW(SPRSCALE(pipe), 0);
1085         I915_WRITE_FW(SPRSURF(pipe), 0);
1086
1087         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1088 }
1089
1090 static bool
1091 ivb_plane_get_hw_state(struct intel_plane *plane,
1092                        enum pipe *pipe)
1093 {
1094         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1095         enum intel_display_power_domain power_domain;
1096         intel_wakeref_t wakeref;
1097         bool ret;
1098
1099         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
1100         wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
1101         if (!wakeref)
1102                 return false;
1103
1104         ret =  I915_READ(SPRCTL(plane->pipe)) & SPRITE_ENABLE;
1105
1106         *pipe = plane->pipe;
1107
1108         intel_display_power_put(dev_priv, power_domain, wakeref);
1109
1110         return ret;
1111 }
1112
1113 static unsigned int
1114 g4x_sprite_max_stride(struct intel_plane *plane,
1115                       u32 pixel_format, u64 modifier,
1116                       unsigned int rotation)
1117 {
1118         return 16384;
1119 }
1120
1121 static u32 g4x_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
1122 {
1123         return DVS_GAMMA_ENABLE;
1124 }
1125
1126 static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state,
1127                           const struct intel_plane_state *plane_state)
1128 {
1129         struct drm_i915_private *dev_priv =
1130                 to_i915(plane_state->base.plane->dev);
1131         const struct drm_framebuffer *fb = plane_state->base.fb;
1132         unsigned int rotation = plane_state->base.rotation;
1133         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1134         u32 dvscntr;
1135
1136         dvscntr = DVS_ENABLE;
1137
1138         if (IS_GEN(dev_priv, 6))
1139                 dvscntr |= DVS_TRICKLE_FEED_DISABLE;
1140
1141         switch (fb->format->format) {
1142         case DRM_FORMAT_XBGR8888:
1143                 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
1144                 break;
1145         case DRM_FORMAT_XRGB8888:
1146                 dvscntr |= DVS_FORMAT_RGBX888;
1147                 break;
1148         case DRM_FORMAT_YUYV:
1149                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
1150                 break;
1151         case DRM_FORMAT_YVYU:
1152                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
1153                 break;
1154         case DRM_FORMAT_UYVY:
1155                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
1156                 break;
1157         case DRM_FORMAT_VYUY:
1158                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
1159                 break;
1160         default:
1161                 MISSING_CASE(fb->format->format);
1162                 return 0;
1163         }
1164
1165         if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
1166                 dvscntr |= DVS_YUV_FORMAT_BT709;
1167
1168         if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
1169                 dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE;
1170
1171         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
1172                 dvscntr |= DVS_TILED;
1173
1174         if (rotation & DRM_MODE_ROTATE_180)
1175                 dvscntr |= DVS_ROTATE_180;
1176
1177         if (key->flags & I915_SET_COLORKEY_DESTINATION)
1178                 dvscntr |= DVS_DEST_KEY;
1179         else if (key->flags & I915_SET_COLORKEY_SOURCE)
1180                 dvscntr |= DVS_SOURCE_KEY;
1181
1182         return dvscntr;
1183 }
1184
1185 static void
1186 g4x_update_plane(struct intel_plane *plane,
1187                  const struct intel_crtc_state *crtc_state,
1188                  const struct intel_plane_state *plane_state)
1189 {
1190         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1191         enum pipe pipe = plane->pipe;
1192         u32 dvssurf_offset = plane_state->color_plane[0].offset;
1193         u32 linear_offset;
1194         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1195         int crtc_x = plane_state->base.dst.x1;
1196         int crtc_y = plane_state->base.dst.y1;
1197         u32 crtc_w = drm_rect_width(&plane_state->base.dst);
1198         u32 crtc_h = drm_rect_height(&plane_state->base.dst);
1199         u32 x = plane_state->color_plane[0].x;
1200         u32 y = plane_state->color_plane[0].y;
1201         u32 src_w = drm_rect_width(&plane_state->base.src) >> 16;
1202         u32 src_h = drm_rect_height(&plane_state->base.src) >> 16;
1203         u32 dvscntr, dvsscale = 0;
1204         unsigned long irqflags;
1205
1206         dvscntr = plane_state->ctl | g4x_sprite_ctl_crtc(crtc_state);
1207
1208         /* Sizes are 0 based */
1209         src_w--;
1210         src_h--;
1211         crtc_w--;
1212         crtc_h--;
1213
1214         if (crtc_w != src_w || crtc_h != src_h)
1215                 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
1216
1217         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
1218
1219         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1220
1221         I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
1222         I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
1223         I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
1224         I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
1225
1226         if (key->flags) {
1227                 I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value);
1228                 I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask);
1229                 I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value);
1230         }
1231
1232         I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
1233         I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
1234
1235         /*
1236          * The control register self-arms if the plane was previously
1237          * disabled. Try to make the plane enable atomic by writing
1238          * the control register just before the surface register.
1239          */
1240         I915_WRITE_FW(DVSCNTR(pipe), dvscntr);
1241         I915_WRITE_FW(DVSSURF(pipe),
1242                       intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
1243
1244         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1245 }
1246
1247 static void
1248 g4x_disable_plane(struct intel_plane *plane,
1249                   const struct intel_crtc_state *crtc_state)
1250 {
1251         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1252         enum pipe pipe = plane->pipe;
1253         unsigned long irqflags;
1254
1255         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1256
1257         I915_WRITE_FW(DVSCNTR(pipe), 0);
1258         /* Disable the scaler */
1259         I915_WRITE_FW(DVSSCALE(pipe), 0);
1260         I915_WRITE_FW(DVSSURF(pipe), 0);
1261
1262         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1263 }
1264
1265 static bool
1266 g4x_plane_get_hw_state(struct intel_plane *plane,
1267                        enum pipe *pipe)
1268 {
1269         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1270         enum intel_display_power_domain power_domain;
1271         intel_wakeref_t wakeref;
1272         bool ret;
1273
1274         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
1275         wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
1276         if (!wakeref)
1277                 return false;
1278
1279         ret = I915_READ(DVSCNTR(plane->pipe)) & DVS_ENABLE;
1280
1281         *pipe = plane->pipe;
1282
1283         intel_display_power_put(dev_priv, power_domain, wakeref);
1284
1285         return ret;
1286 }
1287
1288 static bool intel_fb_scalable(const struct drm_framebuffer *fb)
1289 {
1290         if (!fb)
1291                 return false;
1292
1293         switch (fb->format->format) {
1294         case DRM_FORMAT_C8:
1295                 return false;
1296         default:
1297                 return true;
1298         }
1299 }
1300
1301 static int
1302 g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
1303                          struct intel_plane_state *plane_state)
1304 {
1305         const struct drm_framebuffer *fb = plane_state->base.fb;
1306         const struct drm_rect *src = &plane_state->base.src;
1307         const struct drm_rect *dst = &plane_state->base.dst;
1308         int src_x, src_y, src_w, src_h, crtc_w, crtc_h;
1309         const struct drm_display_mode *adjusted_mode =
1310                 &crtc_state->base.adjusted_mode;
1311         unsigned int cpp = fb->format->cpp[0];
1312         unsigned int width_bytes;
1313         int min_width, min_height;
1314
1315         crtc_w = drm_rect_width(dst);
1316         crtc_h = drm_rect_height(dst);
1317
1318         src_x = src->x1 >> 16;
1319         src_y = src->y1 >> 16;
1320         src_w = drm_rect_width(src) >> 16;
1321         src_h = drm_rect_height(src) >> 16;
1322
1323         if (src_w == crtc_w && src_h == crtc_h)
1324                 return 0;
1325
1326         min_width = 3;
1327
1328         if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
1329                 if (src_h & 1) {
1330                         DRM_DEBUG_KMS("Source height must be even with interlaced modes\n");
1331                         return -EINVAL;
1332                 }
1333                 min_height = 6;
1334         } else {
1335                 min_height = 3;
1336         }
1337
1338         width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
1339
1340         if (src_w < min_width || src_h < min_height ||
1341             src_w > 2048 || src_h > 2048) {
1342                 DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
1343                               src_w, src_h, min_width, min_height, 2048, 2048);
1344                 return -EINVAL;
1345         }
1346
1347         if (width_bytes > 4096) {
1348                 DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n",
1349                               width_bytes, 4096);
1350                 return -EINVAL;
1351         }
1352
1353         if (width_bytes > 4096 || fb->pitches[0] > 4096) {
1354                 DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n",
1355                               fb->pitches[0], 4096);
1356                 return -EINVAL;
1357         }
1358
1359         return 0;
1360 }
1361
1362 static int
1363 g4x_sprite_check(struct intel_crtc_state *crtc_state,
1364                  struct intel_plane_state *plane_state)
1365 {
1366         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1367         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1368         int min_scale = DRM_PLANE_HELPER_NO_SCALING;
1369         int max_scale = DRM_PLANE_HELPER_NO_SCALING;
1370         int ret;
1371
1372         if (intel_fb_scalable(plane_state->base.fb)) {
1373                 if (INTEL_GEN(dev_priv) < 7) {
1374                         min_scale = 1;
1375                         max_scale = 16 << 16;
1376                 } else if (IS_IVYBRIDGE(dev_priv)) {
1377                         min_scale = 1;
1378                         max_scale = 2 << 16;
1379                 }
1380         }
1381
1382         ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1383                                                   &crtc_state->base,
1384                                                   min_scale, max_scale,
1385                                                   true, true);
1386         if (ret)
1387                 return ret;
1388
1389         if (!plane_state->base.visible)
1390                 return 0;
1391
1392         ret = intel_plane_check_src_coordinates(plane_state);
1393         if (ret)
1394                 return ret;
1395
1396         ret = g4x_sprite_check_scaling(crtc_state, plane_state);
1397         if (ret)
1398                 return ret;
1399
1400         ret = i9xx_check_plane_surface(plane_state);
1401         if (ret)
1402                 return ret;
1403
1404         if (INTEL_GEN(dev_priv) >= 7)
1405                 plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state);
1406         else
1407                 plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state);
1408
1409         return 0;
1410 }
1411
1412 int chv_plane_check_rotation(const struct intel_plane_state *plane_state)
1413 {
1414         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1415         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1416         unsigned int rotation = plane_state->base.rotation;
1417
1418         /* CHV ignores the mirror bit when the rotate bit is set :( */
1419         if (IS_CHERRYVIEW(dev_priv) &&
1420             rotation & DRM_MODE_ROTATE_180 &&
1421             rotation & DRM_MODE_REFLECT_X) {
1422                 DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n");
1423                 return -EINVAL;
1424         }
1425
1426         return 0;
1427 }
1428
1429 static int
1430 vlv_sprite_check(struct intel_crtc_state *crtc_state,
1431                  struct intel_plane_state *plane_state)
1432 {
1433         int ret;
1434
1435         ret = chv_plane_check_rotation(plane_state);
1436         if (ret)
1437                 return ret;
1438
1439         ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1440                                                   &crtc_state->base,
1441                                                   DRM_PLANE_HELPER_NO_SCALING,
1442                                                   DRM_PLANE_HELPER_NO_SCALING,
1443                                                   true, true);
1444         if (ret)
1445                 return ret;
1446
1447         if (!plane_state->base.visible)
1448                 return 0;
1449
1450         ret = intel_plane_check_src_coordinates(plane_state);
1451         if (ret)
1452                 return ret;
1453
1454         ret = i9xx_check_plane_surface(plane_state);
1455         if (ret)
1456                 return ret;
1457
1458         plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state);
1459
1460         return 0;
1461 }
1462
1463 static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
1464                               const struct intel_plane_state *plane_state)
1465 {
1466         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1467         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1468         const struct drm_framebuffer *fb = plane_state->base.fb;
1469         unsigned int rotation = plane_state->base.rotation;
1470         struct drm_format_name_buf format_name;
1471
1472         if (!fb)
1473                 return 0;
1474
1475         if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) &&
1476             is_ccs_modifier(fb->modifier)) {
1477                 DRM_DEBUG_KMS("RC support only with 0/180 degree rotation (%x)\n",
1478                               rotation);
1479                 return -EINVAL;
1480         }
1481
1482         if (rotation & DRM_MODE_REFLECT_X &&
1483             fb->modifier == DRM_FORMAT_MOD_LINEAR) {
1484                 DRM_DEBUG_KMS("horizontal flip is not supported with linear surface formats\n");
1485                 return -EINVAL;
1486         }
1487
1488         if (drm_rotation_90_or_270(rotation)) {
1489                 if (fb->modifier != I915_FORMAT_MOD_Y_TILED &&
1490                     fb->modifier != I915_FORMAT_MOD_Yf_TILED) {
1491                         DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n");
1492                         return -EINVAL;
1493                 }
1494
1495                 /*
1496                  * 90/270 is not allowed with RGB64 16:16:16:16 and
1497                  * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards.
1498                  * TBD: Add RGB64 case once its added in supported format
1499                  * list.
1500                  */
1501                 switch (fb->format->format) {
1502                 case DRM_FORMAT_RGB565:
1503                         if (INTEL_GEN(dev_priv) >= 11)
1504                                 break;
1505                         /* fall through */
1506                 case DRM_FORMAT_C8:
1507                         DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n",
1508                                       drm_get_format_name(fb->format->format,
1509                                                           &format_name));
1510                         return -EINVAL;
1511                 default:
1512                         break;
1513                 }
1514         }
1515
1516         /* Y-tiling is not supported in IF-ID Interlace mode */
1517         if (crtc_state->base.enable &&
1518             crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
1519             (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
1520              fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
1521              fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
1522              fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS)) {
1523                 DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n");
1524                 return -EINVAL;
1525         }
1526
1527         return 0;
1528 }
1529
1530 static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state,
1531                                            const struct intel_plane_state *plane_state)
1532 {
1533         struct drm_i915_private *dev_priv =
1534                 to_i915(plane_state->base.plane->dev);
1535         int crtc_x = plane_state->base.dst.x1;
1536         int crtc_w = drm_rect_width(&plane_state->base.dst);
1537         int pipe_src_w = crtc_state->pipe_src_w;
1538
1539         /*
1540          * Display WA #1175: cnl,glk
1541          * Planes other than the cursor may cause FIFO underflow and display
1542          * corruption if starting less than 4 pixels from the right edge of
1543          * the screen.
1544          * Besides the above WA fix the similar problem, where planes other
1545          * than the cursor ending less than 4 pixels from the left edge of the
1546          * screen may cause FIFO underflow and display corruption.
1547          */
1548         if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
1549             (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
1550                 DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n",
1551                               crtc_x + crtc_w < 4 ? "end" : "start",
1552                               crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x,
1553                               4, pipe_src_w - 4);
1554                 return -ERANGE;
1555         }
1556
1557         return 0;
1558 }
1559
1560 static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
1561 {
1562         const struct drm_framebuffer *fb = plane_state->base.fb;
1563         unsigned int rotation = plane_state->base.rotation;
1564         int src_w = drm_rect_width(&plane_state->base.src) >> 16;
1565
1566         /* Display WA #1106 */
1567         if (is_planar_yuv_format(fb->format->format) && src_w & 3 &&
1568             (rotation == DRM_MODE_ROTATE_270 ||
1569              rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
1570                 DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n");
1571                 return -EINVAL;
1572         }
1573
1574         return 0;
1575 }
1576
1577 static int skl_plane_check(struct intel_crtc_state *crtc_state,
1578                            struct intel_plane_state *plane_state)
1579 {
1580         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1581         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1582         const struct drm_framebuffer *fb = plane_state->base.fb;
1583         int min_scale = DRM_PLANE_HELPER_NO_SCALING;
1584         int max_scale = DRM_PLANE_HELPER_NO_SCALING;
1585         int ret;
1586
1587         ret = skl_plane_check_fb(crtc_state, plane_state);
1588         if (ret)
1589                 return ret;
1590
1591         /* use scaler when colorkey is not required */
1592         if (!plane_state->ckey.flags && intel_fb_scalable(fb)) {
1593                 min_scale = 1;
1594                 max_scale = skl_max_scale(crtc_state, fb->format->format);
1595         }
1596
1597         ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1598                                                   &crtc_state->base,
1599                                                   min_scale, max_scale,
1600                                                   true, true);
1601         if (ret)
1602                 return ret;
1603
1604         if (!plane_state->base.visible)
1605                 return 0;
1606
1607         ret = skl_plane_check_dst_coordinates(crtc_state, plane_state);
1608         if (ret)
1609                 return ret;
1610
1611         ret = intel_plane_check_src_coordinates(plane_state);
1612         if (ret)
1613                 return ret;
1614
1615         ret = skl_plane_check_nv12_rotation(plane_state);
1616         if (ret)
1617                 return ret;
1618
1619         ret = skl_check_plane_surface(plane_state);
1620         if (ret)
1621                 return ret;
1622
1623         /* HW only has 8 bits pixel precision, disable plane if invisible */
1624         if (!(plane_state->base.alpha >> 8))
1625                 plane_state->base.visible = false;
1626
1627         plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
1628
1629         if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
1630                 plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
1631                                                              plane_state);
1632
1633         return 0;
1634 }
1635
1636 static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv)
1637 {
1638         return INTEL_GEN(dev_priv) >= 9;
1639 }
1640
1641 static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
1642                                  const struct drm_intel_sprite_colorkey *set)
1643 {
1644         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1645         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1646         struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1647
1648         *key = *set;
1649
1650         /*
1651          * We want src key enabled on the
1652          * sprite and not on the primary.
1653          */
1654         if (plane->id == PLANE_PRIMARY &&
1655             set->flags & I915_SET_COLORKEY_SOURCE)
1656                 key->flags = 0;
1657
1658         /*
1659          * On SKL+ we want dst key enabled on
1660          * the primary and not on the sprite.
1661          */
1662         if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_PRIMARY &&
1663             set->flags & I915_SET_COLORKEY_DESTINATION)
1664                 key->flags = 0;
1665 }
1666
1667 int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
1668                                     struct drm_file *file_priv)
1669 {
1670         struct drm_i915_private *dev_priv = to_i915(dev);
1671         struct drm_intel_sprite_colorkey *set = data;
1672         struct drm_plane *plane;
1673         struct drm_plane_state *plane_state;
1674         struct drm_atomic_state *state;
1675         struct drm_modeset_acquire_ctx ctx;
1676         int ret = 0;
1677
1678         /* ignore the pointless "none" flag */
1679         set->flags &= ~I915_SET_COLORKEY_NONE;
1680
1681         if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
1682                 return -EINVAL;
1683
1684         /* Make sure we don't try to enable both src & dest simultaneously */
1685         if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
1686                 return -EINVAL;
1687
1688         if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
1689             set->flags & I915_SET_COLORKEY_DESTINATION)
1690                 return -EINVAL;
1691
1692         plane = drm_plane_find(dev, file_priv, set->plane_id);
1693         if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
1694                 return -ENOENT;
1695
1696         /*
1697          * SKL+ only plane 2 can do destination keying against plane 1.
1698          * Also multiple planes can't do destination keying on the same
1699          * pipe simultaneously.
1700          */
1701         if (INTEL_GEN(dev_priv) >= 9 &&
1702             to_intel_plane(plane)->id >= PLANE_SPRITE1 &&
1703             set->flags & I915_SET_COLORKEY_DESTINATION)
1704                 return -EINVAL;
1705
1706         drm_modeset_acquire_init(&ctx, 0);
1707
1708         state = drm_atomic_state_alloc(plane->dev);
1709         if (!state) {
1710                 ret = -ENOMEM;
1711                 goto out;
1712         }
1713         state->acquire_ctx = &ctx;
1714
1715         while (1) {
1716                 plane_state = drm_atomic_get_plane_state(state, plane);
1717                 ret = PTR_ERR_OR_ZERO(plane_state);
1718                 if (!ret)
1719                         intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
1720
1721                 /*
1722                  * On some platforms we have to configure
1723                  * the dst colorkey on the primary plane.
1724                  */
1725                 if (!ret && has_dst_key_in_primary_plane(dev_priv)) {
1726                         struct intel_crtc *crtc =
1727                                 intel_get_crtc_for_pipe(dev_priv,
1728                                                         to_intel_plane(plane)->pipe);
1729
1730                         plane_state = drm_atomic_get_plane_state(state,
1731                                                                  crtc->base.primary);
1732                         ret = PTR_ERR_OR_ZERO(plane_state);
1733                         if (!ret)
1734                                 intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
1735                 }
1736
1737                 if (!ret)
1738                         ret = drm_atomic_commit(state);
1739
1740                 if (ret != -EDEADLK)
1741                         break;
1742
1743                 drm_atomic_state_clear(state);
1744                 drm_modeset_backoff(&ctx);
1745         }
1746
1747         drm_atomic_state_put(state);
1748 out:
1749         drm_modeset_drop_locks(&ctx);
1750         drm_modeset_acquire_fini(&ctx);
1751         return ret;
1752 }
1753
1754 static const u32 g4x_plane_formats[] = {
1755         DRM_FORMAT_XRGB8888,
1756         DRM_FORMAT_YUYV,
1757         DRM_FORMAT_YVYU,
1758         DRM_FORMAT_UYVY,
1759         DRM_FORMAT_VYUY,
1760 };
1761
1762 static const u64 i9xx_plane_format_modifiers[] = {
1763         I915_FORMAT_MOD_X_TILED,
1764         DRM_FORMAT_MOD_LINEAR,
1765         DRM_FORMAT_MOD_INVALID
1766 };
1767
1768 static const u32 snb_plane_formats[] = {
1769         DRM_FORMAT_XBGR8888,
1770         DRM_FORMAT_XRGB8888,
1771         DRM_FORMAT_YUYV,
1772         DRM_FORMAT_YVYU,
1773         DRM_FORMAT_UYVY,
1774         DRM_FORMAT_VYUY,
1775 };
1776
1777 static const u32 vlv_plane_formats[] = {
1778         DRM_FORMAT_RGB565,
1779         DRM_FORMAT_ABGR8888,
1780         DRM_FORMAT_ARGB8888,
1781         DRM_FORMAT_XBGR8888,
1782         DRM_FORMAT_XRGB8888,
1783         DRM_FORMAT_XBGR2101010,
1784         DRM_FORMAT_ABGR2101010,
1785         DRM_FORMAT_YUYV,
1786         DRM_FORMAT_YVYU,
1787         DRM_FORMAT_UYVY,
1788         DRM_FORMAT_VYUY,
1789 };
1790
1791 static const u32 skl_plane_formats[] = {
1792         DRM_FORMAT_C8,
1793         DRM_FORMAT_RGB565,
1794         DRM_FORMAT_XRGB8888,
1795         DRM_FORMAT_XBGR8888,
1796         DRM_FORMAT_ARGB8888,
1797         DRM_FORMAT_ABGR8888,
1798         DRM_FORMAT_XRGB2101010,
1799         DRM_FORMAT_XBGR2101010,
1800         DRM_FORMAT_YUYV,
1801         DRM_FORMAT_YVYU,
1802         DRM_FORMAT_UYVY,
1803         DRM_FORMAT_VYUY,
1804 };
1805
1806 static const uint32_t icl_plane_formats[] = {
1807         DRM_FORMAT_C8,
1808         DRM_FORMAT_RGB565,
1809         DRM_FORMAT_XRGB8888,
1810         DRM_FORMAT_XBGR8888,
1811         DRM_FORMAT_ARGB8888,
1812         DRM_FORMAT_ABGR8888,
1813         DRM_FORMAT_XRGB2101010,
1814         DRM_FORMAT_XBGR2101010,
1815         DRM_FORMAT_YUYV,
1816         DRM_FORMAT_YVYU,
1817         DRM_FORMAT_UYVY,
1818         DRM_FORMAT_VYUY,
1819         DRM_FORMAT_Y210,
1820         DRM_FORMAT_Y212,
1821         DRM_FORMAT_Y216,
1822         DRM_FORMAT_Y410,
1823         DRM_FORMAT_Y412,
1824         DRM_FORMAT_Y416,
1825 };
1826
1827 static const u32 skl_planar_formats[] = {
1828         DRM_FORMAT_C8,
1829         DRM_FORMAT_RGB565,
1830         DRM_FORMAT_XRGB8888,
1831         DRM_FORMAT_XBGR8888,
1832         DRM_FORMAT_ARGB8888,
1833         DRM_FORMAT_ABGR8888,
1834         DRM_FORMAT_XRGB2101010,
1835         DRM_FORMAT_XBGR2101010,
1836         DRM_FORMAT_YUYV,
1837         DRM_FORMAT_YVYU,
1838         DRM_FORMAT_UYVY,
1839         DRM_FORMAT_VYUY,
1840         DRM_FORMAT_NV12,
1841 };
1842
1843 static const uint32_t glk_planar_formats[] = {
1844         DRM_FORMAT_C8,
1845         DRM_FORMAT_RGB565,
1846         DRM_FORMAT_XRGB8888,
1847         DRM_FORMAT_XBGR8888,
1848         DRM_FORMAT_ARGB8888,
1849         DRM_FORMAT_ABGR8888,
1850         DRM_FORMAT_XRGB2101010,
1851         DRM_FORMAT_XBGR2101010,
1852         DRM_FORMAT_YUYV,
1853         DRM_FORMAT_YVYU,
1854         DRM_FORMAT_UYVY,
1855         DRM_FORMAT_VYUY,
1856         DRM_FORMAT_NV12,
1857         DRM_FORMAT_P010,
1858         DRM_FORMAT_P012,
1859         DRM_FORMAT_P016,
1860 };
1861
1862 static const uint32_t icl_planar_formats[] = {
1863         DRM_FORMAT_C8,
1864         DRM_FORMAT_RGB565,
1865         DRM_FORMAT_XRGB8888,
1866         DRM_FORMAT_XBGR8888,
1867         DRM_FORMAT_ARGB8888,
1868         DRM_FORMAT_ABGR8888,
1869         DRM_FORMAT_XRGB2101010,
1870         DRM_FORMAT_XBGR2101010,
1871         DRM_FORMAT_YUYV,
1872         DRM_FORMAT_YVYU,
1873         DRM_FORMAT_UYVY,
1874         DRM_FORMAT_VYUY,
1875         DRM_FORMAT_NV12,
1876         DRM_FORMAT_P010,
1877         DRM_FORMAT_P012,
1878         DRM_FORMAT_P016,
1879         DRM_FORMAT_Y210,
1880         DRM_FORMAT_Y212,
1881         DRM_FORMAT_Y216,
1882         DRM_FORMAT_Y410,
1883         DRM_FORMAT_Y412,
1884         DRM_FORMAT_Y416,
1885 };
1886
1887 static const u64 skl_plane_format_modifiers_noccs[] = {
1888         I915_FORMAT_MOD_Yf_TILED,
1889         I915_FORMAT_MOD_Y_TILED,
1890         I915_FORMAT_MOD_X_TILED,
1891         DRM_FORMAT_MOD_LINEAR,
1892         DRM_FORMAT_MOD_INVALID
1893 };
1894
1895 static const u64 skl_plane_format_modifiers_ccs[] = {
1896         I915_FORMAT_MOD_Yf_TILED_CCS,
1897         I915_FORMAT_MOD_Y_TILED_CCS,
1898         I915_FORMAT_MOD_Yf_TILED,
1899         I915_FORMAT_MOD_Y_TILED,
1900         I915_FORMAT_MOD_X_TILED,
1901         DRM_FORMAT_MOD_LINEAR,
1902         DRM_FORMAT_MOD_INVALID
1903 };
1904
1905 static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane,
1906                                             u32 format, u64 modifier)
1907 {
1908         switch (modifier) {
1909         case DRM_FORMAT_MOD_LINEAR:
1910         case I915_FORMAT_MOD_X_TILED:
1911                 break;
1912         default:
1913                 return false;
1914         }
1915
1916         switch (format) {
1917         case DRM_FORMAT_XRGB8888:
1918         case DRM_FORMAT_YUYV:
1919         case DRM_FORMAT_YVYU:
1920         case DRM_FORMAT_UYVY:
1921         case DRM_FORMAT_VYUY:
1922                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
1923                     modifier == I915_FORMAT_MOD_X_TILED)
1924                         return true;
1925                 /* fall through */
1926         default:
1927                 return false;
1928         }
1929 }
1930
1931 static bool snb_sprite_format_mod_supported(struct drm_plane *_plane,
1932                                             u32 format, u64 modifier)
1933 {
1934         switch (modifier) {
1935         case DRM_FORMAT_MOD_LINEAR:
1936         case I915_FORMAT_MOD_X_TILED:
1937                 break;
1938         default:
1939                 return false;
1940         }
1941
1942         switch (format) {
1943         case DRM_FORMAT_XRGB8888:
1944         case DRM_FORMAT_XBGR8888:
1945         case DRM_FORMAT_YUYV:
1946         case DRM_FORMAT_YVYU:
1947         case DRM_FORMAT_UYVY:
1948         case DRM_FORMAT_VYUY:
1949                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
1950                     modifier == I915_FORMAT_MOD_X_TILED)
1951                         return true;
1952                 /* fall through */
1953         default:
1954                 return false;
1955         }
1956 }
1957
1958 static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane,
1959                                             u32 format, u64 modifier)
1960 {
1961         switch (modifier) {
1962         case DRM_FORMAT_MOD_LINEAR:
1963         case I915_FORMAT_MOD_X_TILED:
1964                 break;
1965         default:
1966                 return false;
1967         }
1968
1969         switch (format) {
1970         case DRM_FORMAT_RGB565:
1971         case DRM_FORMAT_ABGR8888:
1972         case DRM_FORMAT_ARGB8888:
1973         case DRM_FORMAT_XBGR8888:
1974         case DRM_FORMAT_XRGB8888:
1975         case DRM_FORMAT_XBGR2101010:
1976         case DRM_FORMAT_ABGR2101010:
1977         case DRM_FORMAT_YUYV:
1978         case DRM_FORMAT_YVYU:
1979         case DRM_FORMAT_UYVY:
1980         case DRM_FORMAT_VYUY:
1981                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
1982                     modifier == I915_FORMAT_MOD_X_TILED)
1983                         return true;
1984                 /* fall through */
1985         default:
1986                 return false;
1987         }
1988 }
1989
1990 static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
1991                                            u32 format, u64 modifier)
1992 {
1993         struct intel_plane *plane = to_intel_plane(_plane);
1994
1995         switch (modifier) {
1996         case DRM_FORMAT_MOD_LINEAR:
1997         case I915_FORMAT_MOD_X_TILED:
1998         case I915_FORMAT_MOD_Y_TILED:
1999         case I915_FORMAT_MOD_Yf_TILED:
2000                 break;
2001         case I915_FORMAT_MOD_Y_TILED_CCS:
2002         case I915_FORMAT_MOD_Yf_TILED_CCS:
2003                 if (!plane->has_ccs)
2004                         return false;
2005                 break;
2006         default:
2007                 return false;
2008         }
2009
2010         switch (format) {
2011         case DRM_FORMAT_XRGB8888:
2012         case DRM_FORMAT_XBGR8888:
2013         case DRM_FORMAT_ARGB8888:
2014         case DRM_FORMAT_ABGR8888:
2015                 if (is_ccs_modifier(modifier))
2016                         return true;
2017                 /* fall through */
2018         case DRM_FORMAT_RGB565:
2019         case DRM_FORMAT_XRGB2101010:
2020         case DRM_FORMAT_XBGR2101010:
2021         case DRM_FORMAT_YUYV:
2022         case DRM_FORMAT_YVYU:
2023         case DRM_FORMAT_UYVY:
2024         case DRM_FORMAT_VYUY:
2025         case DRM_FORMAT_NV12:
2026         case DRM_FORMAT_P010:
2027         case DRM_FORMAT_P012:
2028         case DRM_FORMAT_P016:
2029         case DRM_FORMAT_Y210:
2030         case DRM_FORMAT_Y212:
2031         case DRM_FORMAT_Y216:
2032         case DRM_FORMAT_Y410:
2033         case DRM_FORMAT_Y412:
2034         case DRM_FORMAT_Y416:
2035                 if (modifier == I915_FORMAT_MOD_Yf_TILED)
2036                         return true;
2037                 /* fall through */
2038         case DRM_FORMAT_C8:
2039                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
2040                     modifier == I915_FORMAT_MOD_X_TILED ||
2041                     modifier == I915_FORMAT_MOD_Y_TILED)
2042                         return true;
2043                 /* fall through */
2044         default:
2045                 return false;
2046         }
2047 }
2048
2049 static const struct drm_plane_funcs g4x_sprite_funcs = {
2050         .update_plane = drm_atomic_helper_update_plane,
2051         .disable_plane = drm_atomic_helper_disable_plane,
2052         .destroy = intel_plane_destroy,
2053         .atomic_get_property = intel_plane_atomic_get_property,
2054         .atomic_set_property = intel_plane_atomic_set_property,
2055         .atomic_duplicate_state = intel_plane_duplicate_state,
2056         .atomic_destroy_state = intel_plane_destroy_state,
2057         .format_mod_supported = g4x_sprite_format_mod_supported,
2058 };
2059
2060 static const struct drm_plane_funcs snb_sprite_funcs = {
2061         .update_plane = drm_atomic_helper_update_plane,
2062         .disable_plane = drm_atomic_helper_disable_plane,
2063         .destroy = intel_plane_destroy,
2064         .atomic_get_property = intel_plane_atomic_get_property,
2065         .atomic_set_property = intel_plane_atomic_set_property,
2066         .atomic_duplicate_state = intel_plane_duplicate_state,
2067         .atomic_destroy_state = intel_plane_destroy_state,
2068         .format_mod_supported = snb_sprite_format_mod_supported,
2069 };
2070
2071 static const struct drm_plane_funcs vlv_sprite_funcs = {
2072         .update_plane = drm_atomic_helper_update_plane,
2073         .disable_plane = drm_atomic_helper_disable_plane,
2074         .destroy = intel_plane_destroy,
2075         .atomic_get_property = intel_plane_atomic_get_property,
2076         .atomic_set_property = intel_plane_atomic_set_property,
2077         .atomic_duplicate_state = intel_plane_duplicate_state,
2078         .atomic_destroy_state = intel_plane_destroy_state,
2079         .format_mod_supported = vlv_sprite_format_mod_supported,
2080 };
2081
2082 static const struct drm_plane_funcs skl_plane_funcs = {
2083         .update_plane = drm_atomic_helper_update_plane,
2084         .disable_plane = drm_atomic_helper_disable_plane,
2085         .destroy = intel_plane_destroy,
2086         .atomic_get_property = intel_plane_atomic_get_property,
2087         .atomic_set_property = intel_plane_atomic_set_property,
2088         .atomic_duplicate_state = intel_plane_duplicate_state,
2089         .atomic_destroy_state = intel_plane_destroy_state,
2090         .format_mod_supported = skl_plane_format_mod_supported,
2091 };
2092
2093 static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
2094                               enum pipe pipe, enum plane_id plane_id)
2095 {
2096         if (!HAS_FBC(dev_priv))
2097                 return false;
2098
2099         return pipe == PIPE_A && plane_id == PLANE_PRIMARY;
2100 }
2101
2102 static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
2103                                  enum pipe pipe, enum plane_id plane_id)
2104 {
2105         if (INTEL_GEN(dev_priv) >= 11)
2106                 return plane_id <= PLANE_SPRITE3;
2107
2108         /* Display WA #0870: skl, bxt */
2109         if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
2110                 return false;
2111
2112         if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv) && pipe == PIPE_C)
2113                 return false;
2114
2115         if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0)
2116                 return false;
2117
2118         return true;
2119 }
2120
2121 static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
2122                               enum pipe pipe, enum plane_id plane_id)
2123 {
2124         if (plane_id == PLANE_CURSOR)
2125                 return false;
2126
2127         if (INTEL_GEN(dev_priv) >= 10)
2128                 return true;
2129
2130         if (IS_GEMINILAKE(dev_priv))
2131                 return pipe != PIPE_C;
2132
2133         return pipe != PIPE_C &&
2134                 (plane_id == PLANE_PRIMARY ||
2135                  plane_id == PLANE_SPRITE0);
2136 }
2137
2138 struct intel_plane *
2139 skl_universal_plane_create(struct drm_i915_private *dev_priv,
2140                            enum pipe pipe, enum plane_id plane_id)
2141 {
2142         struct intel_plane *plane;
2143         enum drm_plane_type plane_type;
2144         unsigned int supported_rotations;
2145         unsigned int possible_crtcs;
2146         const u64 *modifiers;
2147         const u32 *formats;
2148         int num_formats;
2149         int ret;
2150
2151         plane = intel_plane_alloc();
2152         if (IS_ERR(plane))
2153                 return plane;
2154
2155         plane->pipe = pipe;
2156         plane->id = plane_id;
2157         plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id);
2158
2159         plane->has_fbc = skl_plane_has_fbc(dev_priv, pipe, plane_id);
2160         if (plane->has_fbc) {
2161                 struct intel_fbc *fbc = &dev_priv->fbc;
2162
2163                 fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
2164         }
2165
2166         plane->max_stride = skl_plane_max_stride;
2167         plane->update_plane = skl_update_plane;
2168         plane->disable_plane = skl_disable_plane;
2169         plane->get_hw_state = skl_plane_get_hw_state;
2170         plane->check_plane = skl_plane_check;
2171         if (icl_is_nv12_y_plane(plane_id))
2172                 plane->update_slave = icl_update_slave;
2173
2174         if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
2175                 if (INTEL_GEN(dev_priv) >= 11) {
2176                         formats = icl_planar_formats;
2177                         num_formats = ARRAY_SIZE(icl_planar_formats);
2178                 } else if (INTEL_GEN(dev_priv) == 10 || IS_GEMINILAKE(dev_priv)) {
2179                         formats = glk_planar_formats;
2180                         num_formats = ARRAY_SIZE(glk_planar_formats);
2181                 } else {
2182                         formats = skl_planar_formats;
2183                         num_formats = ARRAY_SIZE(skl_planar_formats);
2184                 }
2185         } else if (INTEL_GEN(dev_priv) >= 11) {
2186                 formats = icl_plane_formats;
2187                 num_formats = ARRAY_SIZE(icl_plane_formats);
2188         } else {
2189                 formats = skl_plane_formats;
2190                 num_formats = ARRAY_SIZE(skl_plane_formats);
2191         }
2192
2193         plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id);
2194         if (plane->has_ccs)
2195                 modifiers = skl_plane_format_modifiers_ccs;
2196         else
2197                 modifiers = skl_plane_format_modifiers_noccs;
2198
2199         if (plane_id == PLANE_PRIMARY)
2200                 plane_type = DRM_PLANE_TYPE_PRIMARY;
2201         else
2202                 plane_type = DRM_PLANE_TYPE_OVERLAY;
2203
2204         possible_crtcs = BIT(pipe);
2205
2206         ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
2207                                        possible_crtcs, &skl_plane_funcs,
2208                                        formats, num_formats, modifiers,
2209                                        plane_type,
2210                                        "plane %d%c", plane_id + 1,
2211                                        pipe_name(pipe));
2212         if (ret)
2213                 goto fail;
2214
2215         supported_rotations =
2216                 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
2217                 DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
2218
2219         if (INTEL_GEN(dev_priv) >= 10)
2220                 supported_rotations |= DRM_MODE_REFLECT_X;
2221
2222         drm_plane_create_rotation_property(&plane->base,
2223                                            DRM_MODE_ROTATE_0,
2224                                            supported_rotations);
2225
2226         drm_plane_create_color_properties(&plane->base,
2227                                           BIT(DRM_COLOR_YCBCR_BT601) |
2228                                           BIT(DRM_COLOR_YCBCR_BT709),
2229                                           BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
2230                                           BIT(DRM_COLOR_YCBCR_FULL_RANGE),
2231                                           DRM_COLOR_YCBCR_BT709,
2232                                           DRM_COLOR_YCBCR_LIMITED_RANGE);
2233
2234         drm_plane_create_alpha_property(&plane->base);
2235         drm_plane_create_blend_mode_property(&plane->base,
2236                                              BIT(DRM_MODE_BLEND_PIXEL_NONE) |
2237                                              BIT(DRM_MODE_BLEND_PREMULTI) |
2238                                              BIT(DRM_MODE_BLEND_COVERAGE));
2239
2240         drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
2241
2242         return plane;
2243
2244 fail:
2245         intel_plane_free(plane);
2246
2247         return ERR_PTR(ret);
2248 }
2249
2250 struct intel_plane *
2251 intel_sprite_plane_create(struct drm_i915_private *dev_priv,
2252                           enum pipe pipe, int sprite)
2253 {
2254         struct intel_plane *plane;
2255         const struct drm_plane_funcs *plane_funcs;
2256         unsigned long possible_crtcs;
2257         unsigned int supported_rotations;
2258         const u64 *modifiers;
2259         const u32 *formats;
2260         int num_formats;
2261         int ret;
2262
2263         if (INTEL_GEN(dev_priv) >= 9)
2264                 return skl_universal_plane_create(dev_priv, pipe,
2265                                                   PLANE_SPRITE0 + sprite);
2266
2267         plane = intel_plane_alloc();
2268         if (IS_ERR(plane))
2269                 return plane;
2270
2271         if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
2272                 plane->max_stride = i9xx_plane_max_stride;
2273                 plane->update_plane = vlv_update_plane;
2274                 plane->disable_plane = vlv_disable_plane;
2275                 plane->get_hw_state = vlv_plane_get_hw_state;
2276                 plane->check_plane = vlv_sprite_check;
2277
2278                 formats = vlv_plane_formats;
2279                 num_formats = ARRAY_SIZE(vlv_plane_formats);
2280                 modifiers = i9xx_plane_format_modifiers;
2281
2282                 plane_funcs = &vlv_sprite_funcs;
2283         } else if (INTEL_GEN(dev_priv) >= 7) {
2284                 plane->max_stride = g4x_sprite_max_stride;
2285                 plane->update_plane = ivb_update_plane;
2286                 plane->disable_plane = ivb_disable_plane;
2287                 plane->get_hw_state = ivb_plane_get_hw_state;
2288                 plane->check_plane = g4x_sprite_check;
2289
2290                 formats = snb_plane_formats;
2291                 num_formats = ARRAY_SIZE(snb_plane_formats);
2292                 modifiers = i9xx_plane_format_modifiers;
2293
2294                 plane_funcs = &snb_sprite_funcs;
2295         } else {
2296                 plane->max_stride = g4x_sprite_max_stride;
2297                 plane->update_plane = g4x_update_plane;
2298                 plane->disable_plane = g4x_disable_plane;
2299                 plane->get_hw_state = g4x_plane_get_hw_state;
2300                 plane->check_plane = g4x_sprite_check;
2301
2302                 modifiers = i9xx_plane_format_modifiers;
2303                 if (IS_GEN(dev_priv, 6)) {
2304                         formats = snb_plane_formats;
2305                         num_formats = ARRAY_SIZE(snb_plane_formats);
2306
2307                         plane_funcs = &snb_sprite_funcs;
2308                 } else {
2309                         formats = g4x_plane_formats;
2310                         num_formats = ARRAY_SIZE(g4x_plane_formats);
2311
2312                         plane_funcs = &g4x_sprite_funcs;
2313                 }
2314         }
2315
2316         if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
2317                 supported_rotations =
2318                         DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
2319                         DRM_MODE_REFLECT_X;
2320         } else {
2321                 supported_rotations =
2322                         DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
2323         }
2324
2325         plane->pipe = pipe;
2326         plane->id = PLANE_SPRITE0 + sprite;
2327         plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
2328
2329         possible_crtcs = BIT(pipe);
2330
2331         ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
2332                                        possible_crtcs, plane_funcs,
2333                                        formats, num_formats, modifiers,
2334                                        DRM_PLANE_TYPE_OVERLAY,
2335                                        "sprite %c", sprite_name(pipe, sprite));
2336         if (ret)
2337                 goto fail;
2338
2339         drm_plane_create_rotation_property(&plane->base,
2340                                            DRM_MODE_ROTATE_0,
2341                                            supported_rotations);
2342
2343         drm_plane_create_color_properties(&plane->base,
2344                                           BIT(DRM_COLOR_YCBCR_BT601) |
2345                                           BIT(DRM_COLOR_YCBCR_BT709),
2346                                           BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
2347                                           BIT(DRM_COLOR_YCBCR_FULL_RANGE),
2348                                           DRM_COLOR_YCBCR_BT709,
2349                                           DRM_COLOR_YCBCR_LIMITED_RANGE);
2350
2351         drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
2352
2353         return plane;
2354
2355 fail:
2356         intel_plane_free(plane);
2357
2358         return ERR_PTR(ret);
2359 }