Merge tag 'drm-misc-next-2019-03-21' of git://anongit.freedesktop.org/drm/drm-misc...
[linux-2.6-block.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(dev_priv, plane->id)) {
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(dev_priv, plane_id)) {
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(dev_priv, plane_id))
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                  */
1499                 switch (fb->format->format) {
1500                 case DRM_FORMAT_RGB565:
1501                         if (INTEL_GEN(dev_priv) >= 11)
1502                                 break;
1503                         /* fall through */
1504                 case DRM_FORMAT_C8:
1505                 case DRM_FORMAT_XRGB16161616F:
1506                 case DRM_FORMAT_XBGR16161616F:
1507                 case DRM_FORMAT_ARGB16161616F:
1508                 case DRM_FORMAT_ABGR16161616F:
1509                         DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n",
1510                                       drm_get_format_name(fb->format->format,
1511                                                           &format_name));
1512                         return -EINVAL;
1513                 default:
1514                         break;
1515                 }
1516         }
1517
1518         /* Y-tiling is not supported in IF-ID Interlace mode */
1519         if (crtc_state->base.enable &&
1520             crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
1521             (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
1522              fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
1523              fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
1524              fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS)) {
1525                 DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n");
1526                 return -EINVAL;
1527         }
1528
1529         return 0;
1530 }
1531
1532 static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state,
1533                                            const struct intel_plane_state *plane_state)
1534 {
1535         struct drm_i915_private *dev_priv =
1536                 to_i915(plane_state->base.plane->dev);
1537         int crtc_x = plane_state->base.dst.x1;
1538         int crtc_w = drm_rect_width(&plane_state->base.dst);
1539         int pipe_src_w = crtc_state->pipe_src_w;
1540
1541         /*
1542          * Display WA #1175: cnl,glk
1543          * Planes other than the cursor may cause FIFO underflow and display
1544          * corruption if starting less than 4 pixels from the right edge of
1545          * the screen.
1546          * Besides the above WA fix the similar problem, where planes other
1547          * than the cursor ending less than 4 pixels from the left edge of the
1548          * screen may cause FIFO underflow and display corruption.
1549          */
1550         if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
1551             (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
1552                 DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n",
1553                               crtc_x + crtc_w < 4 ? "end" : "start",
1554                               crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x,
1555                               4, pipe_src_w - 4);
1556                 return -ERANGE;
1557         }
1558
1559         return 0;
1560 }
1561
1562 static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
1563 {
1564         const struct drm_framebuffer *fb = plane_state->base.fb;
1565         unsigned int rotation = plane_state->base.rotation;
1566         int src_w = drm_rect_width(&plane_state->base.src) >> 16;
1567
1568         /* Display WA #1106 */
1569         if (is_planar_yuv_format(fb->format->format) && src_w & 3 &&
1570             (rotation == DRM_MODE_ROTATE_270 ||
1571              rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
1572                 DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n");
1573                 return -EINVAL;
1574         }
1575
1576         return 0;
1577 }
1578
1579 static int skl_plane_check(struct intel_crtc_state *crtc_state,
1580                            struct intel_plane_state *plane_state)
1581 {
1582         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1583         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1584         const struct drm_framebuffer *fb = plane_state->base.fb;
1585         int min_scale = DRM_PLANE_HELPER_NO_SCALING;
1586         int max_scale = DRM_PLANE_HELPER_NO_SCALING;
1587         int ret;
1588
1589         ret = skl_plane_check_fb(crtc_state, plane_state);
1590         if (ret)
1591                 return ret;
1592
1593         /* use scaler when colorkey is not required */
1594         if (!plane_state->ckey.flags && intel_fb_scalable(fb)) {
1595                 min_scale = 1;
1596                 max_scale = skl_max_scale(crtc_state, fb->format->format);
1597         }
1598
1599         ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1600                                                   &crtc_state->base,
1601                                                   min_scale, max_scale,
1602                                                   true, true);
1603         if (ret)
1604                 return ret;
1605
1606         if (!plane_state->base.visible)
1607                 return 0;
1608
1609         ret = skl_plane_check_dst_coordinates(crtc_state, plane_state);
1610         if (ret)
1611                 return ret;
1612
1613         ret = intel_plane_check_src_coordinates(plane_state);
1614         if (ret)
1615                 return ret;
1616
1617         ret = skl_plane_check_nv12_rotation(plane_state);
1618         if (ret)
1619                 return ret;
1620
1621         ret = skl_check_plane_surface(plane_state);
1622         if (ret)
1623                 return ret;
1624
1625         /* HW only has 8 bits pixel precision, disable plane if invisible */
1626         if (!(plane_state->base.alpha >> 8))
1627                 plane_state->base.visible = false;
1628
1629         plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
1630
1631         if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
1632                 plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
1633                                                              plane_state);
1634
1635         return 0;
1636 }
1637
1638 static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv)
1639 {
1640         return INTEL_GEN(dev_priv) >= 9;
1641 }
1642
1643 static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
1644                                  const struct drm_intel_sprite_colorkey *set)
1645 {
1646         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1647         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1648         struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1649
1650         *key = *set;
1651
1652         /*
1653          * We want src key enabled on the
1654          * sprite and not on the primary.
1655          */
1656         if (plane->id == PLANE_PRIMARY &&
1657             set->flags & I915_SET_COLORKEY_SOURCE)
1658                 key->flags = 0;
1659
1660         /*
1661          * On SKL+ we want dst key enabled on
1662          * the primary and not on the sprite.
1663          */
1664         if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_PRIMARY &&
1665             set->flags & I915_SET_COLORKEY_DESTINATION)
1666                 key->flags = 0;
1667 }
1668
1669 int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
1670                                     struct drm_file *file_priv)
1671 {
1672         struct drm_i915_private *dev_priv = to_i915(dev);
1673         struct drm_intel_sprite_colorkey *set = data;
1674         struct drm_plane *plane;
1675         struct drm_plane_state *plane_state;
1676         struct drm_atomic_state *state;
1677         struct drm_modeset_acquire_ctx ctx;
1678         int ret = 0;
1679
1680         /* ignore the pointless "none" flag */
1681         set->flags &= ~I915_SET_COLORKEY_NONE;
1682
1683         if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
1684                 return -EINVAL;
1685
1686         /* Make sure we don't try to enable both src & dest simultaneously */
1687         if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
1688                 return -EINVAL;
1689
1690         if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
1691             set->flags & I915_SET_COLORKEY_DESTINATION)
1692                 return -EINVAL;
1693
1694         plane = drm_plane_find(dev, file_priv, set->plane_id);
1695         if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
1696                 return -ENOENT;
1697
1698         /*
1699          * SKL+ only plane 2 can do destination keying against plane 1.
1700          * Also multiple planes can't do destination keying on the same
1701          * pipe simultaneously.
1702          */
1703         if (INTEL_GEN(dev_priv) >= 9 &&
1704             to_intel_plane(plane)->id >= PLANE_SPRITE1 &&
1705             set->flags & I915_SET_COLORKEY_DESTINATION)
1706                 return -EINVAL;
1707
1708         drm_modeset_acquire_init(&ctx, 0);
1709
1710         state = drm_atomic_state_alloc(plane->dev);
1711         if (!state) {
1712                 ret = -ENOMEM;
1713                 goto out;
1714         }
1715         state->acquire_ctx = &ctx;
1716
1717         while (1) {
1718                 plane_state = drm_atomic_get_plane_state(state, plane);
1719                 ret = PTR_ERR_OR_ZERO(plane_state);
1720                 if (!ret)
1721                         intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
1722
1723                 /*
1724                  * On some platforms we have to configure
1725                  * the dst colorkey on the primary plane.
1726                  */
1727                 if (!ret && has_dst_key_in_primary_plane(dev_priv)) {
1728                         struct intel_crtc *crtc =
1729                                 intel_get_crtc_for_pipe(dev_priv,
1730                                                         to_intel_plane(plane)->pipe);
1731
1732                         plane_state = drm_atomic_get_plane_state(state,
1733                                                                  crtc->base.primary);
1734                         ret = PTR_ERR_OR_ZERO(plane_state);
1735                         if (!ret)
1736                                 intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
1737                 }
1738
1739                 if (!ret)
1740                         ret = drm_atomic_commit(state);
1741
1742                 if (ret != -EDEADLK)
1743                         break;
1744
1745                 drm_atomic_state_clear(state);
1746                 drm_modeset_backoff(&ctx);
1747         }
1748
1749         drm_atomic_state_put(state);
1750 out:
1751         drm_modeset_drop_locks(&ctx);
1752         drm_modeset_acquire_fini(&ctx);
1753         return ret;
1754 }
1755
1756 static const u32 g4x_plane_formats[] = {
1757         DRM_FORMAT_XRGB8888,
1758         DRM_FORMAT_YUYV,
1759         DRM_FORMAT_YVYU,
1760         DRM_FORMAT_UYVY,
1761         DRM_FORMAT_VYUY,
1762 };
1763
1764 static const u64 i9xx_plane_format_modifiers[] = {
1765         I915_FORMAT_MOD_X_TILED,
1766         DRM_FORMAT_MOD_LINEAR,
1767         DRM_FORMAT_MOD_INVALID
1768 };
1769
1770 static const u32 snb_plane_formats[] = {
1771         DRM_FORMAT_XBGR8888,
1772         DRM_FORMAT_XRGB8888,
1773         DRM_FORMAT_YUYV,
1774         DRM_FORMAT_YVYU,
1775         DRM_FORMAT_UYVY,
1776         DRM_FORMAT_VYUY,
1777 };
1778
1779 static const u32 vlv_plane_formats[] = {
1780         DRM_FORMAT_RGB565,
1781         DRM_FORMAT_ABGR8888,
1782         DRM_FORMAT_ARGB8888,
1783         DRM_FORMAT_XBGR8888,
1784         DRM_FORMAT_XRGB8888,
1785         DRM_FORMAT_XBGR2101010,
1786         DRM_FORMAT_ABGR2101010,
1787         DRM_FORMAT_YUYV,
1788         DRM_FORMAT_YVYU,
1789         DRM_FORMAT_UYVY,
1790         DRM_FORMAT_VYUY,
1791 };
1792
1793 static const u32 skl_plane_formats[] = {
1794         DRM_FORMAT_C8,
1795         DRM_FORMAT_RGB565,
1796         DRM_FORMAT_XRGB8888,
1797         DRM_FORMAT_XBGR8888,
1798         DRM_FORMAT_ARGB8888,
1799         DRM_FORMAT_ABGR8888,
1800         DRM_FORMAT_XRGB2101010,
1801         DRM_FORMAT_XBGR2101010,
1802         DRM_FORMAT_YUYV,
1803         DRM_FORMAT_YVYU,
1804         DRM_FORMAT_UYVY,
1805         DRM_FORMAT_VYUY,
1806 };
1807
1808 static const uint32_t icl_plane_formats[] = {
1809         DRM_FORMAT_C8,
1810         DRM_FORMAT_RGB565,
1811         DRM_FORMAT_XRGB8888,
1812         DRM_FORMAT_XBGR8888,
1813         DRM_FORMAT_ARGB8888,
1814         DRM_FORMAT_ABGR8888,
1815         DRM_FORMAT_XRGB2101010,
1816         DRM_FORMAT_XBGR2101010,
1817         DRM_FORMAT_YUYV,
1818         DRM_FORMAT_YVYU,
1819         DRM_FORMAT_UYVY,
1820         DRM_FORMAT_VYUY,
1821         DRM_FORMAT_Y210,
1822         DRM_FORMAT_Y212,
1823         DRM_FORMAT_Y216,
1824         DRM_FORMAT_XVYU2101010,
1825         DRM_FORMAT_XVYU12_16161616,
1826         DRM_FORMAT_XVYU16161616,
1827 };
1828
1829 static const uint32_t icl_hdr_plane_formats[] = {
1830         DRM_FORMAT_C8,
1831         DRM_FORMAT_RGB565,
1832         DRM_FORMAT_XRGB8888,
1833         DRM_FORMAT_XBGR8888,
1834         DRM_FORMAT_ARGB8888,
1835         DRM_FORMAT_ABGR8888,
1836         DRM_FORMAT_XRGB2101010,
1837         DRM_FORMAT_XBGR2101010,
1838         DRM_FORMAT_XRGB16161616F,
1839         DRM_FORMAT_XBGR16161616F,
1840         DRM_FORMAT_ARGB16161616F,
1841         DRM_FORMAT_ABGR16161616F,
1842         DRM_FORMAT_YUYV,
1843         DRM_FORMAT_YVYU,
1844         DRM_FORMAT_UYVY,
1845         DRM_FORMAT_VYUY,
1846         DRM_FORMAT_Y210,
1847         DRM_FORMAT_Y212,
1848         DRM_FORMAT_Y216,
1849         DRM_FORMAT_XVYU2101010,
1850         DRM_FORMAT_XVYU12_16161616,
1851         DRM_FORMAT_XVYU16161616,
1852 };
1853
1854 static const u32 skl_planar_formats[] = {
1855         DRM_FORMAT_C8,
1856         DRM_FORMAT_RGB565,
1857         DRM_FORMAT_XRGB8888,
1858         DRM_FORMAT_XBGR8888,
1859         DRM_FORMAT_ARGB8888,
1860         DRM_FORMAT_ABGR8888,
1861         DRM_FORMAT_XRGB2101010,
1862         DRM_FORMAT_XBGR2101010,
1863         DRM_FORMAT_YUYV,
1864         DRM_FORMAT_YVYU,
1865         DRM_FORMAT_UYVY,
1866         DRM_FORMAT_VYUY,
1867         DRM_FORMAT_NV12,
1868 };
1869
1870 static const uint32_t glk_planar_formats[] = {
1871         DRM_FORMAT_C8,
1872         DRM_FORMAT_RGB565,
1873         DRM_FORMAT_XRGB8888,
1874         DRM_FORMAT_XBGR8888,
1875         DRM_FORMAT_ARGB8888,
1876         DRM_FORMAT_ABGR8888,
1877         DRM_FORMAT_XRGB2101010,
1878         DRM_FORMAT_XBGR2101010,
1879         DRM_FORMAT_YUYV,
1880         DRM_FORMAT_YVYU,
1881         DRM_FORMAT_UYVY,
1882         DRM_FORMAT_VYUY,
1883         DRM_FORMAT_NV12,
1884         DRM_FORMAT_P010,
1885         DRM_FORMAT_P012,
1886         DRM_FORMAT_P016,
1887 };
1888
1889 static const uint32_t icl_planar_formats[] = {
1890         DRM_FORMAT_C8,
1891         DRM_FORMAT_RGB565,
1892         DRM_FORMAT_XRGB8888,
1893         DRM_FORMAT_XBGR8888,
1894         DRM_FORMAT_ARGB8888,
1895         DRM_FORMAT_ABGR8888,
1896         DRM_FORMAT_XRGB2101010,
1897         DRM_FORMAT_XBGR2101010,
1898         DRM_FORMAT_YUYV,
1899         DRM_FORMAT_YVYU,
1900         DRM_FORMAT_UYVY,
1901         DRM_FORMAT_VYUY,
1902         DRM_FORMAT_NV12,
1903         DRM_FORMAT_P010,
1904         DRM_FORMAT_P012,
1905         DRM_FORMAT_P016,
1906         DRM_FORMAT_Y210,
1907         DRM_FORMAT_Y212,
1908         DRM_FORMAT_Y216,
1909         DRM_FORMAT_XVYU2101010,
1910         DRM_FORMAT_XVYU12_16161616,
1911         DRM_FORMAT_XVYU16161616,
1912 };
1913
1914 static const uint32_t icl_hdr_planar_formats[] = {
1915         DRM_FORMAT_C8,
1916         DRM_FORMAT_RGB565,
1917         DRM_FORMAT_XRGB8888,
1918         DRM_FORMAT_XBGR8888,
1919         DRM_FORMAT_ARGB8888,
1920         DRM_FORMAT_ABGR8888,
1921         DRM_FORMAT_XRGB2101010,
1922         DRM_FORMAT_XBGR2101010,
1923         DRM_FORMAT_XRGB16161616F,
1924         DRM_FORMAT_XBGR16161616F,
1925         DRM_FORMAT_ARGB16161616F,
1926         DRM_FORMAT_ABGR16161616F,
1927         DRM_FORMAT_YUYV,
1928         DRM_FORMAT_YVYU,
1929         DRM_FORMAT_UYVY,
1930         DRM_FORMAT_VYUY,
1931         DRM_FORMAT_NV12,
1932         DRM_FORMAT_P010,
1933         DRM_FORMAT_P012,
1934         DRM_FORMAT_P016,
1935         DRM_FORMAT_Y210,
1936         DRM_FORMAT_Y212,
1937         DRM_FORMAT_Y216,
1938         DRM_FORMAT_XVYU2101010,
1939         DRM_FORMAT_XVYU12_16161616,
1940         DRM_FORMAT_XVYU16161616,
1941 };
1942
1943 static const u64 skl_plane_format_modifiers_noccs[] = {
1944         I915_FORMAT_MOD_Yf_TILED,
1945         I915_FORMAT_MOD_Y_TILED,
1946         I915_FORMAT_MOD_X_TILED,
1947         DRM_FORMAT_MOD_LINEAR,
1948         DRM_FORMAT_MOD_INVALID
1949 };
1950
1951 static const u64 skl_plane_format_modifiers_ccs[] = {
1952         I915_FORMAT_MOD_Yf_TILED_CCS,
1953         I915_FORMAT_MOD_Y_TILED_CCS,
1954         I915_FORMAT_MOD_Yf_TILED,
1955         I915_FORMAT_MOD_Y_TILED,
1956         I915_FORMAT_MOD_X_TILED,
1957         DRM_FORMAT_MOD_LINEAR,
1958         DRM_FORMAT_MOD_INVALID
1959 };
1960
1961 static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane,
1962                                             u32 format, u64 modifier)
1963 {
1964         switch (modifier) {
1965         case DRM_FORMAT_MOD_LINEAR:
1966         case I915_FORMAT_MOD_X_TILED:
1967                 break;
1968         default:
1969                 return false;
1970         }
1971
1972         switch (format) {
1973         case DRM_FORMAT_XRGB8888:
1974         case DRM_FORMAT_YUYV:
1975         case DRM_FORMAT_YVYU:
1976         case DRM_FORMAT_UYVY:
1977         case DRM_FORMAT_VYUY:
1978                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
1979                     modifier == I915_FORMAT_MOD_X_TILED)
1980                         return true;
1981                 /* fall through */
1982         default:
1983                 return false;
1984         }
1985 }
1986
1987 static bool snb_sprite_format_mod_supported(struct drm_plane *_plane,
1988                                             u32 format, u64 modifier)
1989 {
1990         switch (modifier) {
1991         case DRM_FORMAT_MOD_LINEAR:
1992         case I915_FORMAT_MOD_X_TILED:
1993                 break;
1994         default:
1995                 return false;
1996         }
1997
1998         switch (format) {
1999         case DRM_FORMAT_XRGB8888:
2000         case DRM_FORMAT_XBGR8888:
2001         case DRM_FORMAT_YUYV:
2002         case DRM_FORMAT_YVYU:
2003         case DRM_FORMAT_UYVY:
2004         case DRM_FORMAT_VYUY:
2005                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
2006                     modifier == I915_FORMAT_MOD_X_TILED)
2007                         return true;
2008                 /* fall through */
2009         default:
2010                 return false;
2011         }
2012 }
2013
2014 static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane,
2015                                             u32 format, u64 modifier)
2016 {
2017         switch (modifier) {
2018         case DRM_FORMAT_MOD_LINEAR:
2019         case I915_FORMAT_MOD_X_TILED:
2020                 break;
2021         default:
2022                 return false;
2023         }
2024
2025         switch (format) {
2026         case DRM_FORMAT_RGB565:
2027         case DRM_FORMAT_ABGR8888:
2028         case DRM_FORMAT_ARGB8888:
2029         case DRM_FORMAT_XBGR8888:
2030         case DRM_FORMAT_XRGB8888:
2031         case DRM_FORMAT_XBGR2101010:
2032         case DRM_FORMAT_ABGR2101010:
2033         case DRM_FORMAT_YUYV:
2034         case DRM_FORMAT_YVYU:
2035         case DRM_FORMAT_UYVY:
2036         case DRM_FORMAT_VYUY:
2037                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
2038                     modifier == I915_FORMAT_MOD_X_TILED)
2039                         return true;
2040                 /* fall through */
2041         default:
2042                 return false;
2043         }
2044 }
2045
2046 static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
2047                                            u32 format, u64 modifier)
2048 {
2049         struct intel_plane *plane = to_intel_plane(_plane);
2050
2051         switch (modifier) {
2052         case DRM_FORMAT_MOD_LINEAR:
2053         case I915_FORMAT_MOD_X_TILED:
2054         case I915_FORMAT_MOD_Y_TILED:
2055         case I915_FORMAT_MOD_Yf_TILED:
2056                 break;
2057         case I915_FORMAT_MOD_Y_TILED_CCS:
2058         case I915_FORMAT_MOD_Yf_TILED_CCS:
2059                 if (!plane->has_ccs)
2060                         return false;
2061                 break;
2062         default:
2063                 return false;
2064         }
2065
2066         switch (format) {
2067         case DRM_FORMAT_XRGB8888:
2068         case DRM_FORMAT_XBGR8888:
2069         case DRM_FORMAT_ARGB8888:
2070         case DRM_FORMAT_ABGR8888:
2071                 if (is_ccs_modifier(modifier))
2072                         return true;
2073                 /* fall through */
2074         case DRM_FORMAT_RGB565:
2075         case DRM_FORMAT_XRGB2101010:
2076         case DRM_FORMAT_XBGR2101010:
2077         case DRM_FORMAT_YUYV:
2078         case DRM_FORMAT_YVYU:
2079         case DRM_FORMAT_UYVY:
2080         case DRM_FORMAT_VYUY:
2081         case DRM_FORMAT_NV12:
2082         case DRM_FORMAT_P010:
2083         case DRM_FORMAT_P012:
2084         case DRM_FORMAT_P016:
2085         case DRM_FORMAT_Y210:
2086         case DRM_FORMAT_Y212:
2087         case DRM_FORMAT_Y216:
2088         case DRM_FORMAT_XVYU2101010:
2089         case DRM_FORMAT_XVYU12_16161616:
2090         case DRM_FORMAT_XVYU16161616:
2091                 if (modifier == I915_FORMAT_MOD_Yf_TILED)
2092                         return true;
2093                 /* fall through */
2094         case DRM_FORMAT_C8:
2095         case DRM_FORMAT_XBGR16161616F:
2096         case DRM_FORMAT_ABGR16161616F:
2097         case DRM_FORMAT_XRGB16161616F:
2098         case DRM_FORMAT_ARGB16161616F:
2099                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
2100                     modifier == I915_FORMAT_MOD_X_TILED ||
2101                     modifier == I915_FORMAT_MOD_Y_TILED)
2102                         return true;
2103                 /* fall through */
2104         default:
2105                 return false;
2106         }
2107 }
2108
2109 static const struct drm_plane_funcs g4x_sprite_funcs = {
2110         .update_plane = drm_atomic_helper_update_plane,
2111         .disable_plane = drm_atomic_helper_disable_plane,
2112         .destroy = intel_plane_destroy,
2113         .atomic_get_property = intel_plane_atomic_get_property,
2114         .atomic_set_property = intel_plane_atomic_set_property,
2115         .atomic_duplicate_state = intel_plane_duplicate_state,
2116         .atomic_destroy_state = intel_plane_destroy_state,
2117         .format_mod_supported = g4x_sprite_format_mod_supported,
2118 };
2119
2120 static const struct drm_plane_funcs snb_sprite_funcs = {
2121         .update_plane = drm_atomic_helper_update_plane,
2122         .disable_plane = drm_atomic_helper_disable_plane,
2123         .destroy = intel_plane_destroy,
2124         .atomic_get_property = intel_plane_atomic_get_property,
2125         .atomic_set_property = intel_plane_atomic_set_property,
2126         .atomic_duplicate_state = intel_plane_duplicate_state,
2127         .atomic_destroy_state = intel_plane_destroy_state,
2128         .format_mod_supported = snb_sprite_format_mod_supported,
2129 };
2130
2131 static const struct drm_plane_funcs vlv_sprite_funcs = {
2132         .update_plane = drm_atomic_helper_update_plane,
2133         .disable_plane = drm_atomic_helper_disable_plane,
2134         .destroy = intel_plane_destroy,
2135         .atomic_get_property = intel_plane_atomic_get_property,
2136         .atomic_set_property = intel_plane_atomic_set_property,
2137         .atomic_duplicate_state = intel_plane_duplicate_state,
2138         .atomic_destroy_state = intel_plane_destroy_state,
2139         .format_mod_supported = vlv_sprite_format_mod_supported,
2140 };
2141
2142 static const struct drm_plane_funcs skl_plane_funcs = {
2143         .update_plane = drm_atomic_helper_update_plane,
2144         .disable_plane = drm_atomic_helper_disable_plane,
2145         .destroy = intel_plane_destroy,
2146         .atomic_get_property = intel_plane_atomic_get_property,
2147         .atomic_set_property = intel_plane_atomic_set_property,
2148         .atomic_duplicate_state = intel_plane_duplicate_state,
2149         .atomic_destroy_state = intel_plane_destroy_state,
2150         .format_mod_supported = skl_plane_format_mod_supported,
2151 };
2152
2153 static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
2154                               enum pipe pipe, enum plane_id plane_id)
2155 {
2156         if (!HAS_FBC(dev_priv))
2157                 return false;
2158
2159         return pipe == PIPE_A && plane_id == PLANE_PRIMARY;
2160 }
2161
2162 static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
2163                                  enum pipe pipe, enum plane_id plane_id)
2164 {
2165         if (INTEL_GEN(dev_priv) >= 11)
2166                 return plane_id <= PLANE_SPRITE3;
2167
2168         /* Display WA #0870: skl, bxt */
2169         if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
2170                 return false;
2171
2172         if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv) && pipe == PIPE_C)
2173                 return false;
2174
2175         if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0)
2176                 return false;
2177
2178         return true;
2179 }
2180
2181 static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
2182                               enum pipe pipe, enum plane_id plane_id)
2183 {
2184         if (plane_id == PLANE_CURSOR)
2185                 return false;
2186
2187         if (INTEL_GEN(dev_priv) >= 10)
2188                 return true;
2189
2190         if (IS_GEMINILAKE(dev_priv))
2191                 return pipe != PIPE_C;
2192
2193         return pipe != PIPE_C &&
2194                 (plane_id == PLANE_PRIMARY ||
2195                  plane_id == PLANE_SPRITE0);
2196 }
2197
2198 struct intel_plane *
2199 skl_universal_plane_create(struct drm_i915_private *dev_priv,
2200                            enum pipe pipe, enum plane_id plane_id)
2201 {
2202         struct intel_plane *plane;
2203         enum drm_plane_type plane_type;
2204         unsigned int supported_rotations;
2205         unsigned int possible_crtcs;
2206         const u64 *modifiers;
2207         const u32 *formats;
2208         int num_formats;
2209         int ret;
2210
2211         plane = intel_plane_alloc();
2212         if (IS_ERR(plane))
2213                 return plane;
2214
2215         plane->pipe = pipe;
2216         plane->id = plane_id;
2217         plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id);
2218
2219         plane->has_fbc = skl_plane_has_fbc(dev_priv, pipe, plane_id);
2220         if (plane->has_fbc) {
2221                 struct intel_fbc *fbc = &dev_priv->fbc;
2222
2223                 fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
2224         }
2225
2226         plane->max_stride = skl_plane_max_stride;
2227         plane->update_plane = skl_update_plane;
2228         plane->disable_plane = skl_disable_plane;
2229         plane->get_hw_state = skl_plane_get_hw_state;
2230         plane->check_plane = skl_plane_check;
2231         if (icl_is_nv12_y_plane(plane_id))
2232                 plane->update_slave = icl_update_slave;
2233
2234         if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
2235                 if (icl_is_hdr_plane(dev_priv, plane_id)) {
2236                         formats = icl_hdr_planar_formats;
2237                         num_formats = ARRAY_SIZE(icl_hdr_planar_formats);
2238                 } else if (INTEL_GEN(dev_priv) >= 11) {
2239                         formats = icl_planar_formats;
2240                         num_formats = ARRAY_SIZE(icl_planar_formats);
2241                 } else if (INTEL_GEN(dev_priv) == 10 || IS_GEMINILAKE(dev_priv)) {
2242                         formats = glk_planar_formats;
2243                         num_formats = ARRAY_SIZE(glk_planar_formats);
2244                 } else {
2245                         formats = skl_planar_formats;
2246                         num_formats = ARRAY_SIZE(skl_planar_formats);
2247                 }
2248         } else if (icl_is_hdr_plane(dev_priv, plane_id)) {
2249                 formats = icl_hdr_plane_formats;
2250                 num_formats = ARRAY_SIZE(icl_hdr_plane_formats);
2251         } else if (INTEL_GEN(dev_priv) >= 11) {
2252                 formats = icl_plane_formats;
2253                 num_formats = ARRAY_SIZE(icl_plane_formats);
2254         } else {
2255                 formats = skl_plane_formats;
2256                 num_formats = ARRAY_SIZE(skl_plane_formats);
2257         }
2258
2259         plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id);
2260         if (plane->has_ccs)
2261                 modifiers = skl_plane_format_modifiers_ccs;
2262         else
2263                 modifiers = skl_plane_format_modifiers_noccs;
2264
2265         if (plane_id == PLANE_PRIMARY)
2266                 plane_type = DRM_PLANE_TYPE_PRIMARY;
2267         else
2268                 plane_type = DRM_PLANE_TYPE_OVERLAY;
2269
2270         possible_crtcs = BIT(pipe);
2271
2272         ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
2273                                        possible_crtcs, &skl_plane_funcs,
2274                                        formats, num_formats, modifiers,
2275                                        plane_type,
2276                                        "plane %d%c", plane_id + 1,
2277                                        pipe_name(pipe));
2278         if (ret)
2279                 goto fail;
2280
2281         supported_rotations =
2282                 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
2283                 DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
2284
2285         if (INTEL_GEN(dev_priv) >= 10)
2286                 supported_rotations |= DRM_MODE_REFLECT_X;
2287
2288         drm_plane_create_rotation_property(&plane->base,
2289                                            DRM_MODE_ROTATE_0,
2290                                            supported_rotations);
2291
2292         drm_plane_create_color_properties(&plane->base,
2293                                           BIT(DRM_COLOR_YCBCR_BT601) |
2294                                           BIT(DRM_COLOR_YCBCR_BT709),
2295                                           BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
2296                                           BIT(DRM_COLOR_YCBCR_FULL_RANGE),
2297                                           DRM_COLOR_YCBCR_BT709,
2298                                           DRM_COLOR_YCBCR_LIMITED_RANGE);
2299
2300         drm_plane_create_alpha_property(&plane->base);
2301         drm_plane_create_blend_mode_property(&plane->base,
2302                                              BIT(DRM_MODE_BLEND_PIXEL_NONE) |
2303                                              BIT(DRM_MODE_BLEND_PREMULTI) |
2304                                              BIT(DRM_MODE_BLEND_COVERAGE));
2305
2306         drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
2307
2308         return plane;
2309
2310 fail:
2311         intel_plane_free(plane);
2312
2313         return ERR_PTR(ret);
2314 }
2315
2316 struct intel_plane *
2317 intel_sprite_plane_create(struct drm_i915_private *dev_priv,
2318                           enum pipe pipe, int sprite)
2319 {
2320         struct intel_plane *plane;
2321         const struct drm_plane_funcs *plane_funcs;
2322         unsigned long possible_crtcs;
2323         unsigned int supported_rotations;
2324         const u64 *modifiers;
2325         const u32 *formats;
2326         int num_formats;
2327         int ret;
2328
2329         if (INTEL_GEN(dev_priv) >= 9)
2330                 return skl_universal_plane_create(dev_priv, pipe,
2331                                                   PLANE_SPRITE0 + sprite);
2332
2333         plane = intel_plane_alloc();
2334         if (IS_ERR(plane))
2335                 return plane;
2336
2337         if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
2338                 plane->max_stride = i9xx_plane_max_stride;
2339                 plane->update_plane = vlv_update_plane;
2340                 plane->disable_plane = vlv_disable_plane;
2341                 plane->get_hw_state = vlv_plane_get_hw_state;
2342                 plane->check_plane = vlv_sprite_check;
2343
2344                 formats = vlv_plane_formats;
2345                 num_formats = ARRAY_SIZE(vlv_plane_formats);
2346                 modifiers = i9xx_plane_format_modifiers;
2347
2348                 plane_funcs = &vlv_sprite_funcs;
2349         } else if (INTEL_GEN(dev_priv) >= 7) {
2350                 plane->max_stride = g4x_sprite_max_stride;
2351                 plane->update_plane = ivb_update_plane;
2352                 plane->disable_plane = ivb_disable_plane;
2353                 plane->get_hw_state = ivb_plane_get_hw_state;
2354                 plane->check_plane = g4x_sprite_check;
2355
2356                 formats = snb_plane_formats;
2357                 num_formats = ARRAY_SIZE(snb_plane_formats);
2358                 modifiers = i9xx_plane_format_modifiers;
2359
2360                 plane_funcs = &snb_sprite_funcs;
2361         } else {
2362                 plane->max_stride = g4x_sprite_max_stride;
2363                 plane->update_plane = g4x_update_plane;
2364                 plane->disable_plane = g4x_disable_plane;
2365                 plane->get_hw_state = g4x_plane_get_hw_state;
2366                 plane->check_plane = g4x_sprite_check;
2367
2368                 modifiers = i9xx_plane_format_modifiers;
2369                 if (IS_GEN(dev_priv, 6)) {
2370                         formats = snb_plane_formats;
2371                         num_formats = ARRAY_SIZE(snb_plane_formats);
2372
2373                         plane_funcs = &snb_sprite_funcs;
2374                 } else {
2375                         formats = g4x_plane_formats;
2376                         num_formats = ARRAY_SIZE(g4x_plane_formats);
2377
2378                         plane_funcs = &g4x_sprite_funcs;
2379                 }
2380         }
2381
2382         if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
2383                 supported_rotations =
2384                         DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
2385                         DRM_MODE_REFLECT_X;
2386         } else {
2387                 supported_rotations =
2388                         DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
2389         }
2390
2391         plane->pipe = pipe;
2392         plane->id = PLANE_SPRITE0 + sprite;
2393         plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
2394
2395         possible_crtcs = BIT(pipe);
2396
2397         ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
2398                                        possible_crtcs, plane_funcs,
2399                                        formats, num_formats, modifiers,
2400                                        DRM_PLANE_TYPE_OVERLAY,
2401                                        "sprite %c", sprite_name(pipe, sprite));
2402         if (ret)
2403                 goto fail;
2404
2405         drm_plane_create_rotation_property(&plane->base,
2406                                            DRM_MODE_ROTATE_0,
2407                                            supported_rotations);
2408
2409         drm_plane_create_color_properties(&plane->base,
2410                                           BIT(DRM_COLOR_YCBCR_BT601) |
2411                                           BIT(DRM_COLOR_YCBCR_BT709),
2412                                           BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
2413                                           BIT(DRM_COLOR_YCBCR_FULL_RANGE),
2414                                           DRM_COLOR_YCBCR_BT709,
2415                                           DRM_COLOR_YCBCR_LIMITED_RANGE);
2416
2417         drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
2418
2419         return plane;
2420
2421 fail:
2422         intel_plane_free(plane);
2423
2424         return ERR_PTR(ret);
2425 }