268fb34ff0e21982c2f61b322351c48556580ec7
[sfrench/cifs-2.6.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         if (icl_is_hdr_plane(dev_priv, plane_id))
626                 I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), 0);
627
628         skl_write_plane_wm(plane, crtc_state);
629
630         I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0);
631         I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0);
632
633         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
634 }
635
636 static bool
637 skl_plane_get_hw_state(struct intel_plane *plane,
638                        enum pipe *pipe)
639 {
640         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
641         enum intel_display_power_domain power_domain;
642         enum plane_id plane_id = plane->id;
643         intel_wakeref_t wakeref;
644         bool ret;
645
646         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
647         wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
648         if (!wakeref)
649                 return false;
650
651         ret = I915_READ(PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE;
652
653         *pipe = plane->pipe;
654
655         intel_display_power_put(dev_priv, power_domain, wakeref);
656
657         return ret;
658 }
659
660 static void
661 chv_update_csc(const struct intel_plane_state *plane_state)
662 {
663         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
664         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
665         const struct drm_framebuffer *fb = plane_state->base.fb;
666         enum plane_id plane_id = plane->id;
667         /*
668          * |r|   | c0 c1 c2 |   |cr|
669          * |g| = | c3 c4 c5 | x |y |
670          * |b|   | c6 c7 c8 |   |cb|
671          *
672          * Coefficients are s3.12.
673          *
674          * Cb and Cr apparently come in as signed already, and
675          * we always get full range data in on account of CLRC0/1.
676          */
677         static const s16 csc_matrix[][9] = {
678                 /* BT.601 full range YCbCr -> full range RGB */
679                 [DRM_COLOR_YCBCR_BT601] = {
680                          5743, 4096,     0,
681                         -2925, 4096, -1410,
682                             0, 4096,  7258,
683                 },
684                 /* BT.709 full range YCbCr -> full range RGB */
685                 [DRM_COLOR_YCBCR_BT709] = {
686                          6450, 4096,     0,
687                         -1917, 4096,  -767,
688                             0, 4096,  7601,
689                 },
690         };
691         const s16 *csc = csc_matrix[plane_state->base.color_encoding];
692
693         /* Seems RGB data bypasses the CSC always */
694         if (!fb->format->is_yuv)
695                 return;
696
697         I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
698         I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
699         I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
700
701         I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(csc[1]) | SPCSC_C0(csc[0]));
702         I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(csc[3]) | SPCSC_C0(csc[2]));
703         I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(csc[5]) | SPCSC_C0(csc[4]));
704         I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(csc[7]) | SPCSC_C0(csc[6]));
705         I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(csc[8]));
706
707         I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(1023) | SPCSC_IMIN(0));
708         I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
709         I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
710
711         I915_WRITE_FW(SPCSCYGOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
712         I915_WRITE_FW(SPCSCCBOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
713         I915_WRITE_FW(SPCSCCROCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
714 }
715
716 #define SIN_0 0
717 #define COS_0 1
718
719 static void
720 vlv_update_clrc(const struct intel_plane_state *plane_state)
721 {
722         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
723         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
724         const struct drm_framebuffer *fb = plane_state->base.fb;
725         enum pipe pipe = plane->pipe;
726         enum plane_id plane_id = plane->id;
727         int contrast, brightness, sh_scale, sh_sin, sh_cos;
728
729         if (fb->format->is_yuv &&
730             plane_state->base.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) {
731                 /*
732                  * Expand limited range to full range:
733                  * Contrast is applied first and is used to expand Y range.
734                  * Brightness is applied second and is used to remove the
735                  * offset from Y. Saturation/hue is used to expand CbCr range.
736                  */
737                 contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16);
738                 brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16);
739                 sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128);
740                 sh_sin = SIN_0 * sh_scale;
741                 sh_cos = COS_0 * sh_scale;
742         } else {
743                 /* Pass-through everything. */
744                 contrast = 1 << 6;
745                 brightness = 0;
746                 sh_scale = 1 << 7;
747                 sh_sin = SIN_0 * sh_scale;
748                 sh_cos = COS_0 * sh_scale;
749         }
750
751         /* FIXME these register are single buffered :( */
752         I915_WRITE_FW(SPCLRC0(pipe, plane_id),
753                       SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness));
754         I915_WRITE_FW(SPCLRC1(pipe, plane_id),
755                       SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos));
756 }
757
758 static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
759 {
760         u32 sprctl = 0;
761
762         if (crtc_state->gamma_enable)
763                 sprctl |= SP_GAMMA_ENABLE;
764
765         return sprctl;
766 }
767
768 static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state,
769                           const struct intel_plane_state *plane_state)
770 {
771         const struct drm_framebuffer *fb = plane_state->base.fb;
772         unsigned int rotation = plane_state->base.rotation;
773         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
774         u32 sprctl;
775
776         sprctl = SP_ENABLE;
777
778         switch (fb->format->format) {
779         case DRM_FORMAT_YUYV:
780                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
781                 break;
782         case DRM_FORMAT_YVYU:
783                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
784                 break;
785         case DRM_FORMAT_UYVY:
786                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
787                 break;
788         case DRM_FORMAT_VYUY:
789                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
790                 break;
791         case DRM_FORMAT_RGB565:
792                 sprctl |= SP_FORMAT_BGR565;
793                 break;
794         case DRM_FORMAT_XRGB8888:
795                 sprctl |= SP_FORMAT_BGRX8888;
796                 break;
797         case DRM_FORMAT_ARGB8888:
798                 sprctl |= SP_FORMAT_BGRA8888;
799                 break;
800         case DRM_FORMAT_XBGR2101010:
801                 sprctl |= SP_FORMAT_RGBX1010102;
802                 break;
803         case DRM_FORMAT_ABGR2101010:
804                 sprctl |= SP_FORMAT_RGBA1010102;
805                 break;
806         case DRM_FORMAT_XBGR8888:
807                 sprctl |= SP_FORMAT_RGBX8888;
808                 break;
809         case DRM_FORMAT_ABGR8888:
810                 sprctl |= SP_FORMAT_RGBA8888;
811                 break;
812         default:
813                 MISSING_CASE(fb->format->format);
814                 return 0;
815         }
816
817         if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
818                 sprctl |= SP_YUV_FORMAT_BT709;
819
820         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
821                 sprctl |= SP_TILED;
822
823         if (rotation & DRM_MODE_ROTATE_180)
824                 sprctl |= SP_ROTATE_180;
825
826         if (rotation & DRM_MODE_REFLECT_X)
827                 sprctl |= SP_MIRROR;
828
829         if (key->flags & I915_SET_COLORKEY_SOURCE)
830                 sprctl |= SP_SOURCE_KEY;
831
832         return sprctl;
833 }
834
835 static void
836 vlv_update_plane(struct intel_plane *plane,
837                  const struct intel_crtc_state *crtc_state,
838                  const struct intel_plane_state *plane_state)
839 {
840         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
841         enum pipe pipe = plane->pipe;
842         enum plane_id plane_id = plane->id;
843         u32 sprsurf_offset = plane_state->color_plane[0].offset;
844         u32 linear_offset;
845         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
846         int crtc_x = plane_state->base.dst.x1;
847         int crtc_y = plane_state->base.dst.y1;
848         u32 crtc_w = drm_rect_width(&plane_state->base.dst);
849         u32 crtc_h = drm_rect_height(&plane_state->base.dst);
850         u32 x = plane_state->color_plane[0].x;
851         u32 y = plane_state->color_plane[0].y;
852         unsigned long irqflags;
853         u32 sprctl;
854
855         sprctl = plane_state->ctl | vlv_sprite_ctl_crtc(crtc_state);
856
857         /* Sizes are 0 based */
858         crtc_w--;
859         crtc_h--;
860
861         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
862
863         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
864
865         I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
866                       plane_state->color_plane[0].stride);
867         I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
868         I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
869         I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
870
871         if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
872                 chv_update_csc(plane_state);
873
874         if (key->flags) {
875                 I915_WRITE_FW(SPKEYMINVAL(pipe, plane_id), key->min_value);
876                 I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask);
877                 I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value);
878         }
879
880         I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
881         I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
882
883         /*
884          * The control register self-arms if the plane was previously
885          * disabled. Try to make the plane enable atomic by writing
886          * the control register just before the surface register.
887          */
888         I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl);
889         I915_WRITE_FW(SPSURF(pipe, plane_id),
890                       intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
891
892         vlv_update_clrc(plane_state);
893
894         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
895 }
896
897 static void
898 vlv_disable_plane(struct intel_plane *plane,
899                   const struct intel_crtc_state *crtc_state)
900 {
901         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
902         enum pipe pipe = plane->pipe;
903         enum plane_id plane_id = plane->id;
904         unsigned long irqflags;
905
906         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
907
908         I915_WRITE_FW(SPCNTR(pipe, plane_id), 0);
909         I915_WRITE_FW(SPSURF(pipe, plane_id), 0);
910
911         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
912 }
913
914 static bool
915 vlv_plane_get_hw_state(struct intel_plane *plane,
916                        enum pipe *pipe)
917 {
918         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
919         enum intel_display_power_domain power_domain;
920         enum plane_id plane_id = plane->id;
921         intel_wakeref_t wakeref;
922         bool ret;
923
924         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
925         wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
926         if (!wakeref)
927                 return false;
928
929         ret = I915_READ(SPCNTR(plane->pipe, plane_id)) & SP_ENABLE;
930
931         *pipe = plane->pipe;
932
933         intel_display_power_put(dev_priv, power_domain, wakeref);
934
935         return ret;
936 }
937
938 static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
939 {
940         u32 sprctl = 0;
941
942         if (crtc_state->gamma_enable)
943                 sprctl |= SPRITE_GAMMA_ENABLE;
944
945         if (crtc_state->csc_enable)
946                 sprctl |= SPRITE_PIPE_CSC_ENABLE;
947
948         return sprctl;
949 }
950
951 static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
952                           const struct intel_plane_state *plane_state)
953 {
954         struct drm_i915_private *dev_priv =
955                 to_i915(plane_state->base.plane->dev);
956         const struct drm_framebuffer *fb = plane_state->base.fb;
957         unsigned int rotation = plane_state->base.rotation;
958         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
959         u32 sprctl;
960
961         sprctl = SPRITE_ENABLE;
962
963         if (IS_IVYBRIDGE(dev_priv))
964                 sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
965
966         switch (fb->format->format) {
967         case DRM_FORMAT_XBGR8888:
968                 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
969                 break;
970         case DRM_FORMAT_XRGB8888:
971                 sprctl |= SPRITE_FORMAT_RGBX888;
972                 break;
973         case DRM_FORMAT_YUYV:
974                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
975                 break;
976         case DRM_FORMAT_YVYU:
977                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
978                 break;
979         case DRM_FORMAT_UYVY:
980                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
981                 break;
982         case DRM_FORMAT_VYUY:
983                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
984                 break;
985         default:
986                 MISSING_CASE(fb->format->format);
987                 return 0;
988         }
989
990         if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
991                 sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
992
993         if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
994                 sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE;
995
996         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
997                 sprctl |= SPRITE_TILED;
998
999         if (rotation & DRM_MODE_ROTATE_180)
1000                 sprctl |= SPRITE_ROTATE_180;
1001
1002         if (key->flags & I915_SET_COLORKEY_DESTINATION)
1003                 sprctl |= SPRITE_DEST_KEY;
1004         else if (key->flags & I915_SET_COLORKEY_SOURCE)
1005                 sprctl |= SPRITE_SOURCE_KEY;
1006
1007         return sprctl;
1008 }
1009
1010 static void
1011 ivb_update_plane(struct intel_plane *plane,
1012                  const struct intel_crtc_state *crtc_state,
1013                  const struct intel_plane_state *plane_state)
1014 {
1015         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1016         enum pipe pipe = plane->pipe;
1017         u32 sprsurf_offset = plane_state->color_plane[0].offset;
1018         u32 linear_offset;
1019         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1020         int crtc_x = plane_state->base.dst.x1;
1021         int crtc_y = plane_state->base.dst.y1;
1022         u32 crtc_w = drm_rect_width(&plane_state->base.dst);
1023         u32 crtc_h = drm_rect_height(&plane_state->base.dst);
1024         u32 x = plane_state->color_plane[0].x;
1025         u32 y = plane_state->color_plane[0].y;
1026         u32 src_w = drm_rect_width(&plane_state->base.src) >> 16;
1027         u32 src_h = drm_rect_height(&plane_state->base.src) >> 16;
1028         u32 sprctl, sprscale = 0;
1029         unsigned long irqflags;
1030
1031         sprctl = plane_state->ctl | ivb_sprite_ctl_crtc(crtc_state);
1032
1033         /* Sizes are 0 based */
1034         src_w--;
1035         src_h--;
1036         crtc_w--;
1037         crtc_h--;
1038
1039         if (crtc_w != src_w || crtc_h != src_h)
1040                 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
1041
1042         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
1043
1044         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1045
1046         I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
1047         I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
1048         I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
1049         if (IS_IVYBRIDGE(dev_priv))
1050                 I915_WRITE_FW(SPRSCALE(pipe), sprscale);
1051
1052         if (key->flags) {
1053                 I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value);
1054                 I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask);
1055                 I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value);
1056         }
1057
1058         /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
1059          * register */
1060         if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
1061                 I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x);
1062         } else {
1063                 I915_WRITE_FW(SPRLINOFF(pipe), linear_offset);
1064                 I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x);
1065         }
1066
1067         /*
1068          * The control register self-arms if the plane was previously
1069          * disabled. Try to make the plane enable atomic by writing
1070          * the control register just before the surface register.
1071          */
1072         I915_WRITE_FW(SPRCTL(pipe), sprctl);
1073         I915_WRITE_FW(SPRSURF(pipe),
1074                       intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
1075
1076         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1077 }
1078
1079 static void
1080 ivb_disable_plane(struct intel_plane *plane,
1081                   const struct intel_crtc_state *crtc_state)
1082 {
1083         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1084         enum pipe pipe = plane->pipe;
1085         unsigned long irqflags;
1086
1087         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1088
1089         I915_WRITE_FW(SPRCTL(pipe), 0);
1090         /* Disable the scaler */
1091         if (IS_IVYBRIDGE(dev_priv))
1092                 I915_WRITE_FW(SPRSCALE(pipe), 0);
1093         I915_WRITE_FW(SPRSURF(pipe), 0);
1094
1095         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1096 }
1097
1098 static bool
1099 ivb_plane_get_hw_state(struct intel_plane *plane,
1100                        enum pipe *pipe)
1101 {
1102         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1103         enum intel_display_power_domain power_domain;
1104         intel_wakeref_t wakeref;
1105         bool ret;
1106
1107         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
1108         wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
1109         if (!wakeref)
1110                 return false;
1111
1112         ret =  I915_READ(SPRCTL(plane->pipe)) & SPRITE_ENABLE;
1113
1114         *pipe = plane->pipe;
1115
1116         intel_display_power_put(dev_priv, power_domain, wakeref);
1117
1118         return ret;
1119 }
1120
1121 static unsigned int
1122 g4x_sprite_max_stride(struct intel_plane *plane,
1123                       u32 pixel_format, u64 modifier,
1124                       unsigned int rotation)
1125 {
1126         return 16384;
1127 }
1128
1129 static u32 g4x_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
1130 {
1131         u32 dvscntr = 0;
1132
1133         if (crtc_state->gamma_enable)
1134                 dvscntr |= DVS_GAMMA_ENABLE;
1135
1136         if (crtc_state->csc_enable)
1137                 dvscntr |= DVS_PIPE_CSC_ENABLE;
1138
1139         return dvscntr;
1140 }
1141
1142 static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state,
1143                           const struct intel_plane_state *plane_state)
1144 {
1145         struct drm_i915_private *dev_priv =
1146                 to_i915(plane_state->base.plane->dev);
1147         const struct drm_framebuffer *fb = plane_state->base.fb;
1148         unsigned int rotation = plane_state->base.rotation;
1149         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1150         u32 dvscntr;
1151
1152         dvscntr = DVS_ENABLE;
1153
1154         if (IS_GEN(dev_priv, 6))
1155                 dvscntr |= DVS_TRICKLE_FEED_DISABLE;
1156
1157         switch (fb->format->format) {
1158         case DRM_FORMAT_XBGR8888:
1159                 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
1160                 break;
1161         case DRM_FORMAT_XRGB8888:
1162                 dvscntr |= DVS_FORMAT_RGBX888;
1163                 break;
1164         case DRM_FORMAT_YUYV:
1165                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
1166                 break;
1167         case DRM_FORMAT_YVYU:
1168                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
1169                 break;
1170         case DRM_FORMAT_UYVY:
1171                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
1172                 break;
1173         case DRM_FORMAT_VYUY:
1174                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
1175                 break;
1176         default:
1177                 MISSING_CASE(fb->format->format);
1178                 return 0;
1179         }
1180
1181         if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
1182                 dvscntr |= DVS_YUV_FORMAT_BT709;
1183
1184         if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
1185                 dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE;
1186
1187         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
1188                 dvscntr |= DVS_TILED;
1189
1190         if (rotation & DRM_MODE_ROTATE_180)
1191                 dvscntr |= DVS_ROTATE_180;
1192
1193         if (key->flags & I915_SET_COLORKEY_DESTINATION)
1194                 dvscntr |= DVS_DEST_KEY;
1195         else if (key->flags & I915_SET_COLORKEY_SOURCE)
1196                 dvscntr |= DVS_SOURCE_KEY;
1197
1198         return dvscntr;
1199 }
1200
1201 static void
1202 g4x_update_plane(struct intel_plane *plane,
1203                  const struct intel_crtc_state *crtc_state,
1204                  const struct intel_plane_state *plane_state)
1205 {
1206         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1207         enum pipe pipe = plane->pipe;
1208         u32 dvssurf_offset = plane_state->color_plane[0].offset;
1209         u32 linear_offset;
1210         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1211         int crtc_x = plane_state->base.dst.x1;
1212         int crtc_y = plane_state->base.dst.y1;
1213         u32 crtc_w = drm_rect_width(&plane_state->base.dst);
1214         u32 crtc_h = drm_rect_height(&plane_state->base.dst);
1215         u32 x = plane_state->color_plane[0].x;
1216         u32 y = plane_state->color_plane[0].y;
1217         u32 src_w = drm_rect_width(&plane_state->base.src) >> 16;
1218         u32 src_h = drm_rect_height(&plane_state->base.src) >> 16;
1219         u32 dvscntr, dvsscale = 0;
1220         unsigned long irqflags;
1221
1222         dvscntr = plane_state->ctl | g4x_sprite_ctl_crtc(crtc_state);
1223
1224         /* Sizes are 0 based */
1225         src_w--;
1226         src_h--;
1227         crtc_w--;
1228         crtc_h--;
1229
1230         if (crtc_w != src_w || crtc_h != src_h)
1231                 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
1232
1233         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
1234
1235         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1236
1237         I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
1238         I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
1239         I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
1240         I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
1241
1242         if (key->flags) {
1243                 I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value);
1244                 I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask);
1245                 I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value);
1246         }
1247
1248         I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
1249         I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
1250
1251         /*
1252          * The control register self-arms if the plane was previously
1253          * disabled. Try to make the plane enable atomic by writing
1254          * the control register just before the surface register.
1255          */
1256         I915_WRITE_FW(DVSCNTR(pipe), dvscntr);
1257         I915_WRITE_FW(DVSSURF(pipe),
1258                       intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
1259
1260         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1261 }
1262
1263 static void
1264 g4x_disable_plane(struct intel_plane *plane,
1265                   const struct intel_crtc_state *crtc_state)
1266 {
1267         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1268         enum pipe pipe = plane->pipe;
1269         unsigned long irqflags;
1270
1271         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1272
1273         I915_WRITE_FW(DVSCNTR(pipe), 0);
1274         /* Disable the scaler */
1275         I915_WRITE_FW(DVSSCALE(pipe), 0);
1276         I915_WRITE_FW(DVSSURF(pipe), 0);
1277
1278         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1279 }
1280
1281 static bool
1282 g4x_plane_get_hw_state(struct intel_plane *plane,
1283                        enum pipe *pipe)
1284 {
1285         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1286         enum intel_display_power_domain power_domain;
1287         intel_wakeref_t wakeref;
1288         bool ret;
1289
1290         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
1291         wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
1292         if (!wakeref)
1293                 return false;
1294
1295         ret = I915_READ(DVSCNTR(plane->pipe)) & DVS_ENABLE;
1296
1297         *pipe = plane->pipe;
1298
1299         intel_display_power_put(dev_priv, power_domain, wakeref);
1300
1301         return ret;
1302 }
1303
1304 static bool intel_fb_scalable(const struct drm_framebuffer *fb)
1305 {
1306         if (!fb)
1307                 return false;
1308
1309         switch (fb->format->format) {
1310         case DRM_FORMAT_C8:
1311                 return false;
1312         default:
1313                 return true;
1314         }
1315 }
1316
1317 static int
1318 g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
1319                          struct intel_plane_state *plane_state)
1320 {
1321         const struct drm_framebuffer *fb = plane_state->base.fb;
1322         const struct drm_rect *src = &plane_state->base.src;
1323         const struct drm_rect *dst = &plane_state->base.dst;
1324         int src_x, src_y, src_w, src_h, crtc_w, crtc_h;
1325         const struct drm_display_mode *adjusted_mode =
1326                 &crtc_state->base.adjusted_mode;
1327         unsigned int cpp = fb->format->cpp[0];
1328         unsigned int width_bytes;
1329         int min_width, min_height;
1330
1331         crtc_w = drm_rect_width(dst);
1332         crtc_h = drm_rect_height(dst);
1333
1334         src_x = src->x1 >> 16;
1335         src_y = src->y1 >> 16;
1336         src_w = drm_rect_width(src) >> 16;
1337         src_h = drm_rect_height(src) >> 16;
1338
1339         if (src_w == crtc_w && src_h == crtc_h)
1340                 return 0;
1341
1342         min_width = 3;
1343
1344         if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
1345                 if (src_h & 1) {
1346                         DRM_DEBUG_KMS("Source height must be even with interlaced modes\n");
1347                         return -EINVAL;
1348                 }
1349                 min_height = 6;
1350         } else {
1351                 min_height = 3;
1352         }
1353
1354         width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
1355
1356         if (src_w < min_width || src_h < min_height ||
1357             src_w > 2048 || src_h > 2048) {
1358                 DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
1359                               src_w, src_h, min_width, min_height, 2048, 2048);
1360                 return -EINVAL;
1361         }
1362
1363         if (width_bytes > 4096) {
1364                 DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n",
1365                               width_bytes, 4096);
1366                 return -EINVAL;
1367         }
1368
1369         if (width_bytes > 4096 || fb->pitches[0] > 4096) {
1370                 DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n",
1371                               fb->pitches[0], 4096);
1372                 return -EINVAL;
1373         }
1374
1375         return 0;
1376 }
1377
1378 static int
1379 g4x_sprite_check(struct intel_crtc_state *crtc_state,
1380                  struct intel_plane_state *plane_state)
1381 {
1382         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1383         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1384         int min_scale = DRM_PLANE_HELPER_NO_SCALING;
1385         int max_scale = DRM_PLANE_HELPER_NO_SCALING;
1386         int ret;
1387
1388         if (intel_fb_scalable(plane_state->base.fb)) {
1389                 if (INTEL_GEN(dev_priv) < 7) {
1390                         min_scale = 1;
1391                         max_scale = 16 << 16;
1392                 } else if (IS_IVYBRIDGE(dev_priv)) {
1393                         min_scale = 1;
1394                         max_scale = 2 << 16;
1395                 }
1396         }
1397
1398         ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1399                                                   &crtc_state->base,
1400                                                   min_scale, max_scale,
1401                                                   true, true);
1402         if (ret)
1403                 return ret;
1404
1405         if (!plane_state->base.visible)
1406                 return 0;
1407
1408         ret = intel_plane_check_src_coordinates(plane_state);
1409         if (ret)
1410                 return ret;
1411
1412         ret = g4x_sprite_check_scaling(crtc_state, plane_state);
1413         if (ret)
1414                 return ret;
1415
1416         ret = i9xx_check_plane_surface(plane_state);
1417         if (ret)
1418                 return ret;
1419
1420         if (INTEL_GEN(dev_priv) >= 7)
1421                 plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state);
1422         else
1423                 plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state);
1424
1425         return 0;
1426 }
1427
1428 int chv_plane_check_rotation(const struct intel_plane_state *plane_state)
1429 {
1430         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1431         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1432         unsigned int rotation = plane_state->base.rotation;
1433
1434         /* CHV ignores the mirror bit when the rotate bit is set :( */
1435         if (IS_CHERRYVIEW(dev_priv) &&
1436             rotation & DRM_MODE_ROTATE_180 &&
1437             rotation & DRM_MODE_REFLECT_X) {
1438                 DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n");
1439                 return -EINVAL;
1440         }
1441
1442         return 0;
1443 }
1444
1445 static int
1446 vlv_sprite_check(struct intel_crtc_state *crtc_state,
1447                  struct intel_plane_state *plane_state)
1448 {
1449         int ret;
1450
1451         ret = chv_plane_check_rotation(plane_state);
1452         if (ret)
1453                 return ret;
1454
1455         ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1456                                                   &crtc_state->base,
1457                                                   DRM_PLANE_HELPER_NO_SCALING,
1458                                                   DRM_PLANE_HELPER_NO_SCALING,
1459                                                   true, true);
1460         if (ret)
1461                 return ret;
1462
1463         if (!plane_state->base.visible)
1464                 return 0;
1465
1466         ret = intel_plane_check_src_coordinates(plane_state);
1467         if (ret)
1468                 return ret;
1469
1470         ret = i9xx_check_plane_surface(plane_state);
1471         if (ret)
1472                 return ret;
1473
1474         plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state);
1475
1476         return 0;
1477 }
1478
1479 static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
1480                               const struct intel_plane_state *plane_state)
1481 {
1482         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1483         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1484         const struct drm_framebuffer *fb = plane_state->base.fb;
1485         unsigned int rotation = plane_state->base.rotation;
1486         struct drm_format_name_buf format_name;
1487
1488         if (!fb)
1489                 return 0;
1490
1491         if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) &&
1492             is_ccs_modifier(fb->modifier)) {
1493                 DRM_DEBUG_KMS("RC support only with 0/180 degree rotation (%x)\n",
1494                               rotation);
1495                 return -EINVAL;
1496         }
1497
1498         if (rotation & DRM_MODE_REFLECT_X &&
1499             fb->modifier == DRM_FORMAT_MOD_LINEAR) {
1500                 DRM_DEBUG_KMS("horizontal flip is not supported with linear surface formats\n");
1501                 return -EINVAL;
1502         }
1503
1504         if (drm_rotation_90_or_270(rotation)) {
1505                 if (fb->modifier != I915_FORMAT_MOD_Y_TILED &&
1506                     fb->modifier != I915_FORMAT_MOD_Yf_TILED) {
1507                         DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n");
1508                         return -EINVAL;
1509                 }
1510
1511                 /*
1512                  * 90/270 is not allowed with RGB64 16:16:16:16 and
1513                  * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards.
1514                  */
1515                 switch (fb->format->format) {
1516                 case DRM_FORMAT_RGB565:
1517                         if (INTEL_GEN(dev_priv) >= 11)
1518                                 break;
1519                         /* fall through */
1520                 case DRM_FORMAT_C8:
1521                 case DRM_FORMAT_XRGB16161616F:
1522                 case DRM_FORMAT_XBGR16161616F:
1523                 case DRM_FORMAT_ARGB16161616F:
1524                 case DRM_FORMAT_ABGR16161616F:
1525                         DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n",
1526                                       drm_get_format_name(fb->format->format,
1527                                                           &format_name));
1528                         return -EINVAL;
1529                 default:
1530                         break;
1531                 }
1532         }
1533
1534         /* Y-tiling is not supported in IF-ID Interlace mode */
1535         if (crtc_state->base.enable &&
1536             crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
1537             (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
1538              fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
1539              fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
1540              fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS)) {
1541                 DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n");
1542                 return -EINVAL;
1543         }
1544
1545         return 0;
1546 }
1547
1548 static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state,
1549                                            const struct intel_plane_state *plane_state)
1550 {
1551         struct drm_i915_private *dev_priv =
1552                 to_i915(plane_state->base.plane->dev);
1553         int crtc_x = plane_state->base.dst.x1;
1554         int crtc_w = drm_rect_width(&plane_state->base.dst);
1555         int pipe_src_w = crtc_state->pipe_src_w;
1556
1557         /*
1558          * Display WA #1175: cnl,glk
1559          * Planes other than the cursor may cause FIFO underflow and display
1560          * corruption if starting less than 4 pixels from the right edge of
1561          * the screen.
1562          * Besides the above WA fix the similar problem, where planes other
1563          * than the cursor ending less than 4 pixels from the left edge of the
1564          * screen may cause FIFO underflow and display corruption.
1565          */
1566         if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
1567             (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
1568                 DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n",
1569                               crtc_x + crtc_w < 4 ? "end" : "start",
1570                               crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x,
1571                               4, pipe_src_w - 4);
1572                 return -ERANGE;
1573         }
1574
1575         return 0;
1576 }
1577
1578 static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
1579 {
1580         const struct drm_framebuffer *fb = plane_state->base.fb;
1581         unsigned int rotation = plane_state->base.rotation;
1582         int src_w = drm_rect_width(&plane_state->base.src) >> 16;
1583
1584         /* Display WA #1106 */
1585         if (is_planar_yuv_format(fb->format->format) && src_w & 3 &&
1586             (rotation == DRM_MODE_ROTATE_270 ||
1587              rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
1588                 DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n");
1589                 return -EINVAL;
1590         }
1591
1592         return 0;
1593 }
1594
1595 static int skl_plane_check(struct intel_crtc_state *crtc_state,
1596                            struct intel_plane_state *plane_state)
1597 {
1598         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1599         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1600         const struct drm_framebuffer *fb = plane_state->base.fb;
1601         int min_scale = DRM_PLANE_HELPER_NO_SCALING;
1602         int max_scale = DRM_PLANE_HELPER_NO_SCALING;
1603         int ret;
1604
1605         ret = skl_plane_check_fb(crtc_state, plane_state);
1606         if (ret)
1607                 return ret;
1608
1609         /* use scaler when colorkey is not required */
1610         if (!plane_state->ckey.flags && intel_fb_scalable(fb)) {
1611                 min_scale = 1;
1612                 max_scale = skl_max_scale(crtc_state, fb->format->format);
1613         }
1614
1615         ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1616                                                   &crtc_state->base,
1617                                                   min_scale, max_scale,
1618                                                   true, true);
1619         if (ret)
1620                 return ret;
1621
1622         if (!plane_state->base.visible)
1623                 return 0;
1624
1625         ret = skl_plane_check_dst_coordinates(crtc_state, plane_state);
1626         if (ret)
1627                 return ret;
1628
1629         ret = intel_plane_check_src_coordinates(plane_state);
1630         if (ret)
1631                 return ret;
1632
1633         ret = skl_plane_check_nv12_rotation(plane_state);
1634         if (ret)
1635                 return ret;
1636
1637         ret = skl_check_plane_surface(plane_state);
1638         if (ret)
1639                 return ret;
1640
1641         /* HW only has 8 bits pixel precision, disable plane if invisible */
1642         if (!(plane_state->base.alpha >> 8))
1643                 plane_state->base.visible = false;
1644
1645         plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
1646
1647         if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
1648                 plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
1649                                                              plane_state);
1650
1651         return 0;
1652 }
1653
1654 static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv)
1655 {
1656         return INTEL_GEN(dev_priv) >= 9;
1657 }
1658
1659 static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
1660                                  const struct drm_intel_sprite_colorkey *set)
1661 {
1662         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1663         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1664         struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1665
1666         *key = *set;
1667
1668         /*
1669          * We want src key enabled on the
1670          * sprite and not on the primary.
1671          */
1672         if (plane->id == PLANE_PRIMARY &&
1673             set->flags & I915_SET_COLORKEY_SOURCE)
1674                 key->flags = 0;
1675
1676         /*
1677          * On SKL+ we want dst key enabled on
1678          * the primary and not on the sprite.
1679          */
1680         if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_PRIMARY &&
1681             set->flags & I915_SET_COLORKEY_DESTINATION)
1682                 key->flags = 0;
1683 }
1684
1685 int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
1686                                     struct drm_file *file_priv)
1687 {
1688         struct drm_i915_private *dev_priv = to_i915(dev);
1689         struct drm_intel_sprite_colorkey *set = data;
1690         struct drm_plane *plane;
1691         struct drm_plane_state *plane_state;
1692         struct drm_atomic_state *state;
1693         struct drm_modeset_acquire_ctx ctx;
1694         int ret = 0;
1695
1696         /* ignore the pointless "none" flag */
1697         set->flags &= ~I915_SET_COLORKEY_NONE;
1698
1699         if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
1700                 return -EINVAL;
1701
1702         /* Make sure we don't try to enable both src & dest simultaneously */
1703         if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
1704                 return -EINVAL;
1705
1706         if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
1707             set->flags & I915_SET_COLORKEY_DESTINATION)
1708                 return -EINVAL;
1709
1710         plane = drm_plane_find(dev, file_priv, set->plane_id);
1711         if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
1712                 return -ENOENT;
1713
1714         /*
1715          * SKL+ only plane 2 can do destination keying against plane 1.
1716          * Also multiple planes can't do destination keying on the same
1717          * pipe simultaneously.
1718          */
1719         if (INTEL_GEN(dev_priv) >= 9 &&
1720             to_intel_plane(plane)->id >= PLANE_SPRITE1 &&
1721             set->flags & I915_SET_COLORKEY_DESTINATION)
1722                 return -EINVAL;
1723
1724         drm_modeset_acquire_init(&ctx, 0);
1725
1726         state = drm_atomic_state_alloc(plane->dev);
1727         if (!state) {
1728                 ret = -ENOMEM;
1729                 goto out;
1730         }
1731         state->acquire_ctx = &ctx;
1732
1733         while (1) {
1734                 plane_state = drm_atomic_get_plane_state(state, plane);
1735                 ret = PTR_ERR_OR_ZERO(plane_state);
1736                 if (!ret)
1737                         intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
1738
1739                 /*
1740                  * On some platforms we have to configure
1741                  * the dst colorkey on the primary plane.
1742                  */
1743                 if (!ret && has_dst_key_in_primary_plane(dev_priv)) {
1744                         struct intel_crtc *crtc =
1745                                 intel_get_crtc_for_pipe(dev_priv,
1746                                                         to_intel_plane(plane)->pipe);
1747
1748                         plane_state = drm_atomic_get_plane_state(state,
1749                                                                  crtc->base.primary);
1750                         ret = PTR_ERR_OR_ZERO(plane_state);
1751                         if (!ret)
1752                                 intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
1753                 }
1754
1755                 if (!ret)
1756                         ret = drm_atomic_commit(state);
1757
1758                 if (ret != -EDEADLK)
1759                         break;
1760
1761                 drm_atomic_state_clear(state);
1762                 drm_modeset_backoff(&ctx);
1763         }
1764
1765         drm_atomic_state_put(state);
1766 out:
1767         drm_modeset_drop_locks(&ctx);
1768         drm_modeset_acquire_fini(&ctx);
1769         return ret;
1770 }
1771
1772 static const u32 g4x_plane_formats[] = {
1773         DRM_FORMAT_XRGB8888,
1774         DRM_FORMAT_YUYV,
1775         DRM_FORMAT_YVYU,
1776         DRM_FORMAT_UYVY,
1777         DRM_FORMAT_VYUY,
1778 };
1779
1780 static const u64 i9xx_plane_format_modifiers[] = {
1781         I915_FORMAT_MOD_X_TILED,
1782         DRM_FORMAT_MOD_LINEAR,
1783         DRM_FORMAT_MOD_INVALID
1784 };
1785
1786 static const u32 snb_plane_formats[] = {
1787         DRM_FORMAT_XBGR8888,
1788         DRM_FORMAT_XRGB8888,
1789         DRM_FORMAT_YUYV,
1790         DRM_FORMAT_YVYU,
1791         DRM_FORMAT_UYVY,
1792         DRM_FORMAT_VYUY,
1793 };
1794
1795 static const u32 vlv_plane_formats[] = {
1796         DRM_FORMAT_RGB565,
1797         DRM_FORMAT_ABGR8888,
1798         DRM_FORMAT_ARGB8888,
1799         DRM_FORMAT_XBGR8888,
1800         DRM_FORMAT_XRGB8888,
1801         DRM_FORMAT_XBGR2101010,
1802         DRM_FORMAT_ABGR2101010,
1803         DRM_FORMAT_YUYV,
1804         DRM_FORMAT_YVYU,
1805         DRM_FORMAT_UYVY,
1806         DRM_FORMAT_VYUY,
1807 };
1808
1809 static const u32 skl_plane_formats[] = {
1810         DRM_FORMAT_C8,
1811         DRM_FORMAT_RGB565,
1812         DRM_FORMAT_XRGB8888,
1813         DRM_FORMAT_XBGR8888,
1814         DRM_FORMAT_ARGB8888,
1815         DRM_FORMAT_ABGR8888,
1816         DRM_FORMAT_XRGB2101010,
1817         DRM_FORMAT_XBGR2101010,
1818         DRM_FORMAT_YUYV,
1819         DRM_FORMAT_YVYU,
1820         DRM_FORMAT_UYVY,
1821         DRM_FORMAT_VYUY,
1822 };
1823
1824 static const uint32_t icl_plane_formats[] = {
1825         DRM_FORMAT_C8,
1826         DRM_FORMAT_RGB565,
1827         DRM_FORMAT_XRGB8888,
1828         DRM_FORMAT_XBGR8888,
1829         DRM_FORMAT_ARGB8888,
1830         DRM_FORMAT_ABGR8888,
1831         DRM_FORMAT_XRGB2101010,
1832         DRM_FORMAT_XBGR2101010,
1833         DRM_FORMAT_YUYV,
1834         DRM_FORMAT_YVYU,
1835         DRM_FORMAT_UYVY,
1836         DRM_FORMAT_VYUY,
1837         DRM_FORMAT_Y210,
1838         DRM_FORMAT_Y212,
1839         DRM_FORMAT_Y216,
1840         DRM_FORMAT_Y410,
1841         DRM_FORMAT_Y412,
1842         DRM_FORMAT_Y416,
1843 };
1844
1845 static const uint32_t icl_hdr_plane_formats[] = {
1846         DRM_FORMAT_C8,
1847         DRM_FORMAT_RGB565,
1848         DRM_FORMAT_XRGB8888,
1849         DRM_FORMAT_XBGR8888,
1850         DRM_FORMAT_ARGB8888,
1851         DRM_FORMAT_ABGR8888,
1852         DRM_FORMAT_XRGB2101010,
1853         DRM_FORMAT_XBGR2101010,
1854         DRM_FORMAT_XRGB16161616F,
1855         DRM_FORMAT_XBGR16161616F,
1856         DRM_FORMAT_ARGB16161616F,
1857         DRM_FORMAT_ABGR16161616F,
1858         DRM_FORMAT_YUYV,
1859         DRM_FORMAT_YVYU,
1860         DRM_FORMAT_UYVY,
1861         DRM_FORMAT_VYUY,
1862         DRM_FORMAT_Y210,
1863         DRM_FORMAT_Y212,
1864         DRM_FORMAT_Y216,
1865         DRM_FORMAT_Y410,
1866         DRM_FORMAT_Y412,
1867         DRM_FORMAT_Y416,
1868 };
1869
1870 static const u32 skl_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 };
1885
1886 static const uint32_t glk_planar_formats[] = {
1887         DRM_FORMAT_C8,
1888         DRM_FORMAT_RGB565,
1889         DRM_FORMAT_XRGB8888,
1890         DRM_FORMAT_XBGR8888,
1891         DRM_FORMAT_ARGB8888,
1892         DRM_FORMAT_ABGR8888,
1893         DRM_FORMAT_XRGB2101010,
1894         DRM_FORMAT_XBGR2101010,
1895         DRM_FORMAT_YUYV,
1896         DRM_FORMAT_YVYU,
1897         DRM_FORMAT_UYVY,
1898         DRM_FORMAT_VYUY,
1899         DRM_FORMAT_NV12,
1900         DRM_FORMAT_P010,
1901         DRM_FORMAT_P012,
1902         DRM_FORMAT_P016,
1903 };
1904
1905 static const uint32_t icl_planar_formats[] = {
1906         DRM_FORMAT_C8,
1907         DRM_FORMAT_RGB565,
1908         DRM_FORMAT_XRGB8888,
1909         DRM_FORMAT_XBGR8888,
1910         DRM_FORMAT_ARGB8888,
1911         DRM_FORMAT_ABGR8888,
1912         DRM_FORMAT_XRGB2101010,
1913         DRM_FORMAT_XBGR2101010,
1914         DRM_FORMAT_YUYV,
1915         DRM_FORMAT_YVYU,
1916         DRM_FORMAT_UYVY,
1917         DRM_FORMAT_VYUY,
1918         DRM_FORMAT_NV12,
1919         DRM_FORMAT_P010,
1920         DRM_FORMAT_P012,
1921         DRM_FORMAT_P016,
1922         DRM_FORMAT_Y210,
1923         DRM_FORMAT_Y212,
1924         DRM_FORMAT_Y216,
1925         DRM_FORMAT_Y410,
1926         DRM_FORMAT_Y412,
1927         DRM_FORMAT_Y416,
1928 };
1929
1930 static const uint32_t icl_hdr_planar_formats[] = {
1931         DRM_FORMAT_C8,
1932         DRM_FORMAT_RGB565,
1933         DRM_FORMAT_XRGB8888,
1934         DRM_FORMAT_XBGR8888,
1935         DRM_FORMAT_ARGB8888,
1936         DRM_FORMAT_ABGR8888,
1937         DRM_FORMAT_XRGB2101010,
1938         DRM_FORMAT_XBGR2101010,
1939         DRM_FORMAT_XRGB16161616F,
1940         DRM_FORMAT_XBGR16161616F,
1941         DRM_FORMAT_ARGB16161616F,
1942         DRM_FORMAT_ABGR16161616F,
1943         DRM_FORMAT_YUYV,
1944         DRM_FORMAT_YVYU,
1945         DRM_FORMAT_UYVY,
1946         DRM_FORMAT_VYUY,
1947         DRM_FORMAT_NV12,
1948         DRM_FORMAT_P010,
1949         DRM_FORMAT_P012,
1950         DRM_FORMAT_P016,
1951         DRM_FORMAT_Y210,
1952         DRM_FORMAT_Y212,
1953         DRM_FORMAT_Y216,
1954         DRM_FORMAT_Y410,
1955         DRM_FORMAT_Y412,
1956         DRM_FORMAT_Y416,
1957 };
1958
1959 static const u64 skl_plane_format_modifiers_noccs[] = {
1960         I915_FORMAT_MOD_Yf_TILED,
1961         I915_FORMAT_MOD_Y_TILED,
1962         I915_FORMAT_MOD_X_TILED,
1963         DRM_FORMAT_MOD_LINEAR,
1964         DRM_FORMAT_MOD_INVALID
1965 };
1966
1967 static const u64 skl_plane_format_modifiers_ccs[] = {
1968         I915_FORMAT_MOD_Yf_TILED_CCS,
1969         I915_FORMAT_MOD_Y_TILED_CCS,
1970         I915_FORMAT_MOD_Yf_TILED,
1971         I915_FORMAT_MOD_Y_TILED,
1972         I915_FORMAT_MOD_X_TILED,
1973         DRM_FORMAT_MOD_LINEAR,
1974         DRM_FORMAT_MOD_INVALID
1975 };
1976
1977 static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane,
1978                                             u32 format, u64 modifier)
1979 {
1980         switch (modifier) {
1981         case DRM_FORMAT_MOD_LINEAR:
1982         case I915_FORMAT_MOD_X_TILED:
1983                 break;
1984         default:
1985                 return false;
1986         }
1987
1988         switch (format) {
1989         case DRM_FORMAT_XRGB8888:
1990         case DRM_FORMAT_YUYV:
1991         case DRM_FORMAT_YVYU:
1992         case DRM_FORMAT_UYVY:
1993         case DRM_FORMAT_VYUY:
1994                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
1995                     modifier == I915_FORMAT_MOD_X_TILED)
1996                         return true;
1997                 /* fall through */
1998         default:
1999                 return false;
2000         }
2001 }
2002
2003 static bool snb_sprite_format_mod_supported(struct drm_plane *_plane,
2004                                             u32 format, u64 modifier)
2005 {
2006         switch (modifier) {
2007         case DRM_FORMAT_MOD_LINEAR:
2008         case I915_FORMAT_MOD_X_TILED:
2009                 break;
2010         default:
2011                 return false;
2012         }
2013
2014         switch (format) {
2015         case DRM_FORMAT_XRGB8888:
2016         case DRM_FORMAT_XBGR8888:
2017         case DRM_FORMAT_YUYV:
2018         case DRM_FORMAT_YVYU:
2019         case DRM_FORMAT_UYVY:
2020         case DRM_FORMAT_VYUY:
2021                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
2022                     modifier == I915_FORMAT_MOD_X_TILED)
2023                         return true;
2024                 /* fall through */
2025         default:
2026                 return false;
2027         }
2028 }
2029
2030 static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane,
2031                                             u32 format, u64 modifier)
2032 {
2033         switch (modifier) {
2034         case DRM_FORMAT_MOD_LINEAR:
2035         case I915_FORMAT_MOD_X_TILED:
2036                 break;
2037         default:
2038                 return false;
2039         }
2040
2041         switch (format) {
2042         case DRM_FORMAT_RGB565:
2043         case DRM_FORMAT_ABGR8888:
2044         case DRM_FORMAT_ARGB8888:
2045         case DRM_FORMAT_XBGR8888:
2046         case DRM_FORMAT_XRGB8888:
2047         case DRM_FORMAT_XBGR2101010:
2048         case DRM_FORMAT_ABGR2101010:
2049         case DRM_FORMAT_YUYV:
2050         case DRM_FORMAT_YVYU:
2051         case DRM_FORMAT_UYVY:
2052         case DRM_FORMAT_VYUY:
2053                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
2054                     modifier == I915_FORMAT_MOD_X_TILED)
2055                         return true;
2056                 /* fall through */
2057         default:
2058                 return false;
2059         }
2060 }
2061
2062 static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
2063                                            u32 format, u64 modifier)
2064 {
2065         struct intel_plane *plane = to_intel_plane(_plane);
2066
2067         switch (modifier) {
2068         case DRM_FORMAT_MOD_LINEAR:
2069         case I915_FORMAT_MOD_X_TILED:
2070         case I915_FORMAT_MOD_Y_TILED:
2071         case I915_FORMAT_MOD_Yf_TILED:
2072                 break;
2073         case I915_FORMAT_MOD_Y_TILED_CCS:
2074         case I915_FORMAT_MOD_Yf_TILED_CCS:
2075                 if (!plane->has_ccs)
2076                         return false;
2077                 break;
2078         default:
2079                 return false;
2080         }
2081
2082         switch (format) {
2083         case DRM_FORMAT_XRGB8888:
2084         case DRM_FORMAT_XBGR8888:
2085         case DRM_FORMAT_ARGB8888:
2086         case DRM_FORMAT_ABGR8888:
2087                 if (is_ccs_modifier(modifier))
2088                         return true;
2089                 /* fall through */
2090         case DRM_FORMAT_RGB565:
2091         case DRM_FORMAT_XRGB2101010:
2092         case DRM_FORMAT_XBGR2101010:
2093         case DRM_FORMAT_YUYV:
2094         case DRM_FORMAT_YVYU:
2095         case DRM_FORMAT_UYVY:
2096         case DRM_FORMAT_VYUY:
2097         case DRM_FORMAT_NV12:
2098         case DRM_FORMAT_P010:
2099         case DRM_FORMAT_P012:
2100         case DRM_FORMAT_P016:
2101         case DRM_FORMAT_Y210:
2102         case DRM_FORMAT_Y212:
2103         case DRM_FORMAT_Y216:
2104         case DRM_FORMAT_Y410:
2105         case DRM_FORMAT_Y412:
2106         case DRM_FORMAT_Y416:
2107                 if (modifier == I915_FORMAT_MOD_Yf_TILED)
2108                         return true;
2109                 /* fall through */
2110         case DRM_FORMAT_C8:
2111         case DRM_FORMAT_XBGR16161616F:
2112         case DRM_FORMAT_ABGR16161616F:
2113         case DRM_FORMAT_XRGB16161616F:
2114         case DRM_FORMAT_ARGB16161616F:
2115                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
2116                     modifier == I915_FORMAT_MOD_X_TILED ||
2117                     modifier == I915_FORMAT_MOD_Y_TILED)
2118                         return true;
2119                 /* fall through */
2120         default:
2121                 return false;
2122         }
2123 }
2124
2125 static const struct drm_plane_funcs g4x_sprite_funcs = {
2126         .update_plane = drm_atomic_helper_update_plane,
2127         .disable_plane = drm_atomic_helper_disable_plane,
2128         .destroy = intel_plane_destroy,
2129         .atomic_get_property = intel_plane_atomic_get_property,
2130         .atomic_set_property = intel_plane_atomic_set_property,
2131         .atomic_duplicate_state = intel_plane_duplicate_state,
2132         .atomic_destroy_state = intel_plane_destroy_state,
2133         .format_mod_supported = g4x_sprite_format_mod_supported,
2134 };
2135
2136 static const struct drm_plane_funcs snb_sprite_funcs = {
2137         .update_plane = drm_atomic_helper_update_plane,
2138         .disable_plane = drm_atomic_helper_disable_plane,
2139         .destroy = intel_plane_destroy,
2140         .atomic_get_property = intel_plane_atomic_get_property,
2141         .atomic_set_property = intel_plane_atomic_set_property,
2142         .atomic_duplicate_state = intel_plane_duplicate_state,
2143         .atomic_destroy_state = intel_plane_destroy_state,
2144         .format_mod_supported = snb_sprite_format_mod_supported,
2145 };
2146
2147 static const struct drm_plane_funcs vlv_sprite_funcs = {
2148         .update_plane = drm_atomic_helper_update_plane,
2149         .disable_plane = drm_atomic_helper_disable_plane,
2150         .destroy = intel_plane_destroy,
2151         .atomic_get_property = intel_plane_atomic_get_property,
2152         .atomic_set_property = intel_plane_atomic_set_property,
2153         .atomic_duplicate_state = intel_plane_duplicate_state,
2154         .atomic_destroy_state = intel_plane_destroy_state,
2155         .format_mod_supported = vlv_sprite_format_mod_supported,
2156 };
2157
2158 static const struct drm_plane_funcs skl_plane_funcs = {
2159         .update_plane = drm_atomic_helper_update_plane,
2160         .disable_plane = drm_atomic_helper_disable_plane,
2161         .destroy = intel_plane_destroy,
2162         .atomic_get_property = intel_plane_atomic_get_property,
2163         .atomic_set_property = intel_plane_atomic_set_property,
2164         .atomic_duplicate_state = intel_plane_duplicate_state,
2165         .atomic_destroy_state = intel_plane_destroy_state,
2166         .format_mod_supported = skl_plane_format_mod_supported,
2167 };
2168
2169 static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
2170                               enum pipe pipe, enum plane_id plane_id)
2171 {
2172         if (!HAS_FBC(dev_priv))
2173                 return false;
2174
2175         return pipe == PIPE_A && plane_id == PLANE_PRIMARY;
2176 }
2177
2178 static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
2179                                  enum pipe pipe, enum plane_id plane_id)
2180 {
2181         if (INTEL_GEN(dev_priv) >= 11)
2182                 return plane_id <= PLANE_SPRITE3;
2183
2184         /* Display WA #0870: skl, bxt */
2185         if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
2186                 return false;
2187
2188         if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv) && pipe == PIPE_C)
2189                 return false;
2190
2191         if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0)
2192                 return false;
2193
2194         return true;
2195 }
2196
2197 static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
2198                               enum pipe pipe, enum plane_id plane_id)
2199 {
2200         if (plane_id == PLANE_CURSOR)
2201                 return false;
2202
2203         if (INTEL_GEN(dev_priv) >= 10)
2204                 return true;
2205
2206         if (IS_GEMINILAKE(dev_priv))
2207                 return pipe != PIPE_C;
2208
2209         return pipe != PIPE_C &&
2210                 (plane_id == PLANE_PRIMARY ||
2211                  plane_id == PLANE_SPRITE0);
2212 }
2213
2214 struct intel_plane *
2215 skl_universal_plane_create(struct drm_i915_private *dev_priv,
2216                            enum pipe pipe, enum plane_id plane_id)
2217 {
2218         struct intel_plane *plane;
2219         enum drm_plane_type plane_type;
2220         unsigned int supported_rotations;
2221         unsigned int possible_crtcs;
2222         const u64 *modifiers;
2223         const u32 *formats;
2224         int num_formats;
2225         int ret;
2226
2227         plane = intel_plane_alloc();
2228         if (IS_ERR(plane))
2229                 return plane;
2230
2231         plane->pipe = pipe;
2232         plane->id = plane_id;
2233         plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id);
2234
2235         plane->has_fbc = skl_plane_has_fbc(dev_priv, pipe, plane_id);
2236         if (plane->has_fbc) {
2237                 struct intel_fbc *fbc = &dev_priv->fbc;
2238
2239                 fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
2240         }
2241
2242         plane->max_stride = skl_plane_max_stride;
2243         plane->update_plane = skl_update_plane;
2244         plane->disable_plane = skl_disable_plane;
2245         plane->get_hw_state = skl_plane_get_hw_state;
2246         plane->check_plane = skl_plane_check;
2247         if (icl_is_nv12_y_plane(plane_id))
2248                 plane->update_slave = icl_update_slave;
2249
2250         if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
2251                 if (icl_is_hdr_plane(dev_priv, plane_id)) {
2252                         formats = icl_hdr_planar_formats;
2253                         num_formats = ARRAY_SIZE(icl_hdr_planar_formats);
2254                 } else if (INTEL_GEN(dev_priv) >= 11) {
2255                         formats = icl_planar_formats;
2256                         num_formats = ARRAY_SIZE(icl_planar_formats);
2257                 } else if (INTEL_GEN(dev_priv) == 10 || IS_GEMINILAKE(dev_priv)) {
2258                         formats = glk_planar_formats;
2259                         num_formats = ARRAY_SIZE(glk_planar_formats);
2260                 } else {
2261                         formats = skl_planar_formats;
2262                         num_formats = ARRAY_SIZE(skl_planar_formats);
2263                 }
2264         } else if (icl_is_hdr_plane(dev_priv, plane_id)) {
2265                 formats = icl_hdr_plane_formats;
2266                 num_formats = ARRAY_SIZE(icl_hdr_plane_formats);
2267         } else if (INTEL_GEN(dev_priv) >= 11) {
2268                 formats = icl_plane_formats;
2269                 num_formats = ARRAY_SIZE(icl_plane_formats);
2270         } else {
2271                 formats = skl_plane_formats;
2272                 num_formats = ARRAY_SIZE(skl_plane_formats);
2273         }
2274
2275         plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id);
2276         if (plane->has_ccs)
2277                 modifiers = skl_plane_format_modifiers_ccs;
2278         else
2279                 modifiers = skl_plane_format_modifiers_noccs;
2280
2281         if (plane_id == PLANE_PRIMARY)
2282                 plane_type = DRM_PLANE_TYPE_PRIMARY;
2283         else
2284                 plane_type = DRM_PLANE_TYPE_OVERLAY;
2285
2286         possible_crtcs = BIT(pipe);
2287
2288         ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
2289                                        possible_crtcs, &skl_plane_funcs,
2290                                        formats, num_formats, modifiers,
2291                                        plane_type,
2292                                        "plane %d%c", plane_id + 1,
2293                                        pipe_name(pipe));
2294         if (ret)
2295                 goto fail;
2296
2297         supported_rotations =
2298                 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
2299                 DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
2300
2301         if (INTEL_GEN(dev_priv) >= 10)
2302                 supported_rotations |= DRM_MODE_REFLECT_X;
2303
2304         drm_plane_create_rotation_property(&plane->base,
2305                                            DRM_MODE_ROTATE_0,
2306                                            supported_rotations);
2307
2308         drm_plane_create_color_properties(&plane->base,
2309                                           BIT(DRM_COLOR_YCBCR_BT601) |
2310                                           BIT(DRM_COLOR_YCBCR_BT709),
2311                                           BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
2312                                           BIT(DRM_COLOR_YCBCR_FULL_RANGE),
2313                                           DRM_COLOR_YCBCR_BT709,
2314                                           DRM_COLOR_YCBCR_LIMITED_RANGE);
2315
2316         drm_plane_create_alpha_property(&plane->base);
2317         drm_plane_create_blend_mode_property(&plane->base,
2318                                              BIT(DRM_MODE_BLEND_PIXEL_NONE) |
2319                                              BIT(DRM_MODE_BLEND_PREMULTI) |
2320                                              BIT(DRM_MODE_BLEND_COVERAGE));
2321
2322         drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
2323
2324         return plane;
2325
2326 fail:
2327         intel_plane_free(plane);
2328
2329         return ERR_PTR(ret);
2330 }
2331
2332 struct intel_plane *
2333 intel_sprite_plane_create(struct drm_i915_private *dev_priv,
2334                           enum pipe pipe, int sprite)
2335 {
2336         struct intel_plane *plane;
2337         const struct drm_plane_funcs *plane_funcs;
2338         unsigned long possible_crtcs;
2339         unsigned int supported_rotations;
2340         const u64 *modifiers;
2341         const u32 *formats;
2342         int num_formats;
2343         int ret;
2344
2345         if (INTEL_GEN(dev_priv) >= 9)
2346                 return skl_universal_plane_create(dev_priv, pipe,
2347                                                   PLANE_SPRITE0 + sprite);
2348
2349         plane = intel_plane_alloc();
2350         if (IS_ERR(plane))
2351                 return plane;
2352
2353         if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
2354                 plane->max_stride = i9xx_plane_max_stride;
2355                 plane->update_plane = vlv_update_plane;
2356                 plane->disable_plane = vlv_disable_plane;
2357                 plane->get_hw_state = vlv_plane_get_hw_state;
2358                 plane->check_plane = vlv_sprite_check;
2359
2360                 formats = vlv_plane_formats;
2361                 num_formats = ARRAY_SIZE(vlv_plane_formats);
2362                 modifiers = i9xx_plane_format_modifiers;
2363
2364                 plane_funcs = &vlv_sprite_funcs;
2365         } else if (INTEL_GEN(dev_priv) >= 7) {
2366                 plane->max_stride = g4x_sprite_max_stride;
2367                 plane->update_plane = ivb_update_plane;
2368                 plane->disable_plane = ivb_disable_plane;
2369                 plane->get_hw_state = ivb_plane_get_hw_state;
2370                 plane->check_plane = g4x_sprite_check;
2371
2372                 formats = snb_plane_formats;
2373                 num_formats = ARRAY_SIZE(snb_plane_formats);
2374                 modifiers = i9xx_plane_format_modifiers;
2375
2376                 plane_funcs = &snb_sprite_funcs;
2377         } else {
2378                 plane->max_stride = g4x_sprite_max_stride;
2379                 plane->update_plane = g4x_update_plane;
2380                 plane->disable_plane = g4x_disable_plane;
2381                 plane->get_hw_state = g4x_plane_get_hw_state;
2382                 plane->check_plane = g4x_sprite_check;
2383
2384                 modifiers = i9xx_plane_format_modifiers;
2385                 if (IS_GEN(dev_priv, 6)) {
2386                         formats = snb_plane_formats;
2387                         num_formats = ARRAY_SIZE(snb_plane_formats);
2388
2389                         plane_funcs = &snb_sprite_funcs;
2390                 } else {
2391                         formats = g4x_plane_formats;
2392                         num_formats = ARRAY_SIZE(g4x_plane_formats);
2393
2394                         plane_funcs = &g4x_sprite_funcs;
2395                 }
2396         }
2397
2398         if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
2399                 supported_rotations =
2400                         DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
2401                         DRM_MODE_REFLECT_X;
2402         } else {
2403                 supported_rotations =
2404                         DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
2405         }
2406
2407         plane->pipe = pipe;
2408         plane->id = PLANE_SPRITE0 + sprite;
2409         plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
2410
2411         possible_crtcs = BIT(pipe);
2412
2413         ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
2414                                        possible_crtcs, plane_funcs,
2415                                        formats, num_formats, modifiers,
2416                                        DRM_PLANE_TYPE_OVERLAY,
2417                                        "sprite %c", sprite_name(pipe, sprite));
2418         if (ret)
2419                 goto fail;
2420
2421         drm_plane_create_rotation_property(&plane->base,
2422                                            DRM_MODE_ROTATE_0,
2423                                            supported_rotations);
2424
2425         drm_plane_create_color_properties(&plane->base,
2426                                           BIT(DRM_COLOR_YCBCR_BT601) |
2427                                           BIT(DRM_COLOR_YCBCR_BT709),
2428                                           BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
2429                                           BIT(DRM_COLOR_YCBCR_FULL_RANGE),
2430                                           DRM_COLOR_YCBCR_BT709,
2431                                           DRM_COLOR_YCBCR_LIMITED_RANGE);
2432
2433         drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
2434
2435         return plane;
2436
2437 fail:
2438         intel_plane_free(plane);
2439
2440         return ERR_PTR(ret);
2441 }