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