Merge tag 'sound-5.7-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai...
[linux-2.6-microblaze.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
41 #include "i915_drv.h"
42 #include "i915_trace.h"
43 #include "i915_vgpu.h"
44 #include "intel_atomic_plane.h"
45 #include "intel_display_types.h"
46 #include "intel_frontbuffer.h"
47 #include "intel_pm.h"
48 #include "intel_psr.h"
49 #include "intel_sprite.h"
50
51 int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
52                              int usecs)
53 {
54         /* paranoia */
55         if (!adjusted_mode->crtc_htotal)
56                 return 1;
57
58         return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock,
59                             1000 * adjusted_mode->crtc_htotal);
60 }
61
62 /* FIXME: We should instead only take spinlocks once for the entire update
63  * instead of once per mmio. */
64 #if IS_ENABLED(CONFIG_PROVE_LOCKING)
65 #define VBLANK_EVASION_TIME_US 250
66 #else
67 #define VBLANK_EVASION_TIME_US 100
68 #endif
69
70 /**
71  * intel_pipe_update_start() - start update of a set of display registers
72  * @new_crtc_state: the new crtc state
73  *
74  * Mark the start of an update to pipe registers that should be updated
75  * atomically regarding vblank. If the next vblank will happens within
76  * the next 100 us, this function waits until the vblank passes.
77  *
78  * After a successful call to this function, interrupts will be disabled
79  * until a subsequent call to intel_pipe_update_end(). That is done to
80  * avoid random delays.
81  */
82 void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
83 {
84         struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
85         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
86         const struct drm_display_mode *adjusted_mode = &new_crtc_state->hw.adjusted_mode;
87         long timeout = msecs_to_jiffies_timeout(1);
88         int scanline, min, max, vblank_start;
89         wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
90         bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
91                 intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI);
92         DEFINE_WAIT(wait);
93         u32 psr_status;
94
95         vblank_start = adjusted_mode->crtc_vblank_start;
96         if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
97                 vblank_start = DIV_ROUND_UP(vblank_start, 2);
98
99         /* FIXME needs to be calibrated sensibly */
100         min = vblank_start - intel_usecs_to_scanlines(adjusted_mode,
101                                                       VBLANK_EVASION_TIME_US);
102         max = vblank_start - 1;
103
104         if (min <= 0 || max <= 0)
105                 goto irq_disable;
106
107         if (drm_WARN_ON(&dev_priv->drm, drm_crtc_vblank_get(&crtc->base)))
108                 goto irq_disable;
109
110         /*
111          * Wait for psr to idle out after enabling the VBL interrupts
112          * VBL interrupts will start the PSR exit and prevent a PSR
113          * re-entry as well.
114          */
115         if (intel_psr_wait_for_idle(new_crtc_state, &psr_status))
116                 drm_err(&dev_priv->drm,
117                         "PSR idle timed out 0x%x, atomic update may fail\n",
118                         psr_status);
119
120         local_irq_disable();
121
122         crtc->debug.min_vbl = min;
123         crtc->debug.max_vbl = max;
124         trace_intel_pipe_update_start(crtc);
125
126         for (;;) {
127                 /*
128                  * prepare_to_wait() has a memory barrier, which guarantees
129                  * other CPUs can see the task state update by the time we
130                  * read the scanline.
131                  */
132                 prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
133
134                 scanline = intel_get_crtc_scanline(crtc);
135                 if (scanline < min || scanline > max)
136                         break;
137
138                 if (!timeout) {
139                         drm_err(&dev_priv->drm,
140                                 "Potential atomic update failure on pipe %c\n",
141                                 pipe_name(crtc->pipe));
142                         break;
143                 }
144
145                 local_irq_enable();
146
147                 timeout = schedule_timeout(timeout);
148
149                 local_irq_disable();
150         }
151
152         finish_wait(wq, &wait);
153
154         drm_crtc_vblank_put(&crtc->base);
155
156         /*
157          * On VLV/CHV DSI the scanline counter would appear to
158          * increment approx. 1/3 of a scanline before start of vblank.
159          * The registers still get latched at start of vblank however.
160          * This means we must not write any registers on the first
161          * line of vblank (since not the whole line is actually in
162          * vblank). And unfortunately we can't use the interrupt to
163          * wait here since it will fire too soon. We could use the
164          * frame start interrupt instead since it will fire after the
165          * critical scanline, but that would require more changes
166          * in the interrupt code. So for now we'll just do the nasty
167          * thing and poll for the bad scanline to pass us by.
168          *
169          * FIXME figure out if BXT+ DSI suffers from this as well
170          */
171         while (need_vlv_dsi_wa && scanline == vblank_start)
172                 scanline = intel_get_crtc_scanline(crtc);
173
174         crtc->debug.scanline_start = scanline;
175         crtc->debug.start_vbl_time = ktime_get();
176         crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc);
177
178         trace_intel_pipe_update_vblank_evaded(crtc);
179         return;
180
181 irq_disable:
182         local_irq_disable();
183 }
184
185 /**
186  * intel_pipe_update_end() - end update of a set of display registers
187  * @new_crtc_state: the new crtc state
188  *
189  * Mark the end of an update started with intel_pipe_update_start(). This
190  * re-enables interrupts and verifies the update was actually completed
191  * before a vblank.
192  */
193 void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
194 {
195         struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
196         enum pipe pipe = crtc->pipe;
197         int scanline_end = intel_get_crtc_scanline(crtc);
198         u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc);
199         ktime_t end_vbl_time = ktime_get();
200         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
201
202         trace_intel_pipe_update_end(crtc, end_vbl_count, scanline_end);
203
204         /* We're still in the vblank-evade critical section, this can't race.
205          * Would be slightly nice to just grab the vblank count and arm the
206          * event outside of the critical section - the spinlock might spin for a
207          * while ... */
208         if (new_crtc_state->uapi.event) {
209                 drm_WARN_ON(&dev_priv->drm,
210                             drm_crtc_vblank_get(&crtc->base) != 0);
211
212                 spin_lock(&crtc->base.dev->event_lock);
213                 drm_crtc_arm_vblank_event(&crtc->base,
214                                           new_crtc_state->uapi.event);
215                 spin_unlock(&crtc->base.dev->event_lock);
216
217                 new_crtc_state->uapi.event = NULL;
218         }
219
220         local_irq_enable();
221
222         if (intel_vgpu_active(dev_priv))
223                 return;
224
225         if (crtc->debug.start_vbl_count &&
226             crtc->debug.start_vbl_count != end_vbl_count) {
227                 drm_err(&dev_priv->drm,
228                         "Atomic update failure on pipe %c (start=%u end=%u) time %lld us, min %d, max %d, scanline start %d, end %d\n",
229                         pipe_name(pipe), crtc->debug.start_vbl_count,
230                         end_vbl_count,
231                         ktime_us_delta(end_vbl_time,
232                                        crtc->debug.start_vbl_time),
233                         crtc->debug.min_vbl, crtc->debug.max_vbl,
234                         crtc->debug.scanline_start, scanline_end);
235         }
236 #ifdef CONFIG_DRM_I915_DEBUG_VBLANK_EVADE
237         else if (ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time) >
238                  VBLANK_EVASION_TIME_US)
239                 drm_warn(&dev_priv->drm,
240                          "Atomic update on pipe (%c) took %lld us, max time under evasion is %u us\n",
241                          pipe_name(pipe),
242                          ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
243                          VBLANK_EVASION_TIME_US);
244 #endif
245 }
246
247 int intel_plane_check_stride(const struct intel_plane_state *plane_state)
248 {
249         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
250         const struct drm_framebuffer *fb = plane_state->hw.fb;
251         unsigned int rotation = plane_state->hw.rotation;
252         u32 stride, max_stride;
253
254         /*
255          * We ignore stride for all invisible planes that
256          * can be remapped. Otherwise we could end up
257          * with a false positive when the remapping didn't
258          * kick in due the plane being invisible.
259          */
260         if (intel_plane_can_remap(plane_state) &&
261             !plane_state->uapi.visible)
262                 return 0;
263
264         /* FIXME other color planes? */
265         stride = plane_state->color_plane[0].stride;
266         max_stride = plane->max_stride(plane, fb->format->format,
267                                        fb->modifier, rotation);
268
269         if (stride > max_stride) {
270                 DRM_DEBUG_KMS("[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n",
271                               fb->base.id, stride,
272                               plane->base.base.id, plane->base.name, max_stride);
273                 return -EINVAL;
274         }
275
276         return 0;
277 }
278
279 int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
280 {
281         const struct drm_framebuffer *fb = plane_state->hw.fb;
282         struct drm_rect *src = &plane_state->uapi.src;
283         u32 src_x, src_y, src_w, src_h, hsub, vsub;
284         bool rotated = drm_rotation_90_or_270(plane_state->hw.rotation);
285
286         /*
287          * FIXME hsub/vsub vs. block size is a mess. Pre-tgl CCS
288          * abuses hsub/vsub so we can't use them here. But as they
289          * are limited to 32bpp RGB formats we don't actually need
290          * to check anything.
291          */
292         if (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
293             fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS)
294                 return 0;
295
296         /*
297          * Hardware doesn't handle subpixel coordinates.
298          * Adjust to (macro)pixel boundary, but be careful not to
299          * increase the source viewport size, because that could
300          * push the downscaling factor out of bounds.
301          */
302         src_x = src->x1 >> 16;
303         src_w = drm_rect_width(src) >> 16;
304         src_y = src->y1 >> 16;
305         src_h = drm_rect_height(src) >> 16;
306
307         drm_rect_init(src, src_x << 16, src_y << 16,
308                       src_w << 16, src_h << 16);
309
310         if (fb->format->format == DRM_FORMAT_RGB565 && rotated) {
311                 hsub = 2;
312                 vsub = 2;
313         } else {
314                 hsub = fb->format->hsub;
315                 vsub = fb->format->vsub;
316         }
317
318         if (rotated)
319                 hsub = vsub = max(hsub, vsub);
320
321         if (src_x % hsub || src_w % hsub) {
322                 DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of %u (rotated: %s)\n",
323                               src_x, src_w, hsub, yesno(rotated));
324                 return -EINVAL;
325         }
326
327         if (src_y % vsub || src_h % vsub) {
328                 DRM_DEBUG_KMS("src y/h (%u, %u) must be a multiple of %u (rotated: %s)\n",
329                               src_y, src_h, vsub, yesno(rotated));
330                 return -EINVAL;
331         }
332
333         return 0;
334 }
335
336 bool icl_is_hdr_plane(struct drm_i915_private *dev_priv, enum plane_id plane_id)
337 {
338         return INTEL_GEN(dev_priv) >= 11 &&
339                 icl_hdr_plane_mask() & BIT(plane_id);
340 }
341
342 static void
343 skl_plane_ratio(const struct intel_crtc_state *crtc_state,
344                 const struct intel_plane_state *plane_state,
345                 unsigned int *num, unsigned int *den)
346 {
347         struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev);
348         const struct drm_framebuffer *fb = plane_state->hw.fb;
349
350         if (fb->format->cpp[0] == 8) {
351                 if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv)) {
352                         *num = 10;
353                         *den = 8;
354                 } else {
355                         *num = 9;
356                         *den = 8;
357                 }
358         } else {
359                 *num = 1;
360                 *den = 1;
361         }
362 }
363
364 static int skl_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
365                                const struct intel_plane_state *plane_state)
366 {
367         struct drm_i915_private *dev_priv = to_i915(plane_state->uapi.plane->dev);
368         unsigned int num, den;
369         unsigned int pixel_rate = intel_plane_pixel_rate(crtc_state, plane_state);
370
371         skl_plane_ratio(crtc_state, plane_state, &num, &den);
372
373         /* two pixels per clock on glk+ */
374         if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
375                 den *= 2;
376
377         return DIV_ROUND_UP(pixel_rate * num, den);
378 }
379
380 static unsigned int
381 skl_plane_max_stride(struct intel_plane *plane,
382                      u32 pixel_format, u64 modifier,
383                      unsigned int rotation)
384 {
385         const struct drm_format_info *info = drm_format_info(pixel_format);
386         int cpp = info->cpp[0];
387
388         /*
389          * "The stride in bytes must not exceed the
390          * of the size of 8K pixels and 32K bytes."
391          */
392         if (drm_rotation_90_or_270(rotation))
393                 return min(8192, 32768 / cpp);
394         else
395                 return min(8192 * cpp, 32768);
396 }
397
398 static void
399 skl_program_scaler(struct intel_plane *plane,
400                    const struct intel_crtc_state *crtc_state,
401                    const struct intel_plane_state *plane_state)
402 {
403         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
404         const struct drm_framebuffer *fb = plane_state->hw.fb;
405         enum pipe pipe = plane->pipe;
406         int scaler_id = plane_state->scaler_id;
407         const struct intel_scaler *scaler =
408                 &crtc_state->scaler_state.scalers[scaler_id];
409         int crtc_x = plane_state->uapi.dst.x1;
410         int crtc_y = plane_state->uapi.dst.y1;
411         u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
412         u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
413         u16 y_hphase, uv_rgb_hphase;
414         u16 y_vphase, uv_rgb_vphase;
415         int hscale, vscale;
416
417         hscale = drm_rect_calc_hscale(&plane_state->uapi.src,
418                                       &plane_state->uapi.dst,
419                                       0, INT_MAX);
420         vscale = drm_rect_calc_vscale(&plane_state->uapi.src,
421                                       &plane_state->uapi.dst,
422                                       0, INT_MAX);
423
424         /* TODO: handle sub-pixel coordinates */
425         if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
426             !icl_is_hdr_plane(dev_priv, plane->id)) {
427                 y_hphase = skl_scaler_calc_phase(1, hscale, false);
428                 y_vphase = skl_scaler_calc_phase(1, vscale, false);
429
430                 /* MPEG2 chroma siting convention */
431                 uv_rgb_hphase = skl_scaler_calc_phase(2, hscale, true);
432                 uv_rgb_vphase = skl_scaler_calc_phase(2, vscale, false);
433         } else {
434                 /* not used */
435                 y_hphase = 0;
436                 y_vphase = 0;
437
438                 uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false);
439                 uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false);
440         }
441
442         intel_de_write_fw(dev_priv, SKL_PS_CTRL(pipe, scaler_id),
443                           PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode);
444         intel_de_write_fw(dev_priv, SKL_PS_VPHASE(pipe, scaler_id),
445                           PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
446         intel_de_write_fw(dev_priv, SKL_PS_HPHASE(pipe, scaler_id),
447                           PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
448         intel_de_write_fw(dev_priv, SKL_PS_WIN_POS(pipe, scaler_id),
449                           (crtc_x << 16) | crtc_y);
450         intel_de_write_fw(dev_priv, SKL_PS_WIN_SZ(pipe, scaler_id),
451                           (crtc_w << 16) | crtc_h);
452 }
453
454 /* Preoffset values for YUV to RGB Conversion */
455 #define PREOFF_YUV_TO_RGB_HI            0x1800
456 #define PREOFF_YUV_TO_RGB_ME            0x1F00
457 #define PREOFF_YUV_TO_RGB_LO            0x1800
458
459 #define  ROFF(x)          (((x) & 0xffff) << 16)
460 #define  GOFF(x)          (((x) & 0xffff) << 0)
461 #define  BOFF(x)          (((x) & 0xffff) << 16)
462
463 static void
464 icl_program_input_csc(struct intel_plane *plane,
465                       const struct intel_crtc_state *crtc_state,
466                       const struct intel_plane_state *plane_state)
467 {
468         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
469         enum pipe pipe = plane->pipe;
470         enum plane_id plane_id = plane->id;
471
472         static const u16 input_csc_matrix[][9] = {
473                 /*
474                  * BT.601 full range YCbCr -> full range RGB
475                  * The matrix required is :
476                  * [1.000, 0.000, 1.371,
477                  *  1.000, -0.336, -0.698,
478                  *  1.000, 1.732, 0.0000]
479                  */
480                 [DRM_COLOR_YCBCR_BT601] = {
481                         0x7AF8, 0x7800, 0x0,
482                         0x8B28, 0x7800, 0x9AC0,
483                         0x0, 0x7800, 0x7DD8,
484                 },
485                 /*
486                  * BT.709 full range YCbCr -> full range RGB
487                  * The matrix required is :
488                  * [1.000, 0.000, 1.574,
489                  *  1.000, -0.187, -0.468,
490                  *  1.000, 1.855, 0.0000]
491                  */
492                 [DRM_COLOR_YCBCR_BT709] = {
493                         0x7C98, 0x7800, 0x0,
494                         0x9EF8, 0x7800, 0xAC00,
495                         0x0, 0x7800,  0x7ED8,
496                 },
497                 /*
498                  * BT.2020 full range YCbCr -> full range RGB
499                  * The matrix required is :
500                  * [1.000, 0.000, 1.474,
501                  *  1.000, -0.1645, -0.5713,
502                  *  1.000, 1.8814, 0.0000]
503                  */
504                 [DRM_COLOR_YCBCR_BT2020] = {
505                         0x7BC8, 0x7800, 0x0,
506                         0x8928, 0x7800, 0xAA88,
507                         0x0, 0x7800, 0x7F10,
508                 },
509         };
510
511         /* Matrix for Limited Range to Full Range Conversion */
512         static const u16 input_csc_matrix_lr[][9] = {
513                 /*
514                  * BT.601 Limted range YCbCr -> full range RGB
515                  * The matrix required is :
516                  * [1.164384, 0.000, 1.596027,
517                  *  1.164384, -0.39175, -0.812813,
518                  *  1.164384, 2.017232, 0.0000]
519                  */
520                 [DRM_COLOR_YCBCR_BT601] = {
521                         0x7CC8, 0x7950, 0x0,
522                         0x8D00, 0x7950, 0x9C88,
523                         0x0, 0x7950, 0x6810,
524                 },
525                 /*
526                  * BT.709 Limited range YCbCr -> full range RGB
527                  * The matrix required is :
528                  * [1.164384, 0.000, 1.792741,
529                  *  1.164384, -0.213249, -0.532909,
530                  *  1.164384, 2.112402, 0.0000]
531                  */
532                 [DRM_COLOR_YCBCR_BT709] = {
533                         0x7E58, 0x7950, 0x0,
534                         0x8888, 0x7950, 0xADA8,
535                         0x0, 0x7950,  0x6870,
536                 },
537                 /*
538                  * BT.2020 Limited range YCbCr -> full range RGB
539                  * The matrix required is :
540                  * [1.164, 0.000, 1.678,
541                  *  1.164, -0.1873, -0.6504,
542                  *  1.164, 2.1417, 0.0000]
543                  */
544                 [DRM_COLOR_YCBCR_BT2020] = {
545                         0x7D70, 0x7950, 0x0,
546                         0x8A68, 0x7950, 0xAC00,
547                         0x0, 0x7950, 0x6890,
548                 },
549         };
550         const u16 *csc;
551
552         if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
553                 csc = input_csc_matrix[plane_state->hw.color_encoding];
554         else
555                 csc = input_csc_matrix_lr[plane_state->hw.color_encoding];
556
557         intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0),
558                           ROFF(csc[0]) | GOFF(csc[1]));
559         intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1),
560                           BOFF(csc[2]));
561         intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2),
562                           ROFF(csc[3]) | GOFF(csc[4]));
563         intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3),
564                           BOFF(csc[5]));
565         intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4),
566                           ROFF(csc[6]) | GOFF(csc[7]));
567         intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5),
568                           BOFF(csc[8]));
569
570         intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0),
571                           PREOFF_YUV_TO_RGB_HI);
572         if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
573                 intel_de_write_fw(dev_priv,
574                                   PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
575                                   0);
576         else
577                 intel_de_write_fw(dev_priv,
578                                   PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
579                                   PREOFF_YUV_TO_RGB_ME);
580         intel_de_write_fw(dev_priv, PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2),
581                           PREOFF_YUV_TO_RGB_LO);
582         intel_de_write_fw(dev_priv,
583                           PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0);
584         intel_de_write_fw(dev_priv,
585                           PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0);
586         intel_de_write_fw(dev_priv,
587                           PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0);
588 }
589
590 static void
591 skl_program_plane(struct intel_plane *plane,
592                   const struct intel_crtc_state *crtc_state,
593                   const struct intel_plane_state *plane_state,
594                   int color_plane)
595 {
596         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
597         enum plane_id plane_id = plane->id;
598         enum pipe pipe = plane->pipe;
599         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
600         u32 surf_addr = plane_state->color_plane[color_plane].offset;
601         u32 stride = skl_plane_stride(plane_state, color_plane);
602         const struct drm_framebuffer *fb = plane_state->hw.fb;
603         int aux_plane = intel_main_to_aux_plane(fb, color_plane);
604         u32 aux_dist = plane_state->color_plane[aux_plane].offset - surf_addr;
605         u32 aux_stride = skl_plane_stride(plane_state, aux_plane);
606         int crtc_x = plane_state->uapi.dst.x1;
607         int crtc_y = plane_state->uapi.dst.y1;
608         u32 x = plane_state->color_plane[color_plane].x;
609         u32 y = plane_state->color_plane[color_plane].y;
610         u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
611         u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
612         u8 alpha = plane_state->hw.alpha >> 8;
613         u32 plane_color_ctl = 0;
614         unsigned long irqflags;
615         u32 keymsk, keymax;
616         u32 plane_ctl = plane_state->ctl;
617
618         plane_ctl |= skl_plane_ctl_crtc(crtc_state);
619
620         if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
621                 plane_color_ctl = plane_state->color_ctl |
622                         glk_plane_color_ctl_crtc(crtc_state);
623
624         /* Sizes are 0 based */
625         src_w--;
626         src_h--;
627
628         keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
629
630         keymsk = key->channel_mask & 0x7ffffff;
631         if (alpha < 0xff)
632                 keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
633
634         /* The scaler will handle the output position */
635         if (plane_state->scaler_id >= 0) {
636                 crtc_x = 0;
637                 crtc_y = 0;
638         }
639
640         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
641
642         intel_de_write_fw(dev_priv, PLANE_STRIDE(pipe, plane_id), stride);
643         intel_de_write_fw(dev_priv, PLANE_POS(pipe, plane_id),
644                           (crtc_y << 16) | crtc_x);
645         intel_de_write_fw(dev_priv, PLANE_SIZE(pipe, plane_id),
646                           (src_h << 16) | src_w);
647
648         if (INTEL_GEN(dev_priv) < 12)
649                 aux_dist |= aux_stride;
650         intel_de_write_fw(dev_priv, PLANE_AUX_DIST(pipe, plane_id), aux_dist);
651
652         if (icl_is_hdr_plane(dev_priv, plane_id))
653                 intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id),
654                                   plane_state->cus_ctl);
655
656         if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
657                 intel_de_write_fw(dev_priv, PLANE_COLOR_CTL(pipe, plane_id),
658                                   plane_color_ctl);
659
660         if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id))
661                 icl_program_input_csc(plane, crtc_state, plane_state);
662
663         skl_write_plane_wm(plane, crtc_state);
664
665         intel_de_write_fw(dev_priv, PLANE_KEYVAL(pipe, plane_id),
666                           key->min_value);
667         intel_de_write_fw(dev_priv, PLANE_KEYMSK(pipe, plane_id), keymsk);
668         intel_de_write_fw(dev_priv, PLANE_KEYMAX(pipe, plane_id), keymax);
669
670         intel_de_write_fw(dev_priv, PLANE_OFFSET(pipe, plane_id),
671                           (y << 16) | x);
672
673         if (INTEL_GEN(dev_priv) < 11)
674                 intel_de_write_fw(dev_priv, PLANE_AUX_OFFSET(pipe, plane_id),
675                                   (plane_state->color_plane[1].y << 16) | plane_state->color_plane[1].x);
676
677         /*
678          * The control register self-arms if the plane was previously
679          * disabled. Try to make the plane enable atomic by writing
680          * the control register just before the surface register.
681          */
682         intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), plane_ctl);
683         intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id),
684                           intel_plane_ggtt_offset(plane_state) + surf_addr);
685
686         if (plane_state->scaler_id >= 0)
687                 skl_program_scaler(plane, crtc_state, plane_state);
688
689         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
690 }
691
692 static void
693 skl_update_plane(struct intel_plane *plane,
694                  const struct intel_crtc_state *crtc_state,
695                  const struct intel_plane_state *plane_state)
696 {
697         int color_plane = 0;
698
699         if (plane_state->planar_linked_plane && !plane_state->planar_slave)
700                 /* Program the UV plane on planar master */
701                 color_plane = 1;
702
703         skl_program_plane(plane, crtc_state, plane_state, color_plane);
704 }
705 static void
706 skl_disable_plane(struct intel_plane *plane,
707                   const struct intel_crtc_state *crtc_state)
708 {
709         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
710         enum plane_id plane_id = plane->id;
711         enum pipe pipe = plane->pipe;
712         unsigned long irqflags;
713
714         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
715
716         if (icl_is_hdr_plane(dev_priv, plane_id))
717                 intel_de_write_fw(dev_priv, PLANE_CUS_CTL(pipe, plane_id), 0);
718
719         skl_write_plane_wm(plane, crtc_state);
720
721         intel_de_write_fw(dev_priv, PLANE_CTL(pipe, plane_id), 0);
722         intel_de_write_fw(dev_priv, PLANE_SURF(pipe, plane_id), 0);
723
724         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
725 }
726
727 static bool
728 skl_plane_get_hw_state(struct intel_plane *plane,
729                        enum pipe *pipe)
730 {
731         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
732         enum intel_display_power_domain power_domain;
733         enum plane_id plane_id = plane->id;
734         intel_wakeref_t wakeref;
735         bool ret;
736
737         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
738         wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
739         if (!wakeref)
740                 return false;
741
742         ret = intel_de_read(dev_priv, PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE;
743
744         *pipe = plane->pipe;
745
746         intel_display_power_put(dev_priv, power_domain, wakeref);
747
748         return ret;
749 }
750
751 static void i9xx_plane_linear_gamma(u16 gamma[8])
752 {
753         /* The points are not evenly spaced. */
754         static const u8 in[8] = { 0, 1, 2, 4, 8, 16, 24, 32 };
755         int i;
756
757         for (i = 0; i < 8; i++)
758                 gamma[i] = (in[i] << 8) / 32;
759 }
760
761 static void
762 chv_update_csc(const struct intel_plane_state *plane_state)
763 {
764         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
765         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
766         const struct drm_framebuffer *fb = plane_state->hw.fb;
767         enum plane_id plane_id = plane->id;
768         /*
769          * |r|   | c0 c1 c2 |   |cr|
770          * |g| = | c3 c4 c5 | x |y |
771          * |b|   | c6 c7 c8 |   |cb|
772          *
773          * Coefficients are s3.12.
774          *
775          * Cb and Cr apparently come in as signed already, and
776          * we always get full range data in on account of CLRC0/1.
777          */
778         static const s16 csc_matrix[][9] = {
779                 /* BT.601 full range YCbCr -> full range RGB */
780                 [DRM_COLOR_YCBCR_BT601] = {
781                          5743, 4096,     0,
782                         -2925, 4096, -1410,
783                             0, 4096,  7258,
784                 },
785                 /* BT.709 full range YCbCr -> full range RGB */
786                 [DRM_COLOR_YCBCR_BT709] = {
787                          6450, 4096,     0,
788                         -1917, 4096,  -767,
789                             0, 4096,  7601,
790                 },
791         };
792         const s16 *csc = csc_matrix[plane_state->hw.color_encoding];
793
794         /* Seems RGB data bypasses the CSC always */
795         if (!fb->format->is_yuv)
796                 return;
797
798         intel_de_write_fw(dev_priv, SPCSCYGOFF(plane_id),
799                           SPCSC_OOFF(0) | SPCSC_IOFF(0));
800         intel_de_write_fw(dev_priv, SPCSCCBOFF(plane_id),
801                           SPCSC_OOFF(0) | SPCSC_IOFF(0));
802         intel_de_write_fw(dev_priv, SPCSCCROFF(plane_id),
803                           SPCSC_OOFF(0) | SPCSC_IOFF(0));
804
805         intel_de_write_fw(dev_priv, SPCSCC01(plane_id),
806                           SPCSC_C1(csc[1]) | SPCSC_C0(csc[0]));
807         intel_de_write_fw(dev_priv, SPCSCC23(plane_id),
808                           SPCSC_C1(csc[3]) | SPCSC_C0(csc[2]));
809         intel_de_write_fw(dev_priv, SPCSCC45(plane_id),
810                           SPCSC_C1(csc[5]) | SPCSC_C0(csc[4]));
811         intel_de_write_fw(dev_priv, SPCSCC67(plane_id),
812                           SPCSC_C1(csc[7]) | SPCSC_C0(csc[6]));
813         intel_de_write_fw(dev_priv, SPCSCC8(plane_id), SPCSC_C0(csc[8]));
814
815         intel_de_write_fw(dev_priv, SPCSCYGICLAMP(plane_id),
816                           SPCSC_IMAX(1023) | SPCSC_IMIN(0));
817         intel_de_write_fw(dev_priv, SPCSCCBICLAMP(plane_id),
818                           SPCSC_IMAX(512) | SPCSC_IMIN(-512));
819         intel_de_write_fw(dev_priv, SPCSCCRICLAMP(plane_id),
820                           SPCSC_IMAX(512) | SPCSC_IMIN(-512));
821
822         intel_de_write_fw(dev_priv, SPCSCYGOCLAMP(plane_id),
823                           SPCSC_OMAX(1023) | SPCSC_OMIN(0));
824         intel_de_write_fw(dev_priv, SPCSCCBOCLAMP(plane_id),
825                           SPCSC_OMAX(1023) | SPCSC_OMIN(0));
826         intel_de_write_fw(dev_priv, SPCSCCROCLAMP(plane_id),
827                           SPCSC_OMAX(1023) | SPCSC_OMIN(0));
828 }
829
830 #define SIN_0 0
831 #define COS_0 1
832
833 static void
834 vlv_update_clrc(const struct intel_plane_state *plane_state)
835 {
836         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
837         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
838         const struct drm_framebuffer *fb = plane_state->hw.fb;
839         enum pipe pipe = plane->pipe;
840         enum plane_id plane_id = plane->id;
841         int contrast, brightness, sh_scale, sh_sin, sh_cos;
842
843         if (fb->format->is_yuv &&
844             plane_state->hw.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) {
845                 /*
846                  * Expand limited range to full range:
847                  * Contrast is applied first and is used to expand Y range.
848                  * Brightness is applied second and is used to remove the
849                  * offset from Y. Saturation/hue is used to expand CbCr range.
850                  */
851                 contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16);
852                 brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16);
853                 sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128);
854                 sh_sin = SIN_0 * sh_scale;
855                 sh_cos = COS_0 * sh_scale;
856         } else {
857                 /* Pass-through everything. */
858                 contrast = 1 << 6;
859                 brightness = 0;
860                 sh_scale = 1 << 7;
861                 sh_sin = SIN_0 * sh_scale;
862                 sh_cos = COS_0 * sh_scale;
863         }
864
865         /* FIXME these register are single buffered :( */
866         intel_de_write_fw(dev_priv, SPCLRC0(pipe, plane_id),
867                           SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness));
868         intel_de_write_fw(dev_priv, SPCLRC1(pipe, plane_id),
869                           SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos));
870 }
871
872 static void
873 vlv_plane_ratio(const struct intel_crtc_state *crtc_state,
874                 const struct intel_plane_state *plane_state,
875                 unsigned int *num, unsigned int *den)
876 {
877         u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
878         const struct drm_framebuffer *fb = plane_state->hw.fb;
879         unsigned int cpp = fb->format->cpp[0];
880
881         /*
882          * VLV bspec only considers cases where all three planes are
883          * enabled, and cases where the primary and one sprite is enabled.
884          * Let's assume the case with just two sprites enabled also
885          * maps to the latter case.
886          */
887         if (hweight8(active_planes) == 3) {
888                 switch (cpp) {
889                 case 8:
890                         *num = 11;
891                         *den = 8;
892                         break;
893                 case 4:
894                         *num = 18;
895                         *den = 16;
896                         break;
897                 default:
898                         *num = 1;
899                         *den = 1;
900                         break;
901                 }
902         } else if (hweight8(active_planes) == 2) {
903                 switch (cpp) {
904                 case 8:
905                         *num = 10;
906                         *den = 8;
907                         break;
908                 case 4:
909                         *num = 17;
910                         *den = 16;
911                         break;
912                 default:
913                         *num = 1;
914                         *den = 1;
915                         break;
916                 }
917         } else {
918                 switch (cpp) {
919                 case 8:
920                         *num = 10;
921                         *den = 8;
922                         break;
923                 default:
924                         *num = 1;
925                         *den = 1;
926                         break;
927                 }
928         }
929 }
930
931 int vlv_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
932                         const struct intel_plane_state *plane_state)
933 {
934         unsigned int pixel_rate;
935         unsigned int num, den;
936
937         /*
938          * Note that crtc_state->pixel_rate accounts for both
939          * horizontal and vertical panel fitter downscaling factors.
940          * Pre-HSW bspec tells us to only consider the horizontal
941          * downscaling factor here. We ignore that and just consider
942          * both for simplicity.
943          */
944         pixel_rate = crtc_state->pixel_rate;
945
946         vlv_plane_ratio(crtc_state, plane_state, &num, &den);
947
948         return DIV_ROUND_UP(pixel_rate * num, den);
949 }
950
951 static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
952 {
953         u32 sprctl = 0;
954
955         if (crtc_state->gamma_enable)
956                 sprctl |= SP_GAMMA_ENABLE;
957
958         return sprctl;
959 }
960
961 static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state,
962                           const struct intel_plane_state *plane_state)
963 {
964         const struct drm_framebuffer *fb = plane_state->hw.fb;
965         unsigned int rotation = plane_state->hw.rotation;
966         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
967         u32 sprctl;
968
969         sprctl = SP_ENABLE;
970
971         switch (fb->format->format) {
972         case DRM_FORMAT_YUYV:
973                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
974                 break;
975         case DRM_FORMAT_YVYU:
976                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
977                 break;
978         case DRM_FORMAT_UYVY:
979                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
980                 break;
981         case DRM_FORMAT_VYUY:
982                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
983                 break;
984         case DRM_FORMAT_C8:
985                 sprctl |= SP_FORMAT_8BPP;
986                 break;
987         case DRM_FORMAT_RGB565:
988                 sprctl |= SP_FORMAT_BGR565;
989                 break;
990         case DRM_FORMAT_XRGB8888:
991                 sprctl |= SP_FORMAT_BGRX8888;
992                 break;
993         case DRM_FORMAT_ARGB8888:
994                 sprctl |= SP_FORMAT_BGRA8888;
995                 break;
996         case DRM_FORMAT_XBGR2101010:
997                 sprctl |= SP_FORMAT_RGBX1010102;
998                 break;
999         case DRM_FORMAT_ABGR2101010:
1000                 sprctl |= SP_FORMAT_RGBA1010102;
1001                 break;
1002         case DRM_FORMAT_XRGB2101010:
1003                 sprctl |= SP_FORMAT_BGRX1010102;
1004                 break;
1005         case DRM_FORMAT_ARGB2101010:
1006                 sprctl |= SP_FORMAT_BGRA1010102;
1007                 break;
1008         case DRM_FORMAT_XBGR8888:
1009                 sprctl |= SP_FORMAT_RGBX8888;
1010                 break;
1011         case DRM_FORMAT_ABGR8888:
1012                 sprctl |= SP_FORMAT_RGBA8888;
1013                 break;
1014         default:
1015                 MISSING_CASE(fb->format->format);
1016                 return 0;
1017         }
1018
1019         if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
1020                 sprctl |= SP_YUV_FORMAT_BT709;
1021
1022         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
1023                 sprctl |= SP_TILED;
1024
1025         if (rotation & DRM_MODE_ROTATE_180)
1026                 sprctl |= SP_ROTATE_180;
1027
1028         if (rotation & DRM_MODE_REFLECT_X)
1029                 sprctl |= SP_MIRROR;
1030
1031         if (key->flags & I915_SET_COLORKEY_SOURCE)
1032                 sprctl |= SP_SOURCE_KEY;
1033
1034         return sprctl;
1035 }
1036
1037 static void vlv_update_gamma(const struct intel_plane_state *plane_state)
1038 {
1039         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1040         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1041         const struct drm_framebuffer *fb = plane_state->hw.fb;
1042         enum pipe pipe = plane->pipe;
1043         enum plane_id plane_id = plane->id;
1044         u16 gamma[8];
1045         int i;
1046
1047         /* Seems RGB data bypasses the gamma always */
1048         if (!fb->format->is_yuv)
1049                 return;
1050
1051         i9xx_plane_linear_gamma(gamma);
1052
1053         /* FIXME these register are single buffered :( */
1054         /* The two end points are implicit (0.0 and 1.0) */
1055         for (i = 1; i < 8 - 1; i++)
1056                 intel_de_write_fw(dev_priv, SPGAMC(pipe, plane_id, i - 1),
1057                                   gamma[i] << 16 | gamma[i] << 8 | gamma[i]);
1058 }
1059
1060 static void
1061 vlv_update_plane(struct intel_plane *plane,
1062                  const struct intel_crtc_state *crtc_state,
1063                  const struct intel_plane_state *plane_state)
1064 {
1065         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1066         enum pipe pipe = plane->pipe;
1067         enum plane_id plane_id = plane->id;
1068         u32 sprsurf_offset = plane_state->color_plane[0].offset;
1069         u32 linear_offset;
1070         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1071         int crtc_x = plane_state->uapi.dst.x1;
1072         int crtc_y = plane_state->uapi.dst.y1;
1073         u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
1074         u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
1075         u32 x = plane_state->color_plane[0].x;
1076         u32 y = plane_state->color_plane[0].y;
1077         unsigned long irqflags;
1078         u32 sprctl;
1079
1080         sprctl = plane_state->ctl | vlv_sprite_ctl_crtc(crtc_state);
1081
1082         /* Sizes are 0 based */
1083         crtc_w--;
1084         crtc_h--;
1085
1086         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
1087
1088         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1089
1090         intel_de_write_fw(dev_priv, SPSTRIDE(pipe, plane_id),
1091                           plane_state->color_plane[0].stride);
1092         intel_de_write_fw(dev_priv, SPPOS(pipe, plane_id),
1093                           (crtc_y << 16) | crtc_x);
1094         intel_de_write_fw(dev_priv, SPSIZE(pipe, plane_id),
1095                           (crtc_h << 16) | crtc_w);
1096         intel_de_write_fw(dev_priv, SPCONSTALPHA(pipe, plane_id), 0);
1097
1098         if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
1099                 chv_update_csc(plane_state);
1100
1101         if (key->flags) {
1102                 intel_de_write_fw(dev_priv, SPKEYMINVAL(pipe, plane_id),
1103                                   key->min_value);
1104                 intel_de_write_fw(dev_priv, SPKEYMSK(pipe, plane_id),
1105                                   key->channel_mask);
1106                 intel_de_write_fw(dev_priv, SPKEYMAXVAL(pipe, plane_id),
1107                                   key->max_value);
1108         }
1109
1110         intel_de_write_fw(dev_priv, SPLINOFF(pipe, plane_id), linear_offset);
1111         intel_de_write_fw(dev_priv, SPTILEOFF(pipe, plane_id), (y << 16) | x);
1112
1113         /*
1114          * The control register self-arms if the plane was previously
1115          * disabled. Try to make the plane enable atomic by writing
1116          * the control register just before the surface register.
1117          */
1118         intel_de_write_fw(dev_priv, SPCNTR(pipe, plane_id), sprctl);
1119         intel_de_write_fw(dev_priv, SPSURF(pipe, plane_id),
1120                           intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
1121
1122         vlv_update_clrc(plane_state);
1123         vlv_update_gamma(plane_state);
1124
1125         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1126 }
1127
1128 static void
1129 vlv_disable_plane(struct intel_plane *plane,
1130                   const struct intel_crtc_state *crtc_state)
1131 {
1132         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1133         enum pipe pipe = plane->pipe;
1134         enum plane_id plane_id = plane->id;
1135         unsigned long irqflags;
1136
1137         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1138
1139         intel_de_write_fw(dev_priv, SPCNTR(pipe, plane_id), 0);
1140         intel_de_write_fw(dev_priv, SPSURF(pipe, plane_id), 0);
1141
1142         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1143 }
1144
1145 static bool
1146 vlv_plane_get_hw_state(struct intel_plane *plane,
1147                        enum pipe *pipe)
1148 {
1149         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1150         enum intel_display_power_domain power_domain;
1151         enum plane_id plane_id = plane->id;
1152         intel_wakeref_t wakeref;
1153         bool ret;
1154
1155         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
1156         wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
1157         if (!wakeref)
1158                 return false;
1159
1160         ret = intel_de_read(dev_priv, SPCNTR(plane->pipe, plane_id)) & SP_ENABLE;
1161
1162         *pipe = plane->pipe;
1163
1164         intel_display_power_put(dev_priv, power_domain, wakeref);
1165
1166         return ret;
1167 }
1168
1169 static void ivb_plane_ratio(const struct intel_crtc_state *crtc_state,
1170                             const struct intel_plane_state *plane_state,
1171                             unsigned int *num, unsigned int *den)
1172 {
1173         u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
1174         const struct drm_framebuffer *fb = plane_state->hw.fb;
1175         unsigned int cpp = fb->format->cpp[0];
1176
1177         if (hweight8(active_planes) == 2) {
1178                 switch (cpp) {
1179                 case 8:
1180                         *num = 10;
1181                         *den = 8;
1182                         break;
1183                 case 4:
1184                         *num = 17;
1185                         *den = 16;
1186                         break;
1187                 default:
1188                         *num = 1;
1189                         *den = 1;
1190                         break;
1191                 }
1192         } else {
1193                 switch (cpp) {
1194                 case 8:
1195                         *num = 9;
1196                         *den = 8;
1197                         break;
1198                 default:
1199                         *num = 1;
1200                         *den = 1;
1201                         break;
1202                 }
1203         }
1204 }
1205
1206 static void ivb_plane_ratio_scaling(const struct intel_crtc_state *crtc_state,
1207                                     const struct intel_plane_state *plane_state,
1208                                     unsigned int *num, unsigned int *den)
1209 {
1210         const struct drm_framebuffer *fb = plane_state->hw.fb;
1211         unsigned int cpp = fb->format->cpp[0];
1212
1213         switch (cpp) {
1214         case 8:
1215                 *num = 12;
1216                 *den = 8;
1217                 break;
1218         case 4:
1219                 *num = 19;
1220                 *den = 16;
1221                 break;
1222         case 2:
1223                 *num = 33;
1224                 *den = 32;
1225                 break;
1226         default:
1227                 *num = 1;
1228                 *den = 1;
1229                 break;
1230         }
1231 }
1232
1233 int ivb_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
1234                         const struct intel_plane_state *plane_state)
1235 {
1236         unsigned int pixel_rate;
1237         unsigned int num, den;
1238
1239         /*
1240          * Note that crtc_state->pixel_rate accounts for both
1241          * horizontal and vertical panel fitter downscaling factors.
1242          * Pre-HSW bspec tells us to only consider the horizontal
1243          * downscaling factor here. We ignore that and just consider
1244          * both for simplicity.
1245          */
1246         pixel_rate = crtc_state->pixel_rate;
1247
1248         ivb_plane_ratio(crtc_state, plane_state, &num, &den);
1249
1250         return DIV_ROUND_UP(pixel_rate * num, den);
1251 }
1252
1253 static int ivb_sprite_min_cdclk(const struct intel_crtc_state *crtc_state,
1254                                 const struct intel_plane_state *plane_state)
1255 {
1256         unsigned int src_w, dst_w, pixel_rate;
1257         unsigned int num, den;
1258
1259         /*
1260          * Note that crtc_state->pixel_rate accounts for both
1261          * horizontal and vertical panel fitter downscaling factors.
1262          * Pre-HSW bspec tells us to only consider the horizontal
1263          * downscaling factor here. We ignore that and just consider
1264          * both for simplicity.
1265          */
1266         pixel_rate = crtc_state->pixel_rate;
1267
1268         src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
1269         dst_w = drm_rect_width(&plane_state->uapi.dst);
1270
1271         if (src_w != dst_w)
1272                 ivb_plane_ratio_scaling(crtc_state, plane_state, &num, &den);
1273         else
1274                 ivb_plane_ratio(crtc_state, plane_state, &num, &den);
1275
1276         /* Horizontal downscaling limits the maximum pixel rate */
1277         dst_w = min(src_w, dst_w);
1278
1279         return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, num * src_w),
1280                                 den * dst_w);
1281 }
1282
1283 static void hsw_plane_ratio(const struct intel_crtc_state *crtc_state,
1284                             const struct intel_plane_state *plane_state,
1285                             unsigned int *num, unsigned int *den)
1286 {
1287         u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
1288         const struct drm_framebuffer *fb = plane_state->hw.fb;
1289         unsigned int cpp = fb->format->cpp[0];
1290
1291         if (hweight8(active_planes) == 2) {
1292                 switch (cpp) {
1293                 case 8:
1294                         *num = 10;
1295                         *den = 8;
1296                         break;
1297                 default:
1298                         *num = 1;
1299                         *den = 1;
1300                         break;
1301                 }
1302         } else {
1303                 switch (cpp) {
1304                 case 8:
1305                         *num = 9;
1306                         *den = 8;
1307                         break;
1308                 default:
1309                         *num = 1;
1310                         *den = 1;
1311                         break;
1312                 }
1313         }
1314 }
1315
1316 int hsw_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
1317                         const struct intel_plane_state *plane_state)
1318 {
1319         unsigned int pixel_rate = crtc_state->pixel_rate;
1320         unsigned int num, den;
1321
1322         hsw_plane_ratio(crtc_state, plane_state, &num, &den);
1323
1324         return DIV_ROUND_UP(pixel_rate * num, den);
1325 }
1326
1327 static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
1328 {
1329         u32 sprctl = 0;
1330
1331         if (crtc_state->gamma_enable)
1332                 sprctl |= SPRITE_GAMMA_ENABLE;
1333
1334         if (crtc_state->csc_enable)
1335                 sprctl |= SPRITE_PIPE_CSC_ENABLE;
1336
1337         return sprctl;
1338 }
1339
1340 static bool ivb_need_sprite_gamma(const struct intel_plane_state *plane_state)
1341 {
1342         struct drm_i915_private *dev_priv =
1343                 to_i915(plane_state->uapi.plane->dev);
1344         const struct drm_framebuffer *fb = plane_state->hw.fb;
1345
1346         return fb->format->cpp[0] == 8 &&
1347                 (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv));
1348 }
1349
1350 static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
1351                           const struct intel_plane_state *plane_state)
1352 {
1353         struct drm_i915_private *dev_priv =
1354                 to_i915(plane_state->uapi.plane->dev);
1355         const struct drm_framebuffer *fb = plane_state->hw.fb;
1356         unsigned int rotation = plane_state->hw.rotation;
1357         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1358         u32 sprctl;
1359
1360         sprctl = SPRITE_ENABLE;
1361
1362         if (IS_IVYBRIDGE(dev_priv))
1363                 sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
1364
1365         switch (fb->format->format) {
1366         case DRM_FORMAT_XBGR8888:
1367                 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
1368                 break;
1369         case DRM_FORMAT_XRGB8888:
1370                 sprctl |= SPRITE_FORMAT_RGBX888;
1371                 break;
1372         case DRM_FORMAT_XBGR2101010:
1373                 sprctl |= SPRITE_FORMAT_RGBX101010 | SPRITE_RGB_ORDER_RGBX;
1374                 break;
1375         case DRM_FORMAT_XRGB2101010:
1376                 sprctl |= SPRITE_FORMAT_RGBX101010;
1377                 break;
1378         case DRM_FORMAT_XBGR16161616F:
1379                 sprctl |= SPRITE_FORMAT_RGBX161616 | SPRITE_RGB_ORDER_RGBX;
1380                 break;
1381         case DRM_FORMAT_XRGB16161616F:
1382                 sprctl |= SPRITE_FORMAT_RGBX161616;
1383                 break;
1384         case DRM_FORMAT_YUYV:
1385                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
1386                 break;
1387         case DRM_FORMAT_YVYU:
1388                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
1389                 break;
1390         case DRM_FORMAT_UYVY:
1391                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
1392                 break;
1393         case DRM_FORMAT_VYUY:
1394                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
1395                 break;
1396         default:
1397                 MISSING_CASE(fb->format->format);
1398                 return 0;
1399         }
1400
1401         if (!ivb_need_sprite_gamma(plane_state))
1402                 sprctl |= SPRITE_INT_GAMMA_DISABLE;
1403
1404         if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
1405                 sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
1406
1407         if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
1408                 sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE;
1409
1410         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
1411                 sprctl |= SPRITE_TILED;
1412
1413         if (rotation & DRM_MODE_ROTATE_180)
1414                 sprctl |= SPRITE_ROTATE_180;
1415
1416         if (key->flags & I915_SET_COLORKEY_DESTINATION)
1417                 sprctl |= SPRITE_DEST_KEY;
1418         else if (key->flags & I915_SET_COLORKEY_SOURCE)
1419                 sprctl |= SPRITE_SOURCE_KEY;
1420
1421         return sprctl;
1422 }
1423
1424 static void ivb_sprite_linear_gamma(const struct intel_plane_state *plane_state,
1425                                     u16 gamma[18])
1426 {
1427         int scale, i;
1428
1429         /*
1430          * WaFP16GammaEnabling:ivb,hsw
1431          * "Workaround : When using the 64-bit format, the sprite output
1432          *  on each color channel has one quarter amplitude. It can be
1433          *  brought up to full amplitude by using sprite internal gamma
1434          *  correction, pipe gamma correction, or pipe color space
1435          *  conversion to multiply the sprite output by four."
1436          */
1437         scale = 4;
1438
1439         for (i = 0; i < 16; i++)
1440                 gamma[i] = min((scale * i << 10) / 16, (1 << 10) - 1);
1441
1442         gamma[i] = min((scale * i << 10) / 16, 1 << 10);
1443         i++;
1444
1445         gamma[i] = 3 << 10;
1446         i++;
1447 }
1448
1449 static void ivb_update_gamma(const struct intel_plane_state *plane_state)
1450 {
1451         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1452         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1453         enum pipe pipe = plane->pipe;
1454         u16 gamma[18];
1455         int i;
1456
1457         if (!ivb_need_sprite_gamma(plane_state))
1458                 return;
1459
1460         ivb_sprite_linear_gamma(plane_state, gamma);
1461
1462         /* FIXME these register are single buffered :( */
1463         for (i = 0; i < 16; i++)
1464                 intel_de_write_fw(dev_priv, SPRGAMC(pipe, i),
1465                                   gamma[i] << 20 | gamma[i] << 10 | gamma[i]);
1466
1467         intel_de_write_fw(dev_priv, SPRGAMC16(pipe, 0), gamma[i]);
1468         intel_de_write_fw(dev_priv, SPRGAMC16(pipe, 1), gamma[i]);
1469         intel_de_write_fw(dev_priv, SPRGAMC16(pipe, 2), gamma[i]);
1470         i++;
1471
1472         intel_de_write_fw(dev_priv, SPRGAMC17(pipe, 0), gamma[i]);
1473         intel_de_write_fw(dev_priv, SPRGAMC17(pipe, 1), gamma[i]);
1474         intel_de_write_fw(dev_priv, SPRGAMC17(pipe, 2), gamma[i]);
1475         i++;
1476 }
1477
1478 static void
1479 ivb_update_plane(struct intel_plane *plane,
1480                  const struct intel_crtc_state *crtc_state,
1481                  const struct intel_plane_state *plane_state)
1482 {
1483         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1484         enum pipe pipe = plane->pipe;
1485         u32 sprsurf_offset = plane_state->color_plane[0].offset;
1486         u32 linear_offset;
1487         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1488         int crtc_x = plane_state->uapi.dst.x1;
1489         int crtc_y = plane_state->uapi.dst.y1;
1490         u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
1491         u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
1492         u32 x = plane_state->color_plane[0].x;
1493         u32 y = plane_state->color_plane[0].y;
1494         u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
1495         u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
1496         u32 sprctl, sprscale = 0;
1497         unsigned long irqflags;
1498
1499         sprctl = plane_state->ctl | ivb_sprite_ctl_crtc(crtc_state);
1500
1501         /* Sizes are 0 based */
1502         src_w--;
1503         src_h--;
1504         crtc_w--;
1505         crtc_h--;
1506
1507         if (crtc_w != src_w || crtc_h != src_h)
1508                 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
1509
1510         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
1511
1512         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1513
1514         intel_de_write_fw(dev_priv, SPRSTRIDE(pipe),
1515                           plane_state->color_plane[0].stride);
1516         intel_de_write_fw(dev_priv, SPRPOS(pipe), (crtc_y << 16) | crtc_x);
1517         intel_de_write_fw(dev_priv, SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
1518         if (IS_IVYBRIDGE(dev_priv))
1519                 intel_de_write_fw(dev_priv, SPRSCALE(pipe), sprscale);
1520
1521         if (key->flags) {
1522                 intel_de_write_fw(dev_priv, SPRKEYVAL(pipe), key->min_value);
1523                 intel_de_write_fw(dev_priv, SPRKEYMSK(pipe),
1524                                   key->channel_mask);
1525                 intel_de_write_fw(dev_priv, SPRKEYMAX(pipe), key->max_value);
1526         }
1527
1528         /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
1529          * register */
1530         if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
1531                 intel_de_write_fw(dev_priv, SPROFFSET(pipe), (y << 16) | x);
1532         } else {
1533                 intel_de_write_fw(dev_priv, SPRLINOFF(pipe), linear_offset);
1534                 intel_de_write_fw(dev_priv, SPRTILEOFF(pipe), (y << 16) | x);
1535         }
1536
1537         /*
1538          * The control register self-arms if the plane was previously
1539          * disabled. Try to make the plane enable atomic by writing
1540          * the control register just before the surface register.
1541          */
1542         intel_de_write_fw(dev_priv, SPRCTL(pipe), sprctl);
1543         intel_de_write_fw(dev_priv, SPRSURF(pipe),
1544                           intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
1545
1546         ivb_update_gamma(plane_state);
1547
1548         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1549 }
1550
1551 static void
1552 ivb_disable_plane(struct intel_plane *plane,
1553                   const struct intel_crtc_state *crtc_state)
1554 {
1555         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1556         enum pipe pipe = plane->pipe;
1557         unsigned long irqflags;
1558
1559         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1560
1561         intel_de_write_fw(dev_priv, SPRCTL(pipe), 0);
1562         /* Disable the scaler */
1563         if (IS_IVYBRIDGE(dev_priv))
1564                 intel_de_write_fw(dev_priv, SPRSCALE(pipe), 0);
1565         intel_de_write_fw(dev_priv, SPRSURF(pipe), 0);
1566
1567         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1568 }
1569
1570 static bool
1571 ivb_plane_get_hw_state(struct intel_plane *plane,
1572                        enum pipe *pipe)
1573 {
1574         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1575         enum intel_display_power_domain power_domain;
1576         intel_wakeref_t wakeref;
1577         bool ret;
1578
1579         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
1580         wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
1581         if (!wakeref)
1582                 return false;
1583
1584         ret =  intel_de_read(dev_priv, SPRCTL(plane->pipe)) & SPRITE_ENABLE;
1585
1586         *pipe = plane->pipe;
1587
1588         intel_display_power_put(dev_priv, power_domain, wakeref);
1589
1590         return ret;
1591 }
1592
1593 static int g4x_sprite_min_cdclk(const struct intel_crtc_state *crtc_state,
1594                                 const struct intel_plane_state *plane_state)
1595 {
1596         const struct drm_framebuffer *fb = plane_state->hw.fb;
1597         unsigned int hscale, pixel_rate;
1598         unsigned int limit, decimate;
1599
1600         /*
1601          * Note that crtc_state->pixel_rate accounts for both
1602          * horizontal and vertical panel fitter downscaling factors.
1603          * Pre-HSW bspec tells us to only consider the horizontal
1604          * downscaling factor here. We ignore that and just consider
1605          * both for simplicity.
1606          */
1607         pixel_rate = crtc_state->pixel_rate;
1608
1609         /* Horizontal downscaling limits the maximum pixel rate */
1610         hscale = drm_rect_calc_hscale(&plane_state->uapi.src,
1611                                       &plane_state->uapi.dst,
1612                                       0, INT_MAX);
1613         if (hscale < 0x10000)
1614                 return pixel_rate;
1615
1616         /* Decimation steps at 2x,4x,8x,16x */
1617         decimate = ilog2(hscale >> 16);
1618         hscale >>= decimate;
1619
1620         /* Starting limit is 90% of cdclk */
1621         limit = 9;
1622
1623         /* -10% per decimation step */
1624         limit -= decimate;
1625
1626         /* -10% for RGB */
1627         if (fb->format->cpp[0] >= 4)
1628                 limit--; /* -10% for RGB */
1629
1630         /*
1631          * We should also do -10% if sprite scaling is enabled
1632          * on the other pipe, but we can't really check for that,
1633          * so we ignore it.
1634          */
1635
1636         return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, 10 * hscale),
1637                                 limit << 16);
1638 }
1639
1640 static unsigned int
1641 g4x_sprite_max_stride(struct intel_plane *plane,
1642                       u32 pixel_format, u64 modifier,
1643                       unsigned int rotation)
1644 {
1645         return 16384;
1646 }
1647
1648 static u32 g4x_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
1649 {
1650         u32 dvscntr = 0;
1651
1652         if (crtc_state->gamma_enable)
1653                 dvscntr |= DVS_GAMMA_ENABLE;
1654
1655         if (crtc_state->csc_enable)
1656                 dvscntr |= DVS_PIPE_CSC_ENABLE;
1657
1658         return dvscntr;
1659 }
1660
1661 static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state,
1662                           const struct intel_plane_state *plane_state)
1663 {
1664         struct drm_i915_private *dev_priv =
1665                 to_i915(plane_state->uapi.plane->dev);
1666         const struct drm_framebuffer *fb = plane_state->hw.fb;
1667         unsigned int rotation = plane_state->hw.rotation;
1668         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1669         u32 dvscntr;
1670
1671         dvscntr = DVS_ENABLE;
1672
1673         if (IS_GEN(dev_priv, 6))
1674                 dvscntr |= DVS_TRICKLE_FEED_DISABLE;
1675
1676         switch (fb->format->format) {
1677         case DRM_FORMAT_XBGR8888:
1678                 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
1679                 break;
1680         case DRM_FORMAT_XRGB8888:
1681                 dvscntr |= DVS_FORMAT_RGBX888;
1682                 break;
1683         case DRM_FORMAT_XBGR2101010:
1684                 dvscntr |= DVS_FORMAT_RGBX101010 | DVS_RGB_ORDER_XBGR;
1685                 break;
1686         case DRM_FORMAT_XRGB2101010:
1687                 dvscntr |= DVS_FORMAT_RGBX101010;
1688                 break;
1689         case DRM_FORMAT_XBGR16161616F:
1690                 dvscntr |= DVS_FORMAT_RGBX161616 | DVS_RGB_ORDER_XBGR;
1691                 break;
1692         case DRM_FORMAT_XRGB16161616F:
1693                 dvscntr |= DVS_FORMAT_RGBX161616;
1694                 break;
1695         case DRM_FORMAT_YUYV:
1696                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
1697                 break;
1698         case DRM_FORMAT_YVYU:
1699                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
1700                 break;
1701         case DRM_FORMAT_UYVY:
1702                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
1703                 break;
1704         case DRM_FORMAT_VYUY:
1705                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
1706                 break;
1707         default:
1708                 MISSING_CASE(fb->format->format);
1709                 return 0;
1710         }
1711
1712         if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
1713                 dvscntr |= DVS_YUV_FORMAT_BT709;
1714
1715         if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
1716                 dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE;
1717
1718         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
1719                 dvscntr |= DVS_TILED;
1720
1721         if (rotation & DRM_MODE_ROTATE_180)
1722                 dvscntr |= DVS_ROTATE_180;
1723
1724         if (key->flags & I915_SET_COLORKEY_DESTINATION)
1725                 dvscntr |= DVS_DEST_KEY;
1726         else if (key->flags & I915_SET_COLORKEY_SOURCE)
1727                 dvscntr |= DVS_SOURCE_KEY;
1728
1729         return dvscntr;
1730 }
1731
1732 static void g4x_update_gamma(const struct intel_plane_state *plane_state)
1733 {
1734         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1735         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1736         const struct drm_framebuffer *fb = plane_state->hw.fb;
1737         enum pipe pipe = plane->pipe;
1738         u16 gamma[8];
1739         int i;
1740
1741         /* Seems RGB data bypasses the gamma always */
1742         if (!fb->format->is_yuv)
1743                 return;
1744
1745         i9xx_plane_linear_gamma(gamma);
1746
1747         /* FIXME these register are single buffered :( */
1748         /* The two end points are implicit (0.0 and 1.0) */
1749         for (i = 1; i < 8 - 1; i++)
1750                 intel_de_write_fw(dev_priv, DVSGAMC_G4X(pipe, i - 1),
1751                                   gamma[i] << 16 | gamma[i] << 8 | gamma[i]);
1752 }
1753
1754 static void ilk_sprite_linear_gamma(u16 gamma[17])
1755 {
1756         int i;
1757
1758         for (i = 0; i < 17; i++)
1759                 gamma[i] = (i << 10) / 16;
1760 }
1761
1762 static void ilk_update_gamma(const struct intel_plane_state *plane_state)
1763 {
1764         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1765         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1766         const struct drm_framebuffer *fb = plane_state->hw.fb;
1767         enum pipe pipe = plane->pipe;
1768         u16 gamma[17];
1769         int i;
1770
1771         /* Seems RGB data bypasses the gamma always */
1772         if (!fb->format->is_yuv)
1773                 return;
1774
1775         ilk_sprite_linear_gamma(gamma);
1776
1777         /* FIXME these register are single buffered :( */
1778         for (i = 0; i < 16; i++)
1779                 intel_de_write_fw(dev_priv, DVSGAMC_ILK(pipe, i),
1780                                   gamma[i] << 20 | gamma[i] << 10 | gamma[i]);
1781
1782         intel_de_write_fw(dev_priv, DVSGAMCMAX_ILK(pipe, 0), gamma[i]);
1783         intel_de_write_fw(dev_priv, DVSGAMCMAX_ILK(pipe, 1), gamma[i]);
1784         intel_de_write_fw(dev_priv, DVSGAMCMAX_ILK(pipe, 2), gamma[i]);
1785         i++;
1786 }
1787
1788 static void
1789 g4x_update_plane(struct intel_plane *plane,
1790                  const struct intel_crtc_state *crtc_state,
1791                  const struct intel_plane_state *plane_state)
1792 {
1793         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1794         enum pipe pipe = plane->pipe;
1795         u32 dvssurf_offset = plane_state->color_plane[0].offset;
1796         u32 linear_offset;
1797         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1798         int crtc_x = plane_state->uapi.dst.x1;
1799         int crtc_y = plane_state->uapi.dst.y1;
1800         u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
1801         u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
1802         u32 x = plane_state->color_plane[0].x;
1803         u32 y = plane_state->color_plane[0].y;
1804         u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
1805         u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
1806         u32 dvscntr, dvsscale = 0;
1807         unsigned long irqflags;
1808
1809         dvscntr = plane_state->ctl | g4x_sprite_ctl_crtc(crtc_state);
1810
1811         /* Sizes are 0 based */
1812         src_w--;
1813         src_h--;
1814         crtc_w--;
1815         crtc_h--;
1816
1817         if (crtc_w != src_w || crtc_h != src_h)
1818                 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
1819
1820         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
1821
1822         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1823
1824         intel_de_write_fw(dev_priv, DVSSTRIDE(pipe),
1825                           plane_state->color_plane[0].stride);
1826         intel_de_write_fw(dev_priv, DVSPOS(pipe), (crtc_y << 16) | crtc_x);
1827         intel_de_write_fw(dev_priv, DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
1828         intel_de_write_fw(dev_priv, DVSSCALE(pipe), dvsscale);
1829
1830         if (key->flags) {
1831                 intel_de_write_fw(dev_priv, DVSKEYVAL(pipe), key->min_value);
1832                 intel_de_write_fw(dev_priv, DVSKEYMSK(pipe),
1833                                   key->channel_mask);
1834                 intel_de_write_fw(dev_priv, DVSKEYMAX(pipe), key->max_value);
1835         }
1836
1837         intel_de_write_fw(dev_priv, DVSLINOFF(pipe), linear_offset);
1838         intel_de_write_fw(dev_priv, DVSTILEOFF(pipe), (y << 16) | x);
1839
1840         /*
1841          * The control register self-arms if the plane was previously
1842          * disabled. Try to make the plane enable atomic by writing
1843          * the control register just before the surface register.
1844          */
1845         intel_de_write_fw(dev_priv, DVSCNTR(pipe), dvscntr);
1846         intel_de_write_fw(dev_priv, DVSSURF(pipe),
1847                           intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
1848
1849         if (IS_G4X(dev_priv))
1850                 g4x_update_gamma(plane_state);
1851         else
1852                 ilk_update_gamma(plane_state);
1853
1854         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1855 }
1856
1857 static void
1858 g4x_disable_plane(struct intel_plane *plane,
1859                   const struct intel_crtc_state *crtc_state)
1860 {
1861         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1862         enum pipe pipe = plane->pipe;
1863         unsigned long irqflags;
1864
1865         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1866
1867         intel_de_write_fw(dev_priv, DVSCNTR(pipe), 0);
1868         /* Disable the scaler */
1869         intel_de_write_fw(dev_priv, DVSSCALE(pipe), 0);
1870         intel_de_write_fw(dev_priv, DVSSURF(pipe), 0);
1871
1872         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1873 }
1874
1875 static bool
1876 g4x_plane_get_hw_state(struct intel_plane *plane,
1877                        enum pipe *pipe)
1878 {
1879         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1880         enum intel_display_power_domain power_domain;
1881         intel_wakeref_t wakeref;
1882         bool ret;
1883
1884         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
1885         wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
1886         if (!wakeref)
1887                 return false;
1888
1889         ret = intel_de_read(dev_priv, DVSCNTR(plane->pipe)) & DVS_ENABLE;
1890
1891         *pipe = plane->pipe;
1892
1893         intel_display_power_put(dev_priv, power_domain, wakeref);
1894
1895         return ret;
1896 }
1897
1898 static bool intel_fb_scalable(const struct drm_framebuffer *fb)
1899 {
1900         if (!fb)
1901                 return false;
1902
1903         switch (fb->format->format) {
1904         case DRM_FORMAT_C8:
1905                 return false;
1906         case DRM_FORMAT_XRGB16161616F:
1907         case DRM_FORMAT_ARGB16161616F:
1908         case DRM_FORMAT_XBGR16161616F:
1909         case DRM_FORMAT_ABGR16161616F:
1910                 return INTEL_GEN(to_i915(fb->dev)) >= 11;
1911         default:
1912                 return true;
1913         }
1914 }
1915
1916 static int
1917 g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
1918                          struct intel_plane_state *plane_state)
1919 {
1920         const struct drm_framebuffer *fb = plane_state->hw.fb;
1921         const struct drm_rect *src = &plane_state->uapi.src;
1922         const struct drm_rect *dst = &plane_state->uapi.dst;
1923         int src_x, src_w, src_h, crtc_w, crtc_h;
1924         const struct drm_display_mode *adjusted_mode =
1925                 &crtc_state->hw.adjusted_mode;
1926         unsigned int stride = plane_state->color_plane[0].stride;
1927         unsigned int cpp = fb->format->cpp[0];
1928         unsigned int width_bytes;
1929         int min_width, min_height;
1930
1931         crtc_w = drm_rect_width(dst);
1932         crtc_h = drm_rect_height(dst);
1933
1934         src_x = src->x1 >> 16;
1935         src_w = drm_rect_width(src) >> 16;
1936         src_h = drm_rect_height(src) >> 16;
1937
1938         if (src_w == crtc_w && src_h == crtc_h)
1939                 return 0;
1940
1941         min_width = 3;
1942
1943         if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
1944                 if (src_h & 1) {
1945                         DRM_DEBUG_KMS("Source height must be even with interlaced modes\n");
1946                         return -EINVAL;
1947                 }
1948                 min_height = 6;
1949         } else {
1950                 min_height = 3;
1951         }
1952
1953         width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
1954
1955         if (src_w < min_width || src_h < min_height ||
1956             src_w > 2048 || src_h > 2048) {
1957                 DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
1958                               src_w, src_h, min_width, min_height, 2048, 2048);
1959                 return -EINVAL;
1960         }
1961
1962         if (width_bytes > 4096) {
1963                 DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n",
1964                               width_bytes, 4096);
1965                 return -EINVAL;
1966         }
1967
1968         if (stride > 4096) {
1969                 DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n",
1970                               stride, 4096);
1971                 return -EINVAL;
1972         }
1973
1974         return 0;
1975 }
1976
1977 static int
1978 g4x_sprite_check(struct intel_crtc_state *crtc_state,
1979                  struct intel_plane_state *plane_state)
1980 {
1981         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1982         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1983         int min_scale = DRM_PLANE_HELPER_NO_SCALING;
1984         int max_scale = DRM_PLANE_HELPER_NO_SCALING;
1985         int ret;
1986
1987         if (intel_fb_scalable(plane_state->hw.fb)) {
1988                 if (INTEL_GEN(dev_priv) < 7) {
1989                         min_scale = 1;
1990                         max_scale = 16 << 16;
1991                 } else if (IS_IVYBRIDGE(dev_priv)) {
1992                         min_scale = 1;
1993                         max_scale = 2 << 16;
1994                 }
1995         }
1996
1997         ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
1998                                                   &crtc_state->uapi,
1999                                                   min_scale, max_scale,
2000                                                   true, true);
2001         if (ret)
2002                 return ret;
2003
2004         ret = i9xx_check_plane_surface(plane_state);
2005         if (ret)
2006                 return ret;
2007
2008         if (!plane_state->uapi.visible)
2009                 return 0;
2010
2011         ret = intel_plane_check_src_coordinates(plane_state);
2012         if (ret)
2013                 return ret;
2014
2015         ret = g4x_sprite_check_scaling(crtc_state, plane_state);
2016         if (ret)
2017                 return ret;
2018
2019         if (INTEL_GEN(dev_priv) >= 7)
2020                 plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state);
2021         else
2022                 plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state);
2023
2024         return 0;
2025 }
2026
2027 int chv_plane_check_rotation(const struct intel_plane_state *plane_state)
2028 {
2029         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
2030         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
2031         unsigned int rotation = plane_state->hw.rotation;
2032
2033         /* CHV ignores the mirror bit when the rotate bit is set :( */
2034         if (IS_CHERRYVIEW(dev_priv) &&
2035             rotation & DRM_MODE_ROTATE_180 &&
2036             rotation & DRM_MODE_REFLECT_X) {
2037                 drm_dbg_kms(&dev_priv->drm,
2038                             "Cannot rotate and reflect at the same time\n");
2039                 return -EINVAL;
2040         }
2041
2042         return 0;
2043 }
2044
2045 static int
2046 vlv_sprite_check(struct intel_crtc_state *crtc_state,
2047                  struct intel_plane_state *plane_state)
2048 {
2049         int ret;
2050
2051         ret = chv_plane_check_rotation(plane_state);
2052         if (ret)
2053                 return ret;
2054
2055         ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
2056                                                   &crtc_state->uapi,
2057                                                   DRM_PLANE_HELPER_NO_SCALING,
2058                                                   DRM_PLANE_HELPER_NO_SCALING,
2059                                                   true, true);
2060         if (ret)
2061                 return ret;
2062
2063         ret = i9xx_check_plane_surface(plane_state);
2064         if (ret)
2065                 return ret;
2066
2067         if (!plane_state->uapi.visible)
2068                 return 0;
2069
2070         ret = intel_plane_check_src_coordinates(plane_state);
2071         if (ret)
2072                 return ret;
2073
2074         plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state);
2075
2076         return 0;
2077 }
2078
2079 static bool intel_format_is_p01x(u32 format)
2080 {
2081         switch (format) {
2082         case DRM_FORMAT_P010:
2083         case DRM_FORMAT_P012:
2084         case DRM_FORMAT_P016:
2085                 return true;
2086         default:
2087                 return false;
2088         }
2089 }
2090
2091 static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
2092                               const struct intel_plane_state *plane_state)
2093 {
2094         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
2095         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
2096         const struct drm_framebuffer *fb = plane_state->hw.fb;
2097         unsigned int rotation = plane_state->hw.rotation;
2098         struct drm_format_name_buf format_name;
2099
2100         if (!fb)
2101                 return 0;
2102
2103         if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) &&
2104             is_ccs_modifier(fb->modifier)) {
2105                 drm_dbg_kms(&dev_priv->drm,
2106                             "RC support only with 0/180 degree rotation (%x)\n",
2107                             rotation);
2108                 return -EINVAL;
2109         }
2110
2111         if (rotation & DRM_MODE_REFLECT_X &&
2112             fb->modifier == DRM_FORMAT_MOD_LINEAR) {
2113                 drm_dbg_kms(&dev_priv->drm,
2114                             "horizontal flip is not supported with linear surface formats\n");
2115                 return -EINVAL;
2116         }
2117
2118         if (drm_rotation_90_or_270(rotation)) {
2119                 if (fb->modifier != I915_FORMAT_MOD_Y_TILED &&
2120                     fb->modifier != I915_FORMAT_MOD_Yf_TILED) {
2121                         drm_dbg_kms(&dev_priv->drm,
2122                                     "Y/Yf tiling required for 90/270!\n");
2123                         return -EINVAL;
2124                 }
2125
2126                 /*
2127                  * 90/270 is not allowed with RGB64 16:16:16:16 and
2128                  * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards.
2129                  */
2130                 switch (fb->format->format) {
2131                 case DRM_FORMAT_RGB565:
2132                         if (INTEL_GEN(dev_priv) >= 11)
2133                                 break;
2134                         /* fall through */
2135                 case DRM_FORMAT_C8:
2136                 case DRM_FORMAT_XRGB16161616F:
2137                 case DRM_FORMAT_XBGR16161616F:
2138                 case DRM_FORMAT_ARGB16161616F:
2139                 case DRM_FORMAT_ABGR16161616F:
2140                 case DRM_FORMAT_Y210:
2141                 case DRM_FORMAT_Y212:
2142                 case DRM_FORMAT_Y216:
2143                 case DRM_FORMAT_XVYU12_16161616:
2144                 case DRM_FORMAT_XVYU16161616:
2145                         drm_dbg_kms(&dev_priv->drm,
2146                                     "Unsupported pixel format %s for 90/270!\n",
2147                                     drm_get_format_name(fb->format->format,
2148                                                         &format_name));
2149                         return -EINVAL;
2150                 default:
2151                         break;
2152                 }
2153         }
2154
2155         /* Y-tiling is not supported in IF-ID Interlace mode */
2156         if (crtc_state->hw.enable &&
2157             crtc_state->hw.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
2158             (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
2159              fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
2160              fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
2161              fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS ||
2162              fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS ||
2163              fb->modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS)) {
2164                 drm_dbg_kms(&dev_priv->drm,
2165                             "Y/Yf tiling not supported in IF-ID mode\n");
2166                 return -EINVAL;
2167         }
2168
2169         /* Wa_1606054188:tgl */
2170         if (IS_TIGERLAKE(dev_priv) &&
2171             plane_state->ckey.flags & I915_SET_COLORKEY_SOURCE &&
2172             intel_format_is_p01x(fb->format->format)) {
2173                 drm_dbg_kms(&dev_priv->drm,
2174                             "Source color keying not supported with P01x formats\n");
2175                 return -EINVAL;
2176         }
2177
2178         return 0;
2179 }
2180
2181 static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state,
2182                                            const struct intel_plane_state *plane_state)
2183 {
2184         struct drm_i915_private *dev_priv =
2185                 to_i915(plane_state->uapi.plane->dev);
2186         int crtc_x = plane_state->uapi.dst.x1;
2187         int crtc_w = drm_rect_width(&plane_state->uapi.dst);
2188         int pipe_src_w = crtc_state->pipe_src_w;
2189
2190         /*
2191          * Display WA #1175: cnl,glk
2192          * Planes other than the cursor may cause FIFO underflow and display
2193          * corruption if starting less than 4 pixels from the right edge of
2194          * the screen.
2195          * Besides the above WA fix the similar problem, where planes other
2196          * than the cursor ending less than 4 pixels from the left edge of the
2197          * screen may cause FIFO underflow and display corruption.
2198          */
2199         if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
2200             (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
2201                 drm_dbg_kms(&dev_priv->drm,
2202                             "requested plane X %s position %d invalid (valid range %d-%d)\n",
2203                             crtc_x + crtc_w < 4 ? "end" : "start",
2204                             crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x,
2205                             4, pipe_src_w - 4);
2206                 return -ERANGE;
2207         }
2208
2209         return 0;
2210 }
2211
2212 static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
2213 {
2214         const struct drm_framebuffer *fb = plane_state->hw.fb;
2215         unsigned int rotation = plane_state->hw.rotation;
2216         int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
2217
2218         /* Display WA #1106 */
2219         if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
2220             src_w & 3 &&
2221             (rotation == DRM_MODE_ROTATE_270 ||
2222              rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
2223                 DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n");
2224                 return -EINVAL;
2225         }
2226
2227         return 0;
2228 }
2229
2230 static int skl_plane_max_scale(struct drm_i915_private *dev_priv,
2231                                const struct drm_framebuffer *fb)
2232 {
2233         /*
2234          * We don't yet know the final source width nor
2235          * whether we can use the HQ scaler mode. Assume
2236          * the best case.
2237          * FIXME need to properly check this later.
2238          */
2239         if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv) ||
2240             !intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
2241                 return 0x30000 - 1;
2242         else
2243                 return 0x20000 - 1;
2244 }
2245
2246 static int skl_plane_check(struct intel_crtc_state *crtc_state,
2247                            struct intel_plane_state *plane_state)
2248 {
2249         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
2250         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
2251         const struct drm_framebuffer *fb = plane_state->hw.fb;
2252         int min_scale = DRM_PLANE_HELPER_NO_SCALING;
2253         int max_scale = DRM_PLANE_HELPER_NO_SCALING;
2254         int ret;
2255
2256         ret = skl_plane_check_fb(crtc_state, plane_state);
2257         if (ret)
2258                 return ret;
2259
2260         /* use scaler when colorkey is not required */
2261         if (!plane_state->ckey.flags && intel_fb_scalable(fb)) {
2262                 min_scale = 1;
2263                 max_scale = skl_plane_max_scale(dev_priv, fb);
2264         }
2265
2266         ret = drm_atomic_helper_check_plane_state(&plane_state->uapi,
2267                                                   &crtc_state->uapi,
2268                                                   min_scale, max_scale,
2269                                                   true, true);
2270         if (ret)
2271                 return ret;
2272
2273         ret = skl_check_plane_surface(plane_state);
2274         if (ret)
2275                 return ret;
2276
2277         if (!plane_state->uapi.visible)
2278                 return 0;
2279
2280         ret = skl_plane_check_dst_coordinates(crtc_state, plane_state);
2281         if (ret)
2282                 return ret;
2283
2284         ret = intel_plane_check_src_coordinates(plane_state);
2285         if (ret)
2286                 return ret;
2287
2288         ret = skl_plane_check_nv12_rotation(plane_state);
2289         if (ret)
2290                 return ret;
2291
2292         /* HW only has 8 bits pixel precision, disable plane if invisible */
2293         if (!(plane_state->hw.alpha >> 8))
2294                 plane_state->uapi.visible = false;
2295
2296         plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
2297
2298         if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
2299                 plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
2300                                                              plane_state);
2301
2302         if (intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier) &&
2303             icl_is_hdr_plane(dev_priv, plane->id))
2304                 /* Enable and use MPEG-2 chroma siting */
2305                 plane_state->cus_ctl = PLANE_CUS_ENABLE |
2306                         PLANE_CUS_HPHASE_0 |
2307                         PLANE_CUS_VPHASE_SIGN_NEGATIVE | PLANE_CUS_VPHASE_0_25;
2308         else
2309                 plane_state->cus_ctl = 0;
2310
2311         return 0;
2312 }
2313
2314 static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv)
2315 {
2316         return INTEL_GEN(dev_priv) >= 9;
2317 }
2318
2319 static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
2320                                  const struct drm_intel_sprite_colorkey *set)
2321 {
2322         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
2323         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
2324         struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
2325
2326         *key = *set;
2327
2328         /*
2329          * We want src key enabled on the
2330          * sprite and not on the primary.
2331          */
2332         if (plane->id == PLANE_PRIMARY &&
2333             set->flags & I915_SET_COLORKEY_SOURCE)
2334                 key->flags = 0;
2335
2336         /*
2337          * On SKL+ we want dst key enabled on
2338          * the primary and not on the sprite.
2339          */
2340         if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_PRIMARY &&
2341             set->flags & I915_SET_COLORKEY_DESTINATION)
2342                 key->flags = 0;
2343 }
2344
2345 int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
2346                                     struct drm_file *file_priv)
2347 {
2348         struct drm_i915_private *dev_priv = to_i915(dev);
2349         struct drm_intel_sprite_colorkey *set = data;
2350         struct drm_plane *plane;
2351         struct drm_plane_state *plane_state;
2352         struct drm_atomic_state *state;
2353         struct drm_modeset_acquire_ctx ctx;
2354         int ret = 0;
2355
2356         /* ignore the pointless "none" flag */
2357         set->flags &= ~I915_SET_COLORKEY_NONE;
2358
2359         if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
2360                 return -EINVAL;
2361
2362         /* Make sure we don't try to enable both src & dest simultaneously */
2363         if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
2364                 return -EINVAL;
2365
2366         if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
2367             set->flags & I915_SET_COLORKEY_DESTINATION)
2368                 return -EINVAL;
2369
2370         plane = drm_plane_find(dev, file_priv, set->plane_id);
2371         if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
2372                 return -ENOENT;
2373
2374         /*
2375          * SKL+ only plane 2 can do destination keying against plane 1.
2376          * Also multiple planes can't do destination keying on the same
2377          * pipe simultaneously.
2378          */
2379         if (INTEL_GEN(dev_priv) >= 9 &&
2380             to_intel_plane(plane)->id >= PLANE_SPRITE1 &&
2381             set->flags & I915_SET_COLORKEY_DESTINATION)
2382                 return -EINVAL;
2383
2384         drm_modeset_acquire_init(&ctx, 0);
2385
2386         state = drm_atomic_state_alloc(plane->dev);
2387         if (!state) {
2388                 ret = -ENOMEM;
2389                 goto out;
2390         }
2391         state->acquire_ctx = &ctx;
2392
2393         while (1) {
2394                 plane_state = drm_atomic_get_plane_state(state, plane);
2395                 ret = PTR_ERR_OR_ZERO(plane_state);
2396                 if (!ret)
2397                         intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
2398
2399                 /*
2400                  * On some platforms we have to configure
2401                  * the dst colorkey on the primary plane.
2402                  */
2403                 if (!ret && has_dst_key_in_primary_plane(dev_priv)) {
2404                         struct intel_crtc *crtc =
2405                                 intel_get_crtc_for_pipe(dev_priv,
2406                                                         to_intel_plane(plane)->pipe);
2407
2408                         plane_state = drm_atomic_get_plane_state(state,
2409                                                                  crtc->base.primary);
2410                         ret = PTR_ERR_OR_ZERO(plane_state);
2411                         if (!ret)
2412                                 intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
2413                 }
2414
2415                 if (!ret)
2416                         ret = drm_atomic_commit(state);
2417
2418                 if (ret != -EDEADLK)
2419                         break;
2420
2421                 drm_atomic_state_clear(state);
2422                 drm_modeset_backoff(&ctx);
2423         }
2424
2425         drm_atomic_state_put(state);
2426 out:
2427         drm_modeset_drop_locks(&ctx);
2428         drm_modeset_acquire_fini(&ctx);
2429         return ret;
2430 }
2431
2432 static const u32 g4x_plane_formats[] = {
2433         DRM_FORMAT_XRGB8888,
2434         DRM_FORMAT_YUYV,
2435         DRM_FORMAT_YVYU,
2436         DRM_FORMAT_UYVY,
2437         DRM_FORMAT_VYUY,
2438 };
2439
2440 static const u64 i9xx_plane_format_modifiers[] = {
2441         I915_FORMAT_MOD_X_TILED,
2442         DRM_FORMAT_MOD_LINEAR,
2443         DRM_FORMAT_MOD_INVALID
2444 };
2445
2446 static const u32 snb_plane_formats[] = {
2447         DRM_FORMAT_XRGB8888,
2448         DRM_FORMAT_XBGR8888,
2449         DRM_FORMAT_XRGB2101010,
2450         DRM_FORMAT_XBGR2101010,
2451         DRM_FORMAT_XRGB16161616F,
2452         DRM_FORMAT_XBGR16161616F,
2453         DRM_FORMAT_YUYV,
2454         DRM_FORMAT_YVYU,
2455         DRM_FORMAT_UYVY,
2456         DRM_FORMAT_VYUY,
2457 };
2458
2459 static const u32 vlv_plane_formats[] = {
2460         DRM_FORMAT_C8,
2461         DRM_FORMAT_RGB565,
2462         DRM_FORMAT_XRGB8888,
2463         DRM_FORMAT_XBGR8888,
2464         DRM_FORMAT_ARGB8888,
2465         DRM_FORMAT_ABGR8888,
2466         DRM_FORMAT_XBGR2101010,
2467         DRM_FORMAT_ABGR2101010,
2468         DRM_FORMAT_YUYV,
2469         DRM_FORMAT_YVYU,
2470         DRM_FORMAT_UYVY,
2471         DRM_FORMAT_VYUY,
2472 };
2473
2474 static const u32 chv_pipe_b_sprite_formats[] = {
2475         DRM_FORMAT_C8,
2476         DRM_FORMAT_RGB565,
2477         DRM_FORMAT_XRGB8888,
2478         DRM_FORMAT_XBGR8888,
2479         DRM_FORMAT_ARGB8888,
2480         DRM_FORMAT_ABGR8888,
2481         DRM_FORMAT_XRGB2101010,
2482         DRM_FORMAT_XBGR2101010,
2483         DRM_FORMAT_ARGB2101010,
2484         DRM_FORMAT_ABGR2101010,
2485         DRM_FORMAT_YUYV,
2486         DRM_FORMAT_YVYU,
2487         DRM_FORMAT_UYVY,
2488         DRM_FORMAT_VYUY,
2489 };
2490
2491 static const u32 skl_plane_formats[] = {
2492         DRM_FORMAT_C8,
2493         DRM_FORMAT_RGB565,
2494         DRM_FORMAT_XRGB8888,
2495         DRM_FORMAT_XBGR8888,
2496         DRM_FORMAT_ARGB8888,
2497         DRM_FORMAT_ABGR8888,
2498         DRM_FORMAT_XRGB2101010,
2499         DRM_FORMAT_XBGR2101010,
2500         DRM_FORMAT_XRGB16161616F,
2501         DRM_FORMAT_XBGR16161616F,
2502         DRM_FORMAT_YUYV,
2503         DRM_FORMAT_YVYU,
2504         DRM_FORMAT_UYVY,
2505         DRM_FORMAT_VYUY,
2506 };
2507
2508 static const u32 skl_planar_formats[] = {
2509         DRM_FORMAT_C8,
2510         DRM_FORMAT_RGB565,
2511         DRM_FORMAT_XRGB8888,
2512         DRM_FORMAT_XBGR8888,
2513         DRM_FORMAT_ARGB8888,
2514         DRM_FORMAT_ABGR8888,
2515         DRM_FORMAT_XRGB2101010,
2516         DRM_FORMAT_XBGR2101010,
2517         DRM_FORMAT_XRGB16161616F,
2518         DRM_FORMAT_XBGR16161616F,
2519         DRM_FORMAT_YUYV,
2520         DRM_FORMAT_YVYU,
2521         DRM_FORMAT_UYVY,
2522         DRM_FORMAT_VYUY,
2523         DRM_FORMAT_NV12,
2524 };
2525
2526 static const u32 glk_planar_formats[] = {
2527         DRM_FORMAT_C8,
2528         DRM_FORMAT_RGB565,
2529         DRM_FORMAT_XRGB8888,
2530         DRM_FORMAT_XBGR8888,
2531         DRM_FORMAT_ARGB8888,
2532         DRM_FORMAT_ABGR8888,
2533         DRM_FORMAT_XRGB2101010,
2534         DRM_FORMAT_XBGR2101010,
2535         DRM_FORMAT_XRGB16161616F,
2536         DRM_FORMAT_XBGR16161616F,
2537         DRM_FORMAT_YUYV,
2538         DRM_FORMAT_YVYU,
2539         DRM_FORMAT_UYVY,
2540         DRM_FORMAT_VYUY,
2541         DRM_FORMAT_NV12,
2542         DRM_FORMAT_P010,
2543         DRM_FORMAT_P012,
2544         DRM_FORMAT_P016,
2545 };
2546
2547 static const u32 icl_sdr_y_plane_formats[] = {
2548         DRM_FORMAT_C8,
2549         DRM_FORMAT_RGB565,
2550         DRM_FORMAT_XRGB8888,
2551         DRM_FORMAT_XBGR8888,
2552         DRM_FORMAT_ARGB8888,
2553         DRM_FORMAT_ABGR8888,
2554         DRM_FORMAT_XRGB2101010,
2555         DRM_FORMAT_XBGR2101010,
2556         DRM_FORMAT_ARGB2101010,
2557         DRM_FORMAT_ABGR2101010,
2558         DRM_FORMAT_YUYV,
2559         DRM_FORMAT_YVYU,
2560         DRM_FORMAT_UYVY,
2561         DRM_FORMAT_VYUY,
2562         DRM_FORMAT_Y210,
2563         DRM_FORMAT_Y212,
2564         DRM_FORMAT_Y216,
2565         DRM_FORMAT_XVYU2101010,
2566         DRM_FORMAT_XVYU12_16161616,
2567         DRM_FORMAT_XVYU16161616,
2568 };
2569
2570 static const u32 icl_sdr_uv_plane_formats[] = {
2571         DRM_FORMAT_C8,
2572         DRM_FORMAT_RGB565,
2573         DRM_FORMAT_XRGB8888,
2574         DRM_FORMAT_XBGR8888,
2575         DRM_FORMAT_ARGB8888,
2576         DRM_FORMAT_ABGR8888,
2577         DRM_FORMAT_XRGB2101010,
2578         DRM_FORMAT_XBGR2101010,
2579         DRM_FORMAT_ARGB2101010,
2580         DRM_FORMAT_ABGR2101010,
2581         DRM_FORMAT_YUYV,
2582         DRM_FORMAT_YVYU,
2583         DRM_FORMAT_UYVY,
2584         DRM_FORMAT_VYUY,
2585         DRM_FORMAT_NV12,
2586         DRM_FORMAT_P010,
2587         DRM_FORMAT_P012,
2588         DRM_FORMAT_P016,
2589         DRM_FORMAT_Y210,
2590         DRM_FORMAT_Y212,
2591         DRM_FORMAT_Y216,
2592         DRM_FORMAT_XVYU2101010,
2593         DRM_FORMAT_XVYU12_16161616,
2594         DRM_FORMAT_XVYU16161616,
2595 };
2596
2597 static const u32 icl_hdr_plane_formats[] = {
2598         DRM_FORMAT_C8,
2599         DRM_FORMAT_RGB565,
2600         DRM_FORMAT_XRGB8888,
2601         DRM_FORMAT_XBGR8888,
2602         DRM_FORMAT_ARGB8888,
2603         DRM_FORMAT_ABGR8888,
2604         DRM_FORMAT_XRGB2101010,
2605         DRM_FORMAT_XBGR2101010,
2606         DRM_FORMAT_ARGB2101010,
2607         DRM_FORMAT_ABGR2101010,
2608         DRM_FORMAT_XRGB16161616F,
2609         DRM_FORMAT_XBGR16161616F,
2610         DRM_FORMAT_ARGB16161616F,
2611         DRM_FORMAT_ABGR16161616F,
2612         DRM_FORMAT_YUYV,
2613         DRM_FORMAT_YVYU,
2614         DRM_FORMAT_UYVY,
2615         DRM_FORMAT_VYUY,
2616         DRM_FORMAT_NV12,
2617         DRM_FORMAT_P010,
2618         DRM_FORMAT_P012,
2619         DRM_FORMAT_P016,
2620         DRM_FORMAT_Y210,
2621         DRM_FORMAT_Y212,
2622         DRM_FORMAT_Y216,
2623         DRM_FORMAT_XVYU2101010,
2624         DRM_FORMAT_XVYU12_16161616,
2625         DRM_FORMAT_XVYU16161616,
2626 };
2627
2628 static const u64 skl_plane_format_modifiers_noccs[] = {
2629         I915_FORMAT_MOD_Yf_TILED,
2630         I915_FORMAT_MOD_Y_TILED,
2631         I915_FORMAT_MOD_X_TILED,
2632         DRM_FORMAT_MOD_LINEAR,
2633         DRM_FORMAT_MOD_INVALID
2634 };
2635
2636 static const u64 skl_plane_format_modifiers_ccs[] = {
2637         I915_FORMAT_MOD_Yf_TILED_CCS,
2638         I915_FORMAT_MOD_Y_TILED_CCS,
2639         I915_FORMAT_MOD_Yf_TILED,
2640         I915_FORMAT_MOD_Y_TILED,
2641         I915_FORMAT_MOD_X_TILED,
2642         DRM_FORMAT_MOD_LINEAR,
2643         DRM_FORMAT_MOD_INVALID
2644 };
2645
2646 static const u64 gen12_plane_format_modifiers_mc_ccs[] = {
2647         I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS,
2648         I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
2649         I915_FORMAT_MOD_Y_TILED,
2650         I915_FORMAT_MOD_X_TILED,
2651         DRM_FORMAT_MOD_LINEAR,
2652         DRM_FORMAT_MOD_INVALID
2653 };
2654
2655 static const u64 gen12_plane_format_modifiers_rc_ccs[] = {
2656         I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS,
2657         I915_FORMAT_MOD_Y_TILED,
2658         I915_FORMAT_MOD_X_TILED,
2659         DRM_FORMAT_MOD_LINEAR,
2660         DRM_FORMAT_MOD_INVALID
2661 };
2662
2663 static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane,
2664                                             u32 format, u64 modifier)
2665 {
2666         switch (modifier) {
2667         case DRM_FORMAT_MOD_LINEAR:
2668         case I915_FORMAT_MOD_X_TILED:
2669                 break;
2670         default:
2671                 return false;
2672         }
2673
2674         switch (format) {
2675         case DRM_FORMAT_XRGB8888:
2676         case DRM_FORMAT_YUYV:
2677         case DRM_FORMAT_YVYU:
2678         case DRM_FORMAT_UYVY:
2679         case DRM_FORMAT_VYUY:
2680                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
2681                     modifier == I915_FORMAT_MOD_X_TILED)
2682                         return true;
2683                 /* fall through */
2684         default:
2685                 return false;
2686         }
2687 }
2688
2689 static bool snb_sprite_format_mod_supported(struct drm_plane *_plane,
2690                                             u32 format, u64 modifier)
2691 {
2692         switch (modifier) {
2693         case DRM_FORMAT_MOD_LINEAR:
2694         case I915_FORMAT_MOD_X_TILED:
2695                 break;
2696         default:
2697                 return false;
2698         }
2699
2700         switch (format) {
2701         case DRM_FORMAT_XRGB8888:
2702         case DRM_FORMAT_XBGR8888:
2703         case DRM_FORMAT_XRGB2101010:
2704         case DRM_FORMAT_XBGR2101010:
2705         case DRM_FORMAT_XRGB16161616F:
2706         case DRM_FORMAT_XBGR16161616F:
2707         case DRM_FORMAT_YUYV:
2708         case DRM_FORMAT_YVYU:
2709         case DRM_FORMAT_UYVY:
2710         case DRM_FORMAT_VYUY:
2711                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
2712                     modifier == I915_FORMAT_MOD_X_TILED)
2713                         return true;
2714                 /* fall through */
2715         default:
2716                 return false;
2717         }
2718 }
2719
2720 static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane,
2721                                             u32 format, u64 modifier)
2722 {
2723         switch (modifier) {
2724         case DRM_FORMAT_MOD_LINEAR:
2725         case I915_FORMAT_MOD_X_TILED:
2726                 break;
2727         default:
2728                 return false;
2729         }
2730
2731         switch (format) {
2732         case DRM_FORMAT_C8:
2733         case DRM_FORMAT_RGB565:
2734         case DRM_FORMAT_ABGR8888:
2735         case DRM_FORMAT_ARGB8888:
2736         case DRM_FORMAT_XBGR8888:
2737         case DRM_FORMAT_XRGB8888:
2738         case DRM_FORMAT_XBGR2101010:
2739         case DRM_FORMAT_ABGR2101010:
2740         case DRM_FORMAT_XRGB2101010:
2741         case DRM_FORMAT_ARGB2101010:
2742         case DRM_FORMAT_YUYV:
2743         case DRM_FORMAT_YVYU:
2744         case DRM_FORMAT_UYVY:
2745         case DRM_FORMAT_VYUY:
2746                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
2747                     modifier == I915_FORMAT_MOD_X_TILED)
2748                         return true;
2749                 /* fall through */
2750         default:
2751                 return false;
2752         }
2753 }
2754
2755 static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
2756                                            u32 format, u64 modifier)
2757 {
2758         struct intel_plane *plane = to_intel_plane(_plane);
2759
2760         switch (modifier) {
2761         case DRM_FORMAT_MOD_LINEAR:
2762         case I915_FORMAT_MOD_X_TILED:
2763         case I915_FORMAT_MOD_Y_TILED:
2764         case I915_FORMAT_MOD_Yf_TILED:
2765                 break;
2766         case I915_FORMAT_MOD_Y_TILED_CCS:
2767         case I915_FORMAT_MOD_Yf_TILED_CCS:
2768                 if (!plane->has_ccs)
2769                         return false;
2770                 break;
2771         default:
2772                 return false;
2773         }
2774
2775         switch (format) {
2776         case DRM_FORMAT_XRGB8888:
2777         case DRM_FORMAT_XBGR8888:
2778         case DRM_FORMAT_ARGB8888:
2779         case DRM_FORMAT_ABGR8888:
2780                 if (is_ccs_modifier(modifier))
2781                         return true;
2782                 /* fall through */
2783         case DRM_FORMAT_RGB565:
2784         case DRM_FORMAT_XRGB2101010:
2785         case DRM_FORMAT_XBGR2101010:
2786         case DRM_FORMAT_ARGB2101010:
2787         case DRM_FORMAT_ABGR2101010:
2788         case DRM_FORMAT_YUYV:
2789         case DRM_FORMAT_YVYU:
2790         case DRM_FORMAT_UYVY:
2791         case DRM_FORMAT_VYUY:
2792         case DRM_FORMAT_NV12:
2793         case DRM_FORMAT_P010:
2794         case DRM_FORMAT_P012:
2795         case DRM_FORMAT_P016:
2796         case DRM_FORMAT_XVYU2101010:
2797                 if (modifier == I915_FORMAT_MOD_Yf_TILED)
2798                         return true;
2799                 /* fall through */
2800         case DRM_FORMAT_C8:
2801         case DRM_FORMAT_XBGR16161616F:
2802         case DRM_FORMAT_ABGR16161616F:
2803         case DRM_FORMAT_XRGB16161616F:
2804         case DRM_FORMAT_ARGB16161616F:
2805         case DRM_FORMAT_Y210:
2806         case DRM_FORMAT_Y212:
2807         case DRM_FORMAT_Y216:
2808         case DRM_FORMAT_XVYU12_16161616:
2809         case DRM_FORMAT_XVYU16161616:
2810                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
2811                     modifier == I915_FORMAT_MOD_X_TILED ||
2812                     modifier == I915_FORMAT_MOD_Y_TILED)
2813                         return true;
2814                 /* fall through */
2815         default:
2816                 return false;
2817         }
2818 }
2819
2820 static bool gen12_plane_supports_mc_ccs(struct drm_i915_private *dev_priv,
2821                                         enum plane_id plane_id)
2822 {
2823         /* Wa_14010477008:tgl[a0..c0] */
2824         if (IS_TGL_REVID(dev_priv, TGL_REVID_A0, TGL_REVID_C0))
2825                 return false;
2826
2827         return plane_id < PLANE_SPRITE4;
2828 }
2829
2830 static bool gen12_plane_format_mod_supported(struct drm_plane *_plane,
2831                                              u32 format, u64 modifier)
2832 {
2833         struct drm_i915_private *dev_priv = to_i915(_plane->dev);
2834         struct intel_plane *plane = to_intel_plane(_plane);
2835
2836         switch (modifier) {
2837         case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
2838                 if (!gen12_plane_supports_mc_ccs(dev_priv, plane->id))
2839                         return false;
2840                 /* fall through */
2841         case DRM_FORMAT_MOD_LINEAR:
2842         case I915_FORMAT_MOD_X_TILED:
2843         case I915_FORMAT_MOD_Y_TILED:
2844         case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
2845                 break;
2846         default:
2847                 return false;
2848         }
2849
2850         switch (format) {
2851         case DRM_FORMAT_XRGB8888:
2852         case DRM_FORMAT_XBGR8888:
2853         case DRM_FORMAT_ARGB8888:
2854         case DRM_FORMAT_ABGR8888:
2855                 if (is_ccs_modifier(modifier))
2856                         return true;
2857                 /* fall through */
2858         case DRM_FORMAT_YUYV:
2859         case DRM_FORMAT_YVYU:
2860         case DRM_FORMAT_UYVY:
2861         case DRM_FORMAT_VYUY:
2862         case DRM_FORMAT_NV12:
2863         case DRM_FORMAT_P010:
2864         case DRM_FORMAT_P012:
2865         case DRM_FORMAT_P016:
2866                 if (modifier == I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS)
2867                         return true;
2868                 /* fall through */
2869         case DRM_FORMAT_RGB565:
2870         case DRM_FORMAT_XRGB2101010:
2871         case DRM_FORMAT_XBGR2101010:
2872         case DRM_FORMAT_ARGB2101010:
2873         case DRM_FORMAT_ABGR2101010:
2874         case DRM_FORMAT_XVYU2101010:
2875         case DRM_FORMAT_C8:
2876         case DRM_FORMAT_XBGR16161616F:
2877         case DRM_FORMAT_ABGR16161616F:
2878         case DRM_FORMAT_XRGB16161616F:
2879         case DRM_FORMAT_ARGB16161616F:
2880         case DRM_FORMAT_Y210:
2881         case DRM_FORMAT_Y212:
2882         case DRM_FORMAT_Y216:
2883         case DRM_FORMAT_XVYU12_16161616:
2884         case DRM_FORMAT_XVYU16161616:
2885                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
2886                     modifier == I915_FORMAT_MOD_X_TILED ||
2887                     modifier == I915_FORMAT_MOD_Y_TILED)
2888                         return true;
2889                 /* fall through */
2890         default:
2891                 return false;
2892         }
2893 }
2894
2895 static const struct drm_plane_funcs g4x_sprite_funcs = {
2896         .update_plane = drm_atomic_helper_update_plane,
2897         .disable_plane = drm_atomic_helper_disable_plane,
2898         .destroy = intel_plane_destroy,
2899         .atomic_duplicate_state = intel_plane_duplicate_state,
2900         .atomic_destroy_state = intel_plane_destroy_state,
2901         .format_mod_supported = g4x_sprite_format_mod_supported,
2902 };
2903
2904 static const struct drm_plane_funcs snb_sprite_funcs = {
2905         .update_plane = drm_atomic_helper_update_plane,
2906         .disable_plane = drm_atomic_helper_disable_plane,
2907         .destroy = intel_plane_destroy,
2908         .atomic_duplicate_state = intel_plane_duplicate_state,
2909         .atomic_destroy_state = intel_plane_destroy_state,
2910         .format_mod_supported = snb_sprite_format_mod_supported,
2911 };
2912
2913 static const struct drm_plane_funcs vlv_sprite_funcs = {
2914         .update_plane = drm_atomic_helper_update_plane,
2915         .disable_plane = drm_atomic_helper_disable_plane,
2916         .destroy = intel_plane_destroy,
2917         .atomic_duplicate_state = intel_plane_duplicate_state,
2918         .atomic_destroy_state = intel_plane_destroy_state,
2919         .format_mod_supported = vlv_sprite_format_mod_supported,
2920 };
2921
2922 static const struct drm_plane_funcs skl_plane_funcs = {
2923         .update_plane = drm_atomic_helper_update_plane,
2924         .disable_plane = drm_atomic_helper_disable_plane,
2925         .destroy = intel_plane_destroy,
2926         .atomic_duplicate_state = intel_plane_duplicate_state,
2927         .atomic_destroy_state = intel_plane_destroy_state,
2928         .format_mod_supported = skl_plane_format_mod_supported,
2929 };
2930
2931 static const struct drm_plane_funcs gen12_plane_funcs = {
2932         .update_plane = drm_atomic_helper_update_plane,
2933         .disable_plane = drm_atomic_helper_disable_plane,
2934         .destroy = intel_plane_destroy,
2935         .atomic_duplicate_state = intel_plane_duplicate_state,
2936         .atomic_destroy_state = intel_plane_destroy_state,
2937         .format_mod_supported = gen12_plane_format_mod_supported,
2938 };
2939
2940 static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
2941                               enum pipe pipe, enum plane_id plane_id)
2942 {
2943         if (!HAS_FBC(dev_priv))
2944                 return false;
2945
2946         return pipe == PIPE_A && plane_id == PLANE_PRIMARY;
2947 }
2948
2949 static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
2950                                  enum pipe pipe, enum plane_id plane_id)
2951 {
2952         /* Display WA #0870: skl, bxt */
2953         if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
2954                 return false;
2955
2956         if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv) && pipe == PIPE_C)
2957                 return false;
2958
2959         if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0)
2960                 return false;
2961
2962         return true;
2963 }
2964
2965 static const u32 *skl_get_plane_formats(struct drm_i915_private *dev_priv,
2966                                         enum pipe pipe, enum plane_id plane_id,
2967                                         int *num_formats)
2968 {
2969         if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
2970                 *num_formats = ARRAY_SIZE(skl_planar_formats);
2971                 return skl_planar_formats;
2972         } else {
2973                 *num_formats = ARRAY_SIZE(skl_plane_formats);
2974                 return skl_plane_formats;
2975         }
2976 }
2977
2978 static const u32 *glk_get_plane_formats(struct drm_i915_private *dev_priv,
2979                                         enum pipe pipe, enum plane_id plane_id,
2980                                         int *num_formats)
2981 {
2982         if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
2983                 *num_formats = ARRAY_SIZE(glk_planar_formats);
2984                 return glk_planar_formats;
2985         } else {
2986                 *num_formats = ARRAY_SIZE(skl_plane_formats);
2987                 return skl_plane_formats;
2988         }
2989 }
2990
2991 static const u32 *icl_get_plane_formats(struct drm_i915_private *dev_priv,
2992                                         enum pipe pipe, enum plane_id plane_id,
2993                                         int *num_formats)
2994 {
2995         if (icl_is_hdr_plane(dev_priv, plane_id)) {
2996                 *num_formats = ARRAY_SIZE(icl_hdr_plane_formats);
2997                 return icl_hdr_plane_formats;
2998         } else if (icl_is_nv12_y_plane(plane_id)) {
2999                 *num_formats = ARRAY_SIZE(icl_sdr_y_plane_formats);
3000                 return icl_sdr_y_plane_formats;
3001         } else {
3002                 *num_formats = ARRAY_SIZE(icl_sdr_uv_plane_formats);
3003                 return icl_sdr_uv_plane_formats;
3004         }
3005 }
3006
3007 static const u64 *gen12_get_plane_modifiers(struct drm_i915_private *dev_priv,
3008                                             enum plane_id plane_id)
3009 {
3010         if (gen12_plane_supports_mc_ccs(dev_priv, plane_id))
3011                 return gen12_plane_format_modifiers_mc_ccs;
3012         else
3013                 return gen12_plane_format_modifiers_rc_ccs;
3014 }
3015
3016 static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
3017                               enum pipe pipe, enum plane_id plane_id)
3018 {
3019         if (plane_id == PLANE_CURSOR)
3020                 return false;
3021
3022         if (INTEL_GEN(dev_priv) >= 10)
3023                 return true;
3024
3025         if (IS_GEMINILAKE(dev_priv))
3026                 return pipe != PIPE_C;
3027
3028         return pipe != PIPE_C &&
3029                 (plane_id == PLANE_PRIMARY ||
3030                  plane_id == PLANE_SPRITE0);
3031 }
3032
3033 struct intel_plane *
3034 skl_universal_plane_create(struct drm_i915_private *dev_priv,
3035                            enum pipe pipe, enum plane_id plane_id)
3036 {
3037         const struct drm_plane_funcs *plane_funcs;
3038         struct intel_plane *plane;
3039         enum drm_plane_type plane_type;
3040         unsigned int supported_rotations;
3041         const u64 *modifiers;
3042         const u32 *formats;
3043         int num_formats;
3044         int ret;
3045
3046         plane = intel_plane_alloc();
3047         if (IS_ERR(plane))
3048                 return plane;
3049
3050         plane->pipe = pipe;
3051         plane->id = plane_id;
3052         plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id);
3053
3054         plane->has_fbc = skl_plane_has_fbc(dev_priv, pipe, plane_id);
3055         if (plane->has_fbc) {
3056                 struct intel_fbc *fbc = &dev_priv->fbc;
3057
3058                 fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
3059         }
3060
3061         plane->max_stride = skl_plane_max_stride;
3062         plane->update_plane = skl_update_plane;
3063         plane->disable_plane = skl_disable_plane;
3064         plane->get_hw_state = skl_plane_get_hw_state;
3065         plane->check_plane = skl_plane_check;
3066         plane->min_cdclk = skl_plane_min_cdclk;
3067
3068         if (INTEL_GEN(dev_priv) >= 11)
3069                 formats = icl_get_plane_formats(dev_priv, pipe,
3070                                                 plane_id, &num_formats);
3071         else if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
3072                 formats = glk_get_plane_formats(dev_priv, pipe,
3073                                                 plane_id, &num_formats);
3074         else
3075                 formats = skl_get_plane_formats(dev_priv, pipe,
3076                                                 plane_id, &num_formats);
3077
3078         plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id);
3079         if (INTEL_GEN(dev_priv) >= 12) {
3080                 modifiers = gen12_get_plane_modifiers(dev_priv, plane_id);
3081                 plane_funcs = &gen12_plane_funcs;
3082         } else {
3083                 if (plane->has_ccs)
3084                         modifiers = skl_plane_format_modifiers_ccs;
3085                 else
3086                         modifiers = skl_plane_format_modifiers_noccs;
3087                 plane_funcs = &skl_plane_funcs;
3088         }
3089
3090         if (plane_id == PLANE_PRIMARY)
3091                 plane_type = DRM_PLANE_TYPE_PRIMARY;
3092         else
3093                 plane_type = DRM_PLANE_TYPE_OVERLAY;
3094
3095         ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
3096                                        0, plane_funcs,
3097                                        formats, num_formats, modifiers,
3098                                        plane_type,
3099                                        "plane %d%c", plane_id + 1,
3100                                        pipe_name(pipe));
3101         if (ret)
3102                 goto fail;
3103
3104         supported_rotations =
3105                 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
3106                 DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
3107
3108         if (INTEL_GEN(dev_priv) >= 10)
3109                 supported_rotations |= DRM_MODE_REFLECT_X;
3110
3111         drm_plane_create_rotation_property(&plane->base,
3112                                            DRM_MODE_ROTATE_0,
3113                                            supported_rotations);
3114
3115         drm_plane_create_color_properties(&plane->base,
3116                                           BIT(DRM_COLOR_YCBCR_BT601) |
3117                                           BIT(DRM_COLOR_YCBCR_BT709),
3118                                           BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
3119                                           BIT(DRM_COLOR_YCBCR_FULL_RANGE),
3120                                           DRM_COLOR_YCBCR_BT709,
3121                                           DRM_COLOR_YCBCR_LIMITED_RANGE);
3122
3123         drm_plane_create_alpha_property(&plane->base);
3124         drm_plane_create_blend_mode_property(&plane->base,
3125                                              BIT(DRM_MODE_BLEND_PIXEL_NONE) |
3126                                              BIT(DRM_MODE_BLEND_PREMULTI) |
3127                                              BIT(DRM_MODE_BLEND_COVERAGE));
3128
3129         drm_plane_create_zpos_immutable_property(&plane->base, plane_id);
3130
3131         drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
3132
3133         return plane;
3134
3135 fail:
3136         intel_plane_free(plane);
3137
3138         return ERR_PTR(ret);
3139 }
3140
3141 struct intel_plane *
3142 intel_sprite_plane_create(struct drm_i915_private *dev_priv,
3143                           enum pipe pipe, int sprite)
3144 {
3145         struct intel_plane *plane;
3146         const struct drm_plane_funcs *plane_funcs;
3147         unsigned int supported_rotations;
3148         const u64 *modifiers;
3149         const u32 *formats;
3150         int num_formats;
3151         int ret, zpos;
3152
3153         if (INTEL_GEN(dev_priv) >= 9)
3154                 return skl_universal_plane_create(dev_priv, pipe,
3155                                                   PLANE_SPRITE0 + sprite);
3156
3157         plane = intel_plane_alloc();
3158         if (IS_ERR(plane))
3159                 return plane;
3160
3161         if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
3162                 plane->max_stride = i9xx_plane_max_stride;
3163                 plane->update_plane = vlv_update_plane;
3164                 plane->disable_plane = vlv_disable_plane;
3165                 plane->get_hw_state = vlv_plane_get_hw_state;
3166                 plane->check_plane = vlv_sprite_check;
3167                 plane->min_cdclk = vlv_plane_min_cdclk;
3168
3169                 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
3170                         formats = chv_pipe_b_sprite_formats;
3171                         num_formats = ARRAY_SIZE(chv_pipe_b_sprite_formats);
3172                 } else {
3173                         formats = vlv_plane_formats;
3174                         num_formats = ARRAY_SIZE(vlv_plane_formats);
3175                 }
3176                 modifiers = i9xx_plane_format_modifiers;
3177
3178                 plane_funcs = &vlv_sprite_funcs;
3179         } else if (INTEL_GEN(dev_priv) >= 7) {
3180                 plane->max_stride = g4x_sprite_max_stride;
3181                 plane->update_plane = ivb_update_plane;
3182                 plane->disable_plane = ivb_disable_plane;
3183                 plane->get_hw_state = ivb_plane_get_hw_state;
3184                 plane->check_plane = g4x_sprite_check;
3185
3186                 if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv))
3187                         plane->min_cdclk = hsw_plane_min_cdclk;
3188                 else
3189                         plane->min_cdclk = ivb_sprite_min_cdclk;
3190
3191                 formats = snb_plane_formats;
3192                 num_formats = ARRAY_SIZE(snb_plane_formats);
3193                 modifiers = i9xx_plane_format_modifiers;
3194
3195                 plane_funcs = &snb_sprite_funcs;
3196         } else {
3197                 plane->max_stride = g4x_sprite_max_stride;
3198                 plane->update_plane = g4x_update_plane;
3199                 plane->disable_plane = g4x_disable_plane;
3200                 plane->get_hw_state = g4x_plane_get_hw_state;
3201                 plane->check_plane = g4x_sprite_check;
3202                 plane->min_cdclk = g4x_sprite_min_cdclk;
3203
3204                 modifiers = i9xx_plane_format_modifiers;
3205                 if (IS_GEN(dev_priv, 6)) {
3206                         formats = snb_plane_formats;
3207                         num_formats = ARRAY_SIZE(snb_plane_formats);
3208
3209                         plane_funcs = &snb_sprite_funcs;
3210                 } else {
3211                         formats = g4x_plane_formats;
3212                         num_formats = ARRAY_SIZE(g4x_plane_formats);
3213
3214                         plane_funcs = &g4x_sprite_funcs;
3215                 }
3216         }
3217
3218         if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
3219                 supported_rotations =
3220                         DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
3221                         DRM_MODE_REFLECT_X;
3222         } else {
3223                 supported_rotations =
3224                         DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
3225         }
3226
3227         plane->pipe = pipe;
3228         plane->id = PLANE_SPRITE0 + sprite;
3229         plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
3230
3231         ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
3232                                        0, plane_funcs,
3233                                        formats, num_formats, modifiers,
3234                                        DRM_PLANE_TYPE_OVERLAY,
3235                                        "sprite %c", sprite_name(pipe, sprite));
3236         if (ret)
3237                 goto fail;
3238
3239         drm_plane_create_rotation_property(&plane->base,
3240                                            DRM_MODE_ROTATE_0,
3241                                            supported_rotations);
3242
3243         drm_plane_create_color_properties(&plane->base,
3244                                           BIT(DRM_COLOR_YCBCR_BT601) |
3245                                           BIT(DRM_COLOR_YCBCR_BT709),
3246                                           BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
3247                                           BIT(DRM_COLOR_YCBCR_FULL_RANGE),
3248                                           DRM_COLOR_YCBCR_BT709,
3249                                           DRM_COLOR_YCBCR_LIMITED_RANGE);
3250
3251         zpos = sprite + 1;
3252         drm_plane_create_zpos_immutable_property(&plane->base, zpos);
3253
3254         drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
3255
3256         return plane;
3257
3258 fail:
3259         intel_plane_free(plane);
3260
3261         return ERR_PTR(ret);
3262 }