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