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