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