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