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