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