Merge tag 'mfd-next-5.2' of git://git.kernel.org/pub/scm/linux/kernel/git/lee/mfd
[linux-2.6-microblaze.git] / drivers / gpu / drm / i915 / 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 "intel_atomic_plane.h"
44 #include "intel_drv.h"
45 #include "intel_frontbuffer.h"
46 #include "intel_pm.h"
47 #include "intel_psr.h"
48 #include "intel_sprite.h"
49
50 bool is_planar_yuv_format(u32 pixelformat)
51 {
52         switch (pixelformat) {
53         case DRM_FORMAT_NV12:
54         case DRM_FORMAT_P010:
55         case DRM_FORMAT_P012:
56         case DRM_FORMAT_P016:
57                 return true;
58         default:
59                 return false;
60         }
61 }
62
63 int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
64                              int usecs)
65 {
66         /* paranoia */
67         if (!adjusted_mode->crtc_htotal)
68                 return 1;
69
70         return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock,
71                             1000 * adjusted_mode->crtc_htotal);
72 }
73
74 /* FIXME: We should instead only take spinlocks once for the entire update
75  * instead of once per mmio. */
76 #if IS_ENABLED(CONFIG_PROVE_LOCKING)
77 #define VBLANK_EVASION_TIME_US 250
78 #else
79 #define VBLANK_EVASION_TIME_US 100
80 #endif
81
82 /**
83  * intel_pipe_update_start() - start update of a set of display registers
84  * @new_crtc_state: the new crtc state
85  *
86  * Mark the start of an update to pipe registers that should be updated
87  * atomically regarding vblank. If the next vblank will happens within
88  * the next 100 us, this function waits until the vblank passes.
89  *
90  * After a successful call to this function, interrupts will be disabled
91  * until a subsequent call to intel_pipe_update_end(). That is done to
92  * avoid random delays.
93  */
94 void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
95 {
96         struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
97         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
98         const struct drm_display_mode *adjusted_mode = &new_crtc_state->base.adjusted_mode;
99         long timeout = msecs_to_jiffies_timeout(1);
100         int scanline, min, max, vblank_start;
101         wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
102         bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
103                 intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI);
104         DEFINE_WAIT(wait);
105         u32 psr_status;
106
107         vblank_start = adjusted_mode->crtc_vblank_start;
108         if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
109                 vblank_start = DIV_ROUND_UP(vblank_start, 2);
110
111         /* FIXME needs to be calibrated sensibly */
112         min = vblank_start - intel_usecs_to_scanlines(adjusted_mode,
113                                                       VBLANK_EVASION_TIME_US);
114         max = vblank_start - 1;
115
116         if (min <= 0 || max <= 0)
117                 goto irq_disable;
118
119         if (WARN_ON(drm_crtc_vblank_get(&crtc->base)))
120                 goto irq_disable;
121
122         /*
123          * Wait for psr to idle out after enabling the VBL interrupts
124          * VBL interrupts will start the PSR exit and prevent a PSR
125          * re-entry as well.
126          */
127         if (intel_psr_wait_for_idle(new_crtc_state, &psr_status))
128                 DRM_ERROR("PSR idle timed out 0x%x, atomic update may fail\n",
129                           psr_status);
130
131         local_irq_disable();
132
133         crtc->debug.min_vbl = min;
134         crtc->debug.max_vbl = max;
135         trace_i915_pipe_update_start(crtc);
136
137         for (;;) {
138                 /*
139                  * prepare_to_wait() has a memory barrier, which guarantees
140                  * other CPUs can see the task state update by the time we
141                  * read the scanline.
142                  */
143                 prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
144
145                 scanline = intel_get_crtc_scanline(crtc);
146                 if (scanline < min || scanline > max)
147                         break;
148
149                 if (!timeout) {
150                         DRM_ERROR("Potential atomic update failure on pipe %c\n",
151                                   pipe_name(crtc->pipe));
152                         break;
153                 }
154
155                 local_irq_enable();
156
157                 timeout = schedule_timeout(timeout);
158
159                 local_irq_disable();
160         }
161
162         finish_wait(wq, &wait);
163
164         drm_crtc_vblank_put(&crtc->base);
165
166         /*
167          * On VLV/CHV DSI the scanline counter would appear to
168          * increment approx. 1/3 of a scanline before start of vblank.
169          * The registers still get latched at start of vblank however.
170          * This means we must not write any registers on the first
171          * line of vblank (since not the whole line is actually in
172          * vblank). And unfortunately we can't use the interrupt to
173          * wait here since it will fire too soon. We could use the
174          * frame start interrupt instead since it will fire after the
175          * critical scanline, but that would require more changes
176          * in the interrupt code. So for now we'll just do the nasty
177          * thing and poll for the bad scanline to pass us by.
178          *
179          * FIXME figure out if BXT+ DSI suffers from this as well
180          */
181         while (need_vlv_dsi_wa && scanline == vblank_start)
182                 scanline = intel_get_crtc_scanline(crtc);
183
184         crtc->debug.scanline_start = scanline;
185         crtc->debug.start_vbl_time = ktime_get();
186         crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc);
187
188         trace_i915_pipe_update_vblank_evaded(crtc);
189         return;
190
191 irq_disable:
192         local_irq_disable();
193 }
194
195 /**
196  * intel_pipe_update_end() - end update of a set of display registers
197  * @new_crtc_state: the new crtc state
198  *
199  * Mark the end of an update started with intel_pipe_update_start(). This
200  * re-enables interrupts and verifies the update was actually completed
201  * before a vblank.
202  */
203 void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
204 {
205         struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
206         enum pipe pipe = crtc->pipe;
207         int scanline_end = intel_get_crtc_scanline(crtc);
208         u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc);
209         ktime_t end_vbl_time = ktime_get();
210         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
211
212         trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end);
213
214         /* We're still in the vblank-evade critical section, this can't race.
215          * Would be slightly nice to just grab the vblank count and arm the
216          * event outside of the critical section - the spinlock might spin for a
217          * while ... */
218         if (new_crtc_state->base.event) {
219                 WARN_ON(drm_crtc_vblank_get(&crtc->base) != 0);
220
221                 spin_lock(&crtc->base.dev->event_lock);
222                 drm_crtc_arm_vblank_event(&crtc->base, new_crtc_state->base.event);
223                 spin_unlock(&crtc->base.dev->event_lock);
224
225                 new_crtc_state->base.event = NULL;
226         }
227
228         local_irq_enable();
229
230         if (intel_vgpu_active(dev_priv))
231                 return;
232
233         if (crtc->debug.start_vbl_count &&
234             crtc->debug.start_vbl_count != end_vbl_count) {
235                 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",
236                           pipe_name(pipe), crtc->debug.start_vbl_count,
237                           end_vbl_count,
238                           ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
239                           crtc->debug.min_vbl, crtc->debug.max_vbl,
240                           crtc->debug.scanline_start, scanline_end);
241         }
242 #ifdef CONFIG_DRM_I915_DEBUG_VBLANK_EVADE
243         else if (ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time) >
244                  VBLANK_EVASION_TIME_US)
245                 DRM_WARN("Atomic update on pipe (%c) took %lld us, max time under evasion is %u us\n",
246                          pipe_name(pipe),
247                          ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
248                          VBLANK_EVASION_TIME_US);
249 #endif
250 }
251
252 int intel_plane_check_stride(const struct intel_plane_state *plane_state)
253 {
254         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
255         const struct drm_framebuffer *fb = plane_state->base.fb;
256         unsigned int rotation = plane_state->base.rotation;
257         u32 stride, max_stride;
258
259         /* FIXME other color planes? */
260         stride = plane_state->color_plane[0].stride;
261         max_stride = plane->max_stride(plane, fb->format->format,
262                                        fb->modifier, rotation);
263
264         if (stride > max_stride) {
265                 DRM_DEBUG_KMS("[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n",
266                               fb->base.id, stride,
267                               plane->base.base.id, plane->base.name, max_stride);
268                 return -EINVAL;
269         }
270
271         return 0;
272 }
273
274 int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
275 {
276         const struct drm_framebuffer *fb = plane_state->base.fb;
277         struct drm_rect *src = &plane_state->base.src;
278         u32 src_x, src_y, src_w, src_h, hsub, vsub;
279         bool rotated = drm_rotation_90_or_270(plane_state->base.rotation);
280
281         /*
282          * Hardware doesn't handle subpixel coordinates.
283          * Adjust to (macro)pixel boundary, but be careful not to
284          * increase the source viewport size, because that could
285          * push the downscaling factor out of bounds.
286          */
287         src_x = src->x1 >> 16;
288         src_w = drm_rect_width(src) >> 16;
289         src_y = src->y1 >> 16;
290         src_h = drm_rect_height(src) >> 16;
291
292         src->x1 = src_x << 16;
293         src->x2 = (src_x + src_w) << 16;
294         src->y1 = src_y << 16;
295         src->y2 = (src_y + src_h) << 16;
296
297         if (!fb->format->is_yuv)
298                 return 0;
299
300         /* YUV specific checks */
301         if (!rotated) {
302                 hsub = fb->format->hsub;
303                 vsub = fb->format->vsub;
304         } else {
305                 hsub = vsub = max(fb->format->hsub, fb->format->vsub);
306         }
307
308         if (src_x % hsub || src_w % hsub) {
309                 DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of %u for %sYUV planes\n",
310                               src_x, src_w, hsub, rotated ? "rotated " : "");
311                 return -EINVAL;
312         }
313
314         if (src_y % vsub || src_h % vsub) {
315                 DRM_DEBUG_KMS("src y/h (%u, %u) must be a multiple of %u for %sYUV planes\n",
316                               src_y, src_h, vsub, rotated ? "rotated " : "");
317                 return -EINVAL;
318         }
319
320         return 0;
321 }
322
323 static unsigned int
324 skl_plane_max_stride(struct intel_plane *plane,
325                      u32 pixel_format, u64 modifier,
326                      unsigned int rotation)
327 {
328         int cpp = drm_format_plane_cpp(pixel_format, 0);
329
330         /*
331          * "The stride in bytes must not exceed the
332          * of the size of 8K pixels and 32K bytes."
333          */
334         if (drm_rotation_90_or_270(rotation))
335                 return min(8192, 32768 / cpp);
336         else
337                 return min(8192 * cpp, 32768);
338 }
339
340 static void
341 skl_program_scaler(struct intel_plane *plane,
342                    const struct intel_crtc_state *crtc_state,
343                    const struct intel_plane_state *plane_state)
344 {
345         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
346         enum pipe pipe = plane->pipe;
347         int scaler_id = plane_state->scaler_id;
348         const struct intel_scaler *scaler =
349                 &crtc_state->scaler_state.scalers[scaler_id];
350         int crtc_x = plane_state->base.dst.x1;
351         int crtc_y = plane_state->base.dst.y1;
352         u32 crtc_w = drm_rect_width(&plane_state->base.dst);
353         u32 crtc_h = drm_rect_height(&plane_state->base.dst);
354         u16 y_hphase, uv_rgb_hphase;
355         u16 y_vphase, uv_rgb_vphase;
356         int hscale, vscale;
357
358         hscale = drm_rect_calc_hscale(&plane_state->base.src,
359                                       &plane_state->base.dst,
360                                       0, INT_MAX);
361         vscale = drm_rect_calc_vscale(&plane_state->base.src,
362                                       &plane_state->base.dst,
363                                       0, INT_MAX);
364
365         /* TODO: handle sub-pixel coordinates */
366         if (is_planar_yuv_format(plane_state->base.fb->format->format) &&
367             !icl_is_hdr_plane(dev_priv, plane->id)) {
368                 y_hphase = skl_scaler_calc_phase(1, hscale, false);
369                 y_vphase = skl_scaler_calc_phase(1, vscale, false);
370
371                 /* MPEG2 chroma siting convention */
372                 uv_rgb_hphase = skl_scaler_calc_phase(2, hscale, true);
373                 uv_rgb_vphase = skl_scaler_calc_phase(2, vscale, false);
374         } else {
375                 /* not used */
376                 y_hphase = 0;
377                 y_vphase = 0;
378
379                 uv_rgb_hphase = skl_scaler_calc_phase(1, hscale, false);
380                 uv_rgb_vphase = skl_scaler_calc_phase(1, vscale, false);
381         }
382
383         I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
384                       PS_SCALER_EN | PS_PLANE_SEL(plane->id) | scaler->mode);
385         I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
386                       PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
387         I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
388                       PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
389         I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
390         I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id), (crtc_w << 16) | crtc_h);
391 }
392
393 /* Preoffset values for YUV to RGB Conversion */
394 #define PREOFF_YUV_TO_RGB_HI            0x1800
395 #define PREOFF_YUV_TO_RGB_ME            0x1F00
396 #define PREOFF_YUV_TO_RGB_LO            0x1800
397
398 #define  ROFF(x)          (((x) & 0xffff) << 16)
399 #define  GOFF(x)          (((x) & 0xffff) << 0)
400 #define  BOFF(x)          (((x) & 0xffff) << 16)
401
402 static void
403 icl_program_input_csc(struct intel_plane *plane,
404                       const struct intel_crtc_state *crtc_state,
405                       const struct intel_plane_state *plane_state)
406 {
407         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
408         enum pipe pipe = plane->pipe;
409         enum plane_id plane_id = plane->id;
410
411         static const u16 input_csc_matrix[][9] = {
412                 /*
413                  * BT.601 full range YCbCr -> full range RGB
414                  * The matrix required is :
415                  * [1.000, 0.000, 1.371,
416                  *  1.000, -0.336, -0.698,
417                  *  1.000, 1.732, 0.0000]
418                  */
419                 [DRM_COLOR_YCBCR_BT601] = {
420                         0x7AF8, 0x7800, 0x0,
421                         0x8B28, 0x7800, 0x9AC0,
422                         0x0, 0x7800, 0x7DD8,
423                 },
424                 /*
425                  * BT.709 full range YCbCr -> full range RGB
426                  * The matrix required is :
427                  * [1.000, 0.000, 1.574,
428                  *  1.000, -0.187, -0.468,
429                  *  1.000, 1.855, 0.0000]
430                  */
431                 [DRM_COLOR_YCBCR_BT709] = {
432                         0x7C98, 0x7800, 0x0,
433                         0x9EF8, 0x7800, 0xABF8,
434                         0x0, 0x7800,  0x7ED8,
435                 },
436         };
437
438         /* Matrix for Limited Range to Full Range Conversion */
439         static const u16 input_csc_matrix_lr[][9] = {
440                 /*
441                  * BT.601 Limted range YCbCr -> full range RGB
442                  * The matrix required is :
443                  * [1.164384, 0.000, 1.596370,
444                  *  1.138393, -0.382500, -0.794598,
445                  *  1.138393, 1.971696, 0.0000]
446                  */
447                 [DRM_COLOR_YCBCR_BT601] = {
448                         0x7CC8, 0x7950, 0x0,
449                         0x8CB8, 0x7918, 0x9C40,
450                         0x0, 0x7918, 0x7FC8,
451                 },
452                 /*
453                  * BT.709 Limited range YCbCr -> full range RGB
454                  * The matrix required is :
455                  * [1.164, 0.000, 1.833671,
456                  *  1.138393, -0.213249, -0.532909,
457                  *  1.138393, 2.112402, 0.0000]
458                  */
459                 [DRM_COLOR_YCBCR_BT709] = {
460                         0x7EA8, 0x7950, 0x0,
461                         0x8888, 0x7918, 0xADA8,
462                         0x0, 0x7918,  0x6870,
463                 },
464         };
465         const u16 *csc;
466
467         if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
468                 csc = input_csc_matrix[plane_state->base.color_encoding];
469         else
470                 csc = input_csc_matrix_lr[plane_state->base.color_encoding];
471
472         I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 0), ROFF(csc[0]) |
473                       GOFF(csc[1]));
474         I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 1), BOFF(csc[2]));
475         I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 2), ROFF(csc[3]) |
476                       GOFF(csc[4]));
477         I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 3), BOFF(csc[5]));
478         I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 4), ROFF(csc[6]) |
479                       GOFF(csc[7]));
480         I915_WRITE_FW(PLANE_INPUT_CSC_COEFF(pipe, plane_id, 5), BOFF(csc[8]));
481
482         I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 0),
483                       PREOFF_YUV_TO_RGB_HI);
484         I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 1),
485                       PREOFF_YUV_TO_RGB_ME);
486         I915_WRITE_FW(PLANE_INPUT_CSC_PREOFF(pipe, plane_id, 2),
487                       PREOFF_YUV_TO_RGB_LO);
488         I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 0), 0x0);
489         I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 1), 0x0);
490         I915_WRITE_FW(PLANE_INPUT_CSC_POSTOFF(pipe, plane_id, 2), 0x0);
491 }
492
493 static void
494 skl_program_plane(struct intel_plane *plane,
495                   const struct intel_crtc_state *crtc_state,
496                   const struct intel_plane_state *plane_state,
497                   int color_plane, bool slave, u32 plane_ctl)
498 {
499         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
500         enum plane_id plane_id = plane->id;
501         enum pipe pipe = plane->pipe;
502         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
503         u32 surf_addr = plane_state->color_plane[color_plane].offset;
504         u32 stride = skl_plane_stride(plane_state, color_plane);
505         u32 aux_stride = skl_plane_stride(plane_state, 1);
506         int crtc_x = plane_state->base.dst.x1;
507         int crtc_y = plane_state->base.dst.y1;
508         u32 x = plane_state->color_plane[color_plane].x;
509         u32 y = plane_state->color_plane[color_plane].y;
510         u32 src_w = drm_rect_width(&plane_state->base.src) >> 16;
511         u32 src_h = drm_rect_height(&plane_state->base.src) >> 16;
512         struct intel_plane *linked = plane_state->linked_plane;
513         const struct drm_framebuffer *fb = plane_state->base.fb;
514         u8 alpha = plane_state->base.alpha >> 8;
515         u32 plane_color_ctl = 0;
516         unsigned long irqflags;
517         u32 keymsk, keymax;
518
519         plane_ctl |= skl_plane_ctl_crtc(crtc_state);
520
521         if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
522                 plane_color_ctl = plane_state->color_ctl |
523                         glk_plane_color_ctl_crtc(crtc_state);
524
525         /* Sizes are 0 based */
526         src_w--;
527         src_h--;
528
529         keymax = (key->max_value & 0xffffff) | PLANE_KEYMAX_ALPHA(alpha);
530
531         keymsk = key->channel_mask & 0x7ffffff;
532         if (alpha < 0xff)
533                 keymsk |= PLANE_KEYMSK_ALPHA_ENABLE;
534
535         /* The scaler will handle the output position */
536         if (plane_state->scaler_id >= 0) {
537                 crtc_x = 0;
538                 crtc_y = 0;
539         }
540
541         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
542
543         I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
544         I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
545         I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
546         I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
547                       (plane_state->color_plane[1].offset - surf_addr) | aux_stride);
548
549         if (icl_is_hdr_plane(dev_priv, plane_id)) {
550                 u32 cus_ctl = 0;
551
552                 if (linked) {
553                         /* Enable and use MPEG-2 chroma siting */
554                         cus_ctl = PLANE_CUS_ENABLE |
555                                 PLANE_CUS_HPHASE_0 |
556                                 PLANE_CUS_VPHASE_SIGN_NEGATIVE |
557                                 PLANE_CUS_VPHASE_0_25;
558
559                         if (linked->id == PLANE_SPRITE5)
560                                 cus_ctl |= PLANE_CUS_PLANE_7;
561                         else if (linked->id == PLANE_SPRITE4)
562                                 cus_ctl |= PLANE_CUS_PLANE_6;
563                         else
564                                 MISSING_CASE(linked->id);
565                 }
566
567                 I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), cus_ctl);
568         }
569
570         if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
571                 I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id), plane_color_ctl);
572
573         if (fb->format->is_yuv && icl_is_hdr_plane(dev_priv, plane_id))
574                 icl_program_input_csc(plane, crtc_state, plane_state);
575
576         skl_write_plane_wm(plane, crtc_state);
577
578         I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
579         I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), keymsk);
580         I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), keymax);
581
582         I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
583
584         if (INTEL_GEN(dev_priv) < 11)
585                 I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
586                               (plane_state->color_plane[1].y << 16) |
587                               plane_state->color_plane[1].x);
588
589         /*
590          * The control register self-arms if the plane was previously
591          * disabled. Try to make the plane enable atomic by writing
592          * the control register just before the surface register.
593          */
594         I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
595         I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
596                       intel_plane_ggtt_offset(plane_state) + surf_addr);
597
598         if (!slave && plane_state->scaler_id >= 0)
599                 skl_program_scaler(plane, crtc_state, plane_state);
600
601         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
602 }
603
604 static void
605 skl_update_plane(struct intel_plane *plane,
606                  const struct intel_crtc_state *crtc_state,
607                  const struct intel_plane_state *plane_state)
608 {
609         int color_plane = 0;
610
611         if (plane_state->linked_plane) {
612                 /* Program the UV plane */
613                 color_plane = 1;
614         }
615
616         skl_program_plane(plane, crtc_state, plane_state,
617                           color_plane, false, plane_state->ctl);
618 }
619
620 static void
621 icl_update_slave(struct intel_plane *plane,
622                  const struct intel_crtc_state *crtc_state,
623                  const struct intel_plane_state *plane_state)
624 {
625         skl_program_plane(plane, crtc_state, plane_state, 0, true,
626                           plane_state->ctl | PLANE_CTL_YUV420_Y_PLANE);
627 }
628
629 static void
630 skl_disable_plane(struct intel_plane *plane,
631                   const struct intel_crtc_state *crtc_state)
632 {
633         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
634         enum plane_id plane_id = plane->id;
635         enum pipe pipe = plane->pipe;
636         unsigned long irqflags;
637
638         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
639
640         if (icl_is_hdr_plane(dev_priv, plane_id))
641                 I915_WRITE_FW(PLANE_CUS_CTL(pipe, plane_id), 0);
642
643         skl_write_plane_wm(plane, crtc_state);
644
645         I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0);
646         I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0);
647
648         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
649 }
650
651 static bool
652 skl_plane_get_hw_state(struct intel_plane *plane,
653                        enum pipe *pipe)
654 {
655         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
656         enum intel_display_power_domain power_domain;
657         enum plane_id plane_id = plane->id;
658         intel_wakeref_t wakeref;
659         bool ret;
660
661         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
662         wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
663         if (!wakeref)
664                 return false;
665
666         ret = I915_READ(PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE;
667
668         *pipe = plane->pipe;
669
670         intel_display_power_put(dev_priv, power_domain, wakeref);
671
672         return ret;
673 }
674
675 static void
676 chv_update_csc(const struct intel_plane_state *plane_state)
677 {
678         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
679         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
680         const struct drm_framebuffer *fb = plane_state->base.fb;
681         enum plane_id plane_id = plane->id;
682         /*
683          * |r|   | c0 c1 c2 |   |cr|
684          * |g| = | c3 c4 c5 | x |y |
685          * |b|   | c6 c7 c8 |   |cb|
686          *
687          * Coefficients are s3.12.
688          *
689          * Cb and Cr apparently come in as signed already, and
690          * we always get full range data in on account of CLRC0/1.
691          */
692         static const s16 csc_matrix[][9] = {
693                 /* BT.601 full range YCbCr -> full range RGB */
694                 [DRM_COLOR_YCBCR_BT601] = {
695                          5743, 4096,     0,
696                         -2925, 4096, -1410,
697                             0, 4096,  7258,
698                 },
699                 /* BT.709 full range YCbCr -> full range RGB */
700                 [DRM_COLOR_YCBCR_BT709] = {
701                          6450, 4096,     0,
702                         -1917, 4096,  -767,
703                             0, 4096,  7601,
704                 },
705         };
706         const s16 *csc = csc_matrix[plane_state->base.color_encoding];
707
708         /* Seems RGB data bypasses the CSC always */
709         if (!fb->format->is_yuv)
710                 return;
711
712         I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
713         I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
714         I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
715
716         I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(csc[1]) | SPCSC_C0(csc[0]));
717         I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(csc[3]) | SPCSC_C0(csc[2]));
718         I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(csc[5]) | SPCSC_C0(csc[4]));
719         I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(csc[7]) | SPCSC_C0(csc[6]));
720         I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(csc[8]));
721
722         I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(1023) | SPCSC_IMIN(0));
723         I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
724         I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
725
726         I915_WRITE_FW(SPCSCYGOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
727         I915_WRITE_FW(SPCSCCBOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
728         I915_WRITE_FW(SPCSCCROCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
729 }
730
731 #define SIN_0 0
732 #define COS_0 1
733
734 static void
735 vlv_update_clrc(const struct intel_plane_state *plane_state)
736 {
737         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
738         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
739         const struct drm_framebuffer *fb = plane_state->base.fb;
740         enum pipe pipe = plane->pipe;
741         enum plane_id plane_id = plane->id;
742         int contrast, brightness, sh_scale, sh_sin, sh_cos;
743
744         if (fb->format->is_yuv &&
745             plane_state->base.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) {
746                 /*
747                  * Expand limited range to full range:
748                  * Contrast is applied first and is used to expand Y range.
749                  * Brightness is applied second and is used to remove the
750                  * offset from Y. Saturation/hue is used to expand CbCr range.
751                  */
752                 contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16);
753                 brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16);
754                 sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128);
755                 sh_sin = SIN_0 * sh_scale;
756                 sh_cos = COS_0 * sh_scale;
757         } else {
758                 /* Pass-through everything. */
759                 contrast = 1 << 6;
760                 brightness = 0;
761                 sh_scale = 1 << 7;
762                 sh_sin = SIN_0 * sh_scale;
763                 sh_cos = COS_0 * sh_scale;
764         }
765
766         /* FIXME these register are single buffered :( */
767         I915_WRITE_FW(SPCLRC0(pipe, plane_id),
768                       SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness));
769         I915_WRITE_FW(SPCLRC1(pipe, plane_id),
770                       SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos));
771 }
772
773 static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
774 {
775         u32 sprctl = 0;
776
777         if (crtc_state->gamma_enable)
778                 sprctl |= SP_GAMMA_ENABLE;
779
780         return sprctl;
781 }
782
783 static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state,
784                           const struct intel_plane_state *plane_state)
785 {
786         const struct drm_framebuffer *fb = plane_state->base.fb;
787         unsigned int rotation = plane_state->base.rotation;
788         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
789         u32 sprctl;
790
791         sprctl = SP_ENABLE;
792
793         switch (fb->format->format) {
794         case DRM_FORMAT_YUYV:
795                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
796                 break;
797         case DRM_FORMAT_YVYU:
798                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
799                 break;
800         case DRM_FORMAT_UYVY:
801                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
802                 break;
803         case DRM_FORMAT_VYUY:
804                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
805                 break;
806         case DRM_FORMAT_RGB565:
807                 sprctl |= SP_FORMAT_BGR565;
808                 break;
809         case DRM_FORMAT_XRGB8888:
810                 sprctl |= SP_FORMAT_BGRX8888;
811                 break;
812         case DRM_FORMAT_ARGB8888:
813                 sprctl |= SP_FORMAT_BGRA8888;
814                 break;
815         case DRM_FORMAT_XBGR2101010:
816                 sprctl |= SP_FORMAT_RGBX1010102;
817                 break;
818         case DRM_FORMAT_ABGR2101010:
819                 sprctl |= SP_FORMAT_RGBA1010102;
820                 break;
821         case DRM_FORMAT_XBGR8888:
822                 sprctl |= SP_FORMAT_RGBX8888;
823                 break;
824         case DRM_FORMAT_ABGR8888:
825                 sprctl |= SP_FORMAT_RGBA8888;
826                 break;
827         default:
828                 MISSING_CASE(fb->format->format);
829                 return 0;
830         }
831
832         if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
833                 sprctl |= SP_YUV_FORMAT_BT709;
834
835         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
836                 sprctl |= SP_TILED;
837
838         if (rotation & DRM_MODE_ROTATE_180)
839                 sprctl |= SP_ROTATE_180;
840
841         if (rotation & DRM_MODE_REFLECT_X)
842                 sprctl |= SP_MIRROR;
843
844         if (key->flags & I915_SET_COLORKEY_SOURCE)
845                 sprctl |= SP_SOURCE_KEY;
846
847         return sprctl;
848 }
849
850 static void
851 vlv_update_plane(struct intel_plane *plane,
852                  const struct intel_crtc_state *crtc_state,
853                  const struct intel_plane_state *plane_state)
854 {
855         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
856         enum pipe pipe = plane->pipe;
857         enum plane_id plane_id = plane->id;
858         u32 sprsurf_offset = plane_state->color_plane[0].offset;
859         u32 linear_offset;
860         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
861         int crtc_x = plane_state->base.dst.x1;
862         int crtc_y = plane_state->base.dst.y1;
863         u32 crtc_w = drm_rect_width(&plane_state->base.dst);
864         u32 crtc_h = drm_rect_height(&plane_state->base.dst);
865         u32 x = plane_state->color_plane[0].x;
866         u32 y = plane_state->color_plane[0].y;
867         unsigned long irqflags;
868         u32 sprctl;
869
870         sprctl = plane_state->ctl | vlv_sprite_ctl_crtc(crtc_state);
871
872         /* Sizes are 0 based */
873         crtc_w--;
874         crtc_h--;
875
876         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
877
878         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
879
880         I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
881                       plane_state->color_plane[0].stride);
882         I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
883         I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
884         I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
885
886         if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
887                 chv_update_csc(plane_state);
888
889         if (key->flags) {
890                 I915_WRITE_FW(SPKEYMINVAL(pipe, plane_id), key->min_value);
891                 I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask);
892                 I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value);
893         }
894
895         I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
896         I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
897
898         /*
899          * The control register self-arms if the plane was previously
900          * disabled. Try to make the plane enable atomic by writing
901          * the control register just before the surface register.
902          */
903         I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl);
904         I915_WRITE_FW(SPSURF(pipe, plane_id),
905                       intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
906
907         vlv_update_clrc(plane_state);
908
909         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
910 }
911
912 static void
913 vlv_disable_plane(struct intel_plane *plane,
914                   const struct intel_crtc_state *crtc_state)
915 {
916         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
917         enum pipe pipe = plane->pipe;
918         enum plane_id plane_id = plane->id;
919         unsigned long irqflags;
920
921         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
922
923         I915_WRITE_FW(SPCNTR(pipe, plane_id), 0);
924         I915_WRITE_FW(SPSURF(pipe, plane_id), 0);
925
926         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
927 }
928
929 static bool
930 vlv_plane_get_hw_state(struct intel_plane *plane,
931                        enum pipe *pipe)
932 {
933         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
934         enum intel_display_power_domain power_domain;
935         enum plane_id plane_id = plane->id;
936         intel_wakeref_t wakeref;
937         bool ret;
938
939         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
940         wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
941         if (!wakeref)
942                 return false;
943
944         ret = I915_READ(SPCNTR(plane->pipe, plane_id)) & SP_ENABLE;
945
946         *pipe = plane->pipe;
947
948         intel_display_power_put(dev_priv, power_domain, wakeref);
949
950         return ret;
951 }
952
953 static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
954 {
955         u32 sprctl = 0;
956
957         if (crtc_state->gamma_enable)
958                 sprctl |= SPRITE_GAMMA_ENABLE;
959
960         if (crtc_state->csc_enable)
961                 sprctl |= SPRITE_PIPE_CSC_ENABLE;
962
963         return sprctl;
964 }
965
966 static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
967                           const struct intel_plane_state *plane_state)
968 {
969         struct drm_i915_private *dev_priv =
970                 to_i915(plane_state->base.plane->dev);
971         const struct drm_framebuffer *fb = plane_state->base.fb;
972         unsigned int rotation = plane_state->base.rotation;
973         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
974         u32 sprctl;
975
976         sprctl = SPRITE_ENABLE;
977
978         if (IS_IVYBRIDGE(dev_priv))
979                 sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
980
981         switch (fb->format->format) {
982         case DRM_FORMAT_XBGR8888:
983                 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
984                 break;
985         case DRM_FORMAT_XRGB8888:
986                 sprctl |= SPRITE_FORMAT_RGBX888;
987                 break;
988         case DRM_FORMAT_YUYV:
989                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
990                 break;
991         case DRM_FORMAT_YVYU:
992                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
993                 break;
994         case DRM_FORMAT_UYVY:
995                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
996                 break;
997         case DRM_FORMAT_VYUY:
998                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
999                 break;
1000         default:
1001                 MISSING_CASE(fb->format->format);
1002                 return 0;
1003         }
1004
1005         if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
1006                 sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
1007
1008         if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
1009                 sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE;
1010
1011         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
1012                 sprctl |= SPRITE_TILED;
1013
1014         if (rotation & DRM_MODE_ROTATE_180)
1015                 sprctl |= SPRITE_ROTATE_180;
1016
1017         if (key->flags & I915_SET_COLORKEY_DESTINATION)
1018                 sprctl |= SPRITE_DEST_KEY;
1019         else if (key->flags & I915_SET_COLORKEY_SOURCE)
1020                 sprctl |= SPRITE_SOURCE_KEY;
1021
1022         return sprctl;
1023 }
1024
1025 static void
1026 ivb_update_plane(struct intel_plane *plane,
1027                  const struct intel_crtc_state *crtc_state,
1028                  const struct intel_plane_state *plane_state)
1029 {
1030         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1031         enum pipe pipe = plane->pipe;
1032         u32 sprsurf_offset = plane_state->color_plane[0].offset;
1033         u32 linear_offset;
1034         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1035         int crtc_x = plane_state->base.dst.x1;
1036         int crtc_y = plane_state->base.dst.y1;
1037         u32 crtc_w = drm_rect_width(&plane_state->base.dst);
1038         u32 crtc_h = drm_rect_height(&plane_state->base.dst);
1039         u32 x = plane_state->color_plane[0].x;
1040         u32 y = plane_state->color_plane[0].y;
1041         u32 src_w = drm_rect_width(&plane_state->base.src) >> 16;
1042         u32 src_h = drm_rect_height(&plane_state->base.src) >> 16;
1043         u32 sprctl, sprscale = 0;
1044         unsigned long irqflags;
1045
1046         sprctl = plane_state->ctl | ivb_sprite_ctl_crtc(crtc_state);
1047
1048         /* Sizes are 0 based */
1049         src_w--;
1050         src_h--;
1051         crtc_w--;
1052         crtc_h--;
1053
1054         if (crtc_w != src_w || crtc_h != src_h)
1055                 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
1056
1057         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
1058
1059         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1060
1061         I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
1062         I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
1063         I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
1064         if (IS_IVYBRIDGE(dev_priv))
1065                 I915_WRITE_FW(SPRSCALE(pipe), sprscale);
1066
1067         if (key->flags) {
1068                 I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value);
1069                 I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask);
1070                 I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value);
1071         }
1072
1073         /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
1074          * register */
1075         if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
1076                 I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x);
1077         } else {
1078                 I915_WRITE_FW(SPRLINOFF(pipe), linear_offset);
1079                 I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x);
1080         }
1081
1082         /*
1083          * The control register self-arms if the plane was previously
1084          * disabled. Try to make the plane enable atomic by writing
1085          * the control register just before the surface register.
1086          */
1087         I915_WRITE_FW(SPRCTL(pipe), sprctl);
1088         I915_WRITE_FW(SPRSURF(pipe),
1089                       intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
1090
1091         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1092 }
1093
1094 static void
1095 ivb_disable_plane(struct intel_plane *plane,
1096                   const struct intel_crtc_state *crtc_state)
1097 {
1098         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1099         enum pipe pipe = plane->pipe;
1100         unsigned long irqflags;
1101
1102         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1103
1104         I915_WRITE_FW(SPRCTL(pipe), 0);
1105         /* Disable the scaler */
1106         if (IS_IVYBRIDGE(dev_priv))
1107                 I915_WRITE_FW(SPRSCALE(pipe), 0);
1108         I915_WRITE_FW(SPRSURF(pipe), 0);
1109
1110         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1111 }
1112
1113 static bool
1114 ivb_plane_get_hw_state(struct intel_plane *plane,
1115                        enum pipe *pipe)
1116 {
1117         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1118         enum intel_display_power_domain power_domain;
1119         intel_wakeref_t wakeref;
1120         bool ret;
1121
1122         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
1123         wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
1124         if (!wakeref)
1125                 return false;
1126
1127         ret =  I915_READ(SPRCTL(plane->pipe)) & SPRITE_ENABLE;
1128
1129         *pipe = plane->pipe;
1130
1131         intel_display_power_put(dev_priv, power_domain, wakeref);
1132
1133         return ret;
1134 }
1135
1136 static unsigned int
1137 g4x_sprite_max_stride(struct intel_plane *plane,
1138                       u32 pixel_format, u64 modifier,
1139                       unsigned int rotation)
1140 {
1141         return 16384;
1142 }
1143
1144 static u32 g4x_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
1145 {
1146         u32 dvscntr = 0;
1147
1148         if (crtc_state->gamma_enable)
1149                 dvscntr |= DVS_GAMMA_ENABLE;
1150
1151         if (crtc_state->csc_enable)
1152                 dvscntr |= DVS_PIPE_CSC_ENABLE;
1153
1154         return dvscntr;
1155 }
1156
1157 static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state,
1158                           const struct intel_plane_state *plane_state)
1159 {
1160         struct drm_i915_private *dev_priv =
1161                 to_i915(plane_state->base.plane->dev);
1162         const struct drm_framebuffer *fb = plane_state->base.fb;
1163         unsigned int rotation = plane_state->base.rotation;
1164         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1165         u32 dvscntr;
1166
1167         dvscntr = DVS_ENABLE;
1168
1169         if (IS_GEN(dev_priv, 6))
1170                 dvscntr |= DVS_TRICKLE_FEED_DISABLE;
1171
1172         switch (fb->format->format) {
1173         case DRM_FORMAT_XBGR8888:
1174                 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
1175                 break;
1176         case DRM_FORMAT_XRGB8888:
1177                 dvscntr |= DVS_FORMAT_RGBX888;
1178                 break;
1179         case DRM_FORMAT_YUYV:
1180                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
1181                 break;
1182         case DRM_FORMAT_YVYU:
1183                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
1184                 break;
1185         case DRM_FORMAT_UYVY:
1186                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
1187                 break;
1188         case DRM_FORMAT_VYUY:
1189                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
1190                 break;
1191         default:
1192                 MISSING_CASE(fb->format->format);
1193                 return 0;
1194         }
1195
1196         if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
1197                 dvscntr |= DVS_YUV_FORMAT_BT709;
1198
1199         if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
1200                 dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE;
1201
1202         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
1203                 dvscntr |= DVS_TILED;
1204
1205         if (rotation & DRM_MODE_ROTATE_180)
1206                 dvscntr |= DVS_ROTATE_180;
1207
1208         if (key->flags & I915_SET_COLORKEY_DESTINATION)
1209                 dvscntr |= DVS_DEST_KEY;
1210         else if (key->flags & I915_SET_COLORKEY_SOURCE)
1211                 dvscntr |= DVS_SOURCE_KEY;
1212
1213         return dvscntr;
1214 }
1215
1216 static void
1217 g4x_update_plane(struct intel_plane *plane,
1218                  const struct intel_crtc_state *crtc_state,
1219                  const struct intel_plane_state *plane_state)
1220 {
1221         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1222         enum pipe pipe = plane->pipe;
1223         u32 dvssurf_offset = plane_state->color_plane[0].offset;
1224         u32 linear_offset;
1225         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1226         int crtc_x = plane_state->base.dst.x1;
1227         int crtc_y = plane_state->base.dst.y1;
1228         u32 crtc_w = drm_rect_width(&plane_state->base.dst);
1229         u32 crtc_h = drm_rect_height(&plane_state->base.dst);
1230         u32 x = plane_state->color_plane[0].x;
1231         u32 y = plane_state->color_plane[0].y;
1232         u32 src_w = drm_rect_width(&plane_state->base.src) >> 16;
1233         u32 src_h = drm_rect_height(&plane_state->base.src) >> 16;
1234         u32 dvscntr, dvsscale = 0;
1235         unsigned long irqflags;
1236
1237         dvscntr = plane_state->ctl | g4x_sprite_ctl_crtc(crtc_state);
1238
1239         /* Sizes are 0 based */
1240         src_w--;
1241         src_h--;
1242         crtc_w--;
1243         crtc_h--;
1244
1245         if (crtc_w != src_w || crtc_h != src_h)
1246                 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
1247
1248         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
1249
1250         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1251
1252         I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
1253         I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
1254         I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
1255         I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
1256
1257         if (key->flags) {
1258                 I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value);
1259                 I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask);
1260                 I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value);
1261         }
1262
1263         I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
1264         I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
1265
1266         /*
1267          * The control register self-arms if the plane was previously
1268          * disabled. Try to make the plane enable atomic by writing
1269          * the control register just before the surface register.
1270          */
1271         I915_WRITE_FW(DVSCNTR(pipe), dvscntr);
1272         I915_WRITE_FW(DVSSURF(pipe),
1273                       intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
1274
1275         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1276 }
1277
1278 static void
1279 g4x_disable_plane(struct intel_plane *plane,
1280                   const struct intel_crtc_state *crtc_state)
1281 {
1282         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1283         enum pipe pipe = plane->pipe;
1284         unsigned long irqflags;
1285
1286         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1287
1288         I915_WRITE_FW(DVSCNTR(pipe), 0);
1289         /* Disable the scaler */
1290         I915_WRITE_FW(DVSSCALE(pipe), 0);
1291         I915_WRITE_FW(DVSSURF(pipe), 0);
1292
1293         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1294 }
1295
1296 static bool
1297 g4x_plane_get_hw_state(struct intel_plane *plane,
1298                        enum pipe *pipe)
1299 {
1300         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1301         enum intel_display_power_domain power_domain;
1302         intel_wakeref_t wakeref;
1303         bool ret;
1304
1305         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
1306         wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
1307         if (!wakeref)
1308                 return false;
1309
1310         ret = I915_READ(DVSCNTR(plane->pipe)) & DVS_ENABLE;
1311
1312         *pipe = plane->pipe;
1313
1314         intel_display_power_put(dev_priv, power_domain, wakeref);
1315
1316         return ret;
1317 }
1318
1319 static bool intel_fb_scalable(const struct drm_framebuffer *fb)
1320 {
1321         if (!fb)
1322                 return false;
1323
1324         switch (fb->format->format) {
1325         case DRM_FORMAT_C8:
1326                 return false;
1327         default:
1328                 return true;
1329         }
1330 }
1331
1332 static int
1333 g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
1334                          struct intel_plane_state *plane_state)
1335 {
1336         const struct drm_framebuffer *fb = plane_state->base.fb;
1337         const struct drm_rect *src = &plane_state->base.src;
1338         const struct drm_rect *dst = &plane_state->base.dst;
1339         int src_x, src_y, src_w, src_h, crtc_w, crtc_h;
1340         const struct drm_display_mode *adjusted_mode =
1341                 &crtc_state->base.adjusted_mode;
1342         unsigned int cpp = fb->format->cpp[0];
1343         unsigned int width_bytes;
1344         int min_width, min_height;
1345
1346         crtc_w = drm_rect_width(dst);
1347         crtc_h = drm_rect_height(dst);
1348
1349         src_x = src->x1 >> 16;
1350         src_y = src->y1 >> 16;
1351         src_w = drm_rect_width(src) >> 16;
1352         src_h = drm_rect_height(src) >> 16;
1353
1354         if (src_w == crtc_w && src_h == crtc_h)
1355                 return 0;
1356
1357         min_width = 3;
1358
1359         if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
1360                 if (src_h & 1) {
1361                         DRM_DEBUG_KMS("Source height must be even with interlaced modes\n");
1362                         return -EINVAL;
1363                 }
1364                 min_height = 6;
1365         } else {
1366                 min_height = 3;
1367         }
1368
1369         width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
1370
1371         if (src_w < min_width || src_h < min_height ||
1372             src_w > 2048 || src_h > 2048) {
1373                 DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
1374                               src_w, src_h, min_width, min_height, 2048, 2048);
1375                 return -EINVAL;
1376         }
1377
1378         if (width_bytes > 4096) {
1379                 DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n",
1380                               width_bytes, 4096);
1381                 return -EINVAL;
1382         }
1383
1384         if (width_bytes > 4096 || fb->pitches[0] > 4096) {
1385                 DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n",
1386                               fb->pitches[0], 4096);
1387                 return -EINVAL;
1388         }
1389
1390         return 0;
1391 }
1392
1393 static int
1394 g4x_sprite_check(struct intel_crtc_state *crtc_state,
1395                  struct intel_plane_state *plane_state)
1396 {
1397         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1398         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1399         int min_scale = DRM_PLANE_HELPER_NO_SCALING;
1400         int max_scale = DRM_PLANE_HELPER_NO_SCALING;
1401         int ret;
1402
1403         if (intel_fb_scalable(plane_state->base.fb)) {
1404                 if (INTEL_GEN(dev_priv) < 7) {
1405                         min_scale = 1;
1406                         max_scale = 16 << 16;
1407                 } else if (IS_IVYBRIDGE(dev_priv)) {
1408                         min_scale = 1;
1409                         max_scale = 2 << 16;
1410                 }
1411         }
1412
1413         ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1414                                                   &crtc_state->base,
1415                                                   min_scale, max_scale,
1416                                                   true, true);
1417         if (ret)
1418                 return ret;
1419
1420         if (!plane_state->base.visible)
1421                 return 0;
1422
1423         ret = intel_plane_check_src_coordinates(plane_state);
1424         if (ret)
1425                 return ret;
1426
1427         ret = g4x_sprite_check_scaling(crtc_state, plane_state);
1428         if (ret)
1429                 return ret;
1430
1431         ret = i9xx_check_plane_surface(plane_state);
1432         if (ret)
1433                 return ret;
1434
1435         if (INTEL_GEN(dev_priv) >= 7)
1436                 plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state);
1437         else
1438                 plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state);
1439
1440         return 0;
1441 }
1442
1443 int chv_plane_check_rotation(const struct intel_plane_state *plane_state)
1444 {
1445         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1446         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1447         unsigned int rotation = plane_state->base.rotation;
1448
1449         /* CHV ignores the mirror bit when the rotate bit is set :( */
1450         if (IS_CHERRYVIEW(dev_priv) &&
1451             rotation & DRM_MODE_ROTATE_180 &&
1452             rotation & DRM_MODE_REFLECT_X) {
1453                 DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n");
1454                 return -EINVAL;
1455         }
1456
1457         return 0;
1458 }
1459
1460 static int
1461 vlv_sprite_check(struct intel_crtc_state *crtc_state,
1462                  struct intel_plane_state *plane_state)
1463 {
1464         int ret;
1465
1466         ret = chv_plane_check_rotation(plane_state);
1467         if (ret)
1468                 return ret;
1469
1470         ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1471                                                   &crtc_state->base,
1472                                                   DRM_PLANE_HELPER_NO_SCALING,
1473                                                   DRM_PLANE_HELPER_NO_SCALING,
1474                                                   true, true);
1475         if (ret)
1476                 return ret;
1477
1478         if (!plane_state->base.visible)
1479                 return 0;
1480
1481         ret = intel_plane_check_src_coordinates(plane_state);
1482         if (ret)
1483                 return ret;
1484
1485         ret = i9xx_check_plane_surface(plane_state);
1486         if (ret)
1487                 return ret;
1488
1489         plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state);
1490
1491         return 0;
1492 }
1493
1494 static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
1495                               const struct intel_plane_state *plane_state)
1496 {
1497         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1498         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1499         const struct drm_framebuffer *fb = plane_state->base.fb;
1500         unsigned int rotation = plane_state->base.rotation;
1501         struct drm_format_name_buf format_name;
1502
1503         if (!fb)
1504                 return 0;
1505
1506         if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) &&
1507             is_ccs_modifier(fb->modifier)) {
1508                 DRM_DEBUG_KMS("RC support only with 0/180 degree rotation (%x)\n",
1509                               rotation);
1510                 return -EINVAL;
1511         }
1512
1513         if (rotation & DRM_MODE_REFLECT_X &&
1514             fb->modifier == DRM_FORMAT_MOD_LINEAR) {
1515                 DRM_DEBUG_KMS("horizontal flip is not supported with linear surface formats\n");
1516                 return -EINVAL;
1517         }
1518
1519         if (drm_rotation_90_or_270(rotation)) {
1520                 if (fb->modifier != I915_FORMAT_MOD_Y_TILED &&
1521                     fb->modifier != I915_FORMAT_MOD_Yf_TILED) {
1522                         DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n");
1523                         return -EINVAL;
1524                 }
1525
1526                 /*
1527                  * 90/270 is not allowed with RGB64 16:16:16:16 and
1528                  * Indexed 8-bit. RGB 16-bit 5:6:5 is allowed gen11 onwards.
1529                  */
1530                 switch (fb->format->format) {
1531                 case DRM_FORMAT_RGB565:
1532                         if (INTEL_GEN(dev_priv) >= 11)
1533                                 break;
1534                         /* fall through */
1535                 case DRM_FORMAT_C8:
1536                 case DRM_FORMAT_XRGB16161616F:
1537                 case DRM_FORMAT_XBGR16161616F:
1538                 case DRM_FORMAT_ARGB16161616F:
1539                 case DRM_FORMAT_ABGR16161616F:
1540                 case DRM_FORMAT_Y210:
1541                 case DRM_FORMAT_Y212:
1542                 case DRM_FORMAT_Y216:
1543                 case DRM_FORMAT_XVYU12_16161616:
1544                 case DRM_FORMAT_XVYU16161616:
1545                         DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n",
1546                                       drm_get_format_name(fb->format->format,
1547                                                           &format_name));
1548                         return -EINVAL;
1549                 default:
1550                         break;
1551                 }
1552         }
1553
1554         /* Y-tiling is not supported in IF-ID Interlace mode */
1555         if (crtc_state->base.enable &&
1556             crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
1557             (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
1558              fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
1559              fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
1560              fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS)) {
1561                 DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n");
1562                 return -EINVAL;
1563         }
1564
1565         return 0;
1566 }
1567
1568 static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state,
1569                                            const struct intel_plane_state *plane_state)
1570 {
1571         struct drm_i915_private *dev_priv =
1572                 to_i915(plane_state->base.plane->dev);
1573         int crtc_x = plane_state->base.dst.x1;
1574         int crtc_w = drm_rect_width(&plane_state->base.dst);
1575         int pipe_src_w = crtc_state->pipe_src_w;
1576
1577         /*
1578          * Display WA #1175: cnl,glk
1579          * Planes other than the cursor may cause FIFO underflow and display
1580          * corruption if starting less than 4 pixels from the right edge of
1581          * the screen.
1582          * Besides the above WA fix the similar problem, where planes other
1583          * than the cursor ending less than 4 pixels from the left edge of the
1584          * screen may cause FIFO underflow and display corruption.
1585          */
1586         if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
1587             (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
1588                 DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n",
1589                               crtc_x + crtc_w < 4 ? "end" : "start",
1590                               crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x,
1591                               4, pipe_src_w - 4);
1592                 return -ERANGE;
1593         }
1594
1595         return 0;
1596 }
1597
1598 static int skl_plane_check_nv12_rotation(const struct intel_plane_state *plane_state)
1599 {
1600         const struct drm_framebuffer *fb = plane_state->base.fb;
1601         unsigned int rotation = plane_state->base.rotation;
1602         int src_w = drm_rect_width(&plane_state->base.src) >> 16;
1603
1604         /* Display WA #1106 */
1605         if (is_planar_yuv_format(fb->format->format) && src_w & 3 &&
1606             (rotation == DRM_MODE_ROTATE_270 ||
1607              rotation == (DRM_MODE_REFLECT_X | DRM_MODE_ROTATE_90))) {
1608                 DRM_DEBUG_KMS("src width must be multiple of 4 for rotated planar YUV\n");
1609                 return -EINVAL;
1610         }
1611
1612         return 0;
1613 }
1614
1615 static int skl_plane_check(struct intel_crtc_state *crtc_state,
1616                            struct intel_plane_state *plane_state)
1617 {
1618         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1619         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1620         const struct drm_framebuffer *fb = plane_state->base.fb;
1621         int min_scale = DRM_PLANE_HELPER_NO_SCALING;
1622         int max_scale = DRM_PLANE_HELPER_NO_SCALING;
1623         int ret;
1624
1625         ret = skl_plane_check_fb(crtc_state, plane_state);
1626         if (ret)
1627                 return ret;
1628
1629         /* use scaler when colorkey is not required */
1630         if (!plane_state->ckey.flags && intel_fb_scalable(fb)) {
1631                 min_scale = 1;
1632                 max_scale = skl_max_scale(crtc_state, fb->format->format);
1633         }
1634
1635         ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1636                                                   &crtc_state->base,
1637                                                   min_scale, max_scale,
1638                                                   true, true);
1639         if (ret)
1640                 return ret;
1641
1642         if (!plane_state->base.visible)
1643                 return 0;
1644
1645         ret = skl_plane_check_dst_coordinates(crtc_state, plane_state);
1646         if (ret)
1647                 return ret;
1648
1649         ret = intel_plane_check_src_coordinates(plane_state);
1650         if (ret)
1651                 return ret;
1652
1653         ret = skl_plane_check_nv12_rotation(plane_state);
1654         if (ret)
1655                 return ret;
1656
1657         ret = skl_check_plane_surface(plane_state);
1658         if (ret)
1659                 return ret;
1660
1661         /* HW only has 8 bits pixel precision, disable plane if invisible */
1662         if (!(plane_state->base.alpha >> 8))
1663                 plane_state->base.visible = false;
1664
1665         plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
1666
1667         if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
1668                 plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
1669                                                              plane_state);
1670
1671         return 0;
1672 }
1673
1674 static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv)
1675 {
1676         return INTEL_GEN(dev_priv) >= 9;
1677 }
1678
1679 static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
1680                                  const struct drm_intel_sprite_colorkey *set)
1681 {
1682         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1683         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1684         struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1685
1686         *key = *set;
1687
1688         /*
1689          * We want src key enabled on the
1690          * sprite and not on the primary.
1691          */
1692         if (plane->id == PLANE_PRIMARY &&
1693             set->flags & I915_SET_COLORKEY_SOURCE)
1694                 key->flags = 0;
1695
1696         /*
1697          * On SKL+ we want dst key enabled on
1698          * the primary and not on the sprite.
1699          */
1700         if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_PRIMARY &&
1701             set->flags & I915_SET_COLORKEY_DESTINATION)
1702                 key->flags = 0;
1703 }
1704
1705 int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
1706                                     struct drm_file *file_priv)
1707 {
1708         struct drm_i915_private *dev_priv = to_i915(dev);
1709         struct drm_intel_sprite_colorkey *set = data;
1710         struct drm_plane *plane;
1711         struct drm_plane_state *plane_state;
1712         struct drm_atomic_state *state;
1713         struct drm_modeset_acquire_ctx ctx;
1714         int ret = 0;
1715
1716         /* ignore the pointless "none" flag */
1717         set->flags &= ~I915_SET_COLORKEY_NONE;
1718
1719         if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
1720                 return -EINVAL;
1721
1722         /* Make sure we don't try to enable both src & dest simultaneously */
1723         if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
1724                 return -EINVAL;
1725
1726         if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
1727             set->flags & I915_SET_COLORKEY_DESTINATION)
1728                 return -EINVAL;
1729
1730         plane = drm_plane_find(dev, file_priv, set->plane_id);
1731         if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
1732                 return -ENOENT;
1733
1734         /*
1735          * SKL+ only plane 2 can do destination keying against plane 1.
1736          * Also multiple planes can't do destination keying on the same
1737          * pipe simultaneously.
1738          */
1739         if (INTEL_GEN(dev_priv) >= 9 &&
1740             to_intel_plane(plane)->id >= PLANE_SPRITE1 &&
1741             set->flags & I915_SET_COLORKEY_DESTINATION)
1742                 return -EINVAL;
1743
1744         drm_modeset_acquire_init(&ctx, 0);
1745
1746         state = drm_atomic_state_alloc(plane->dev);
1747         if (!state) {
1748                 ret = -ENOMEM;
1749                 goto out;
1750         }
1751         state->acquire_ctx = &ctx;
1752
1753         while (1) {
1754                 plane_state = drm_atomic_get_plane_state(state, plane);
1755                 ret = PTR_ERR_OR_ZERO(plane_state);
1756                 if (!ret)
1757                         intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
1758
1759                 /*
1760                  * On some platforms we have to configure
1761                  * the dst colorkey on the primary plane.
1762                  */
1763                 if (!ret && has_dst_key_in_primary_plane(dev_priv)) {
1764                         struct intel_crtc *crtc =
1765                                 intel_get_crtc_for_pipe(dev_priv,
1766                                                         to_intel_plane(plane)->pipe);
1767
1768                         plane_state = drm_atomic_get_plane_state(state,
1769                                                                  crtc->base.primary);
1770                         ret = PTR_ERR_OR_ZERO(plane_state);
1771                         if (!ret)
1772                                 intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
1773                 }
1774
1775                 if (!ret)
1776                         ret = drm_atomic_commit(state);
1777
1778                 if (ret != -EDEADLK)
1779                         break;
1780
1781                 drm_atomic_state_clear(state);
1782                 drm_modeset_backoff(&ctx);
1783         }
1784
1785         drm_atomic_state_put(state);
1786 out:
1787         drm_modeset_drop_locks(&ctx);
1788         drm_modeset_acquire_fini(&ctx);
1789         return ret;
1790 }
1791
1792 static const u32 g4x_plane_formats[] = {
1793         DRM_FORMAT_XRGB8888,
1794         DRM_FORMAT_YUYV,
1795         DRM_FORMAT_YVYU,
1796         DRM_FORMAT_UYVY,
1797         DRM_FORMAT_VYUY,
1798 };
1799
1800 static const u64 i9xx_plane_format_modifiers[] = {
1801         I915_FORMAT_MOD_X_TILED,
1802         DRM_FORMAT_MOD_LINEAR,
1803         DRM_FORMAT_MOD_INVALID
1804 };
1805
1806 static const u32 snb_plane_formats[] = {
1807         DRM_FORMAT_XBGR8888,
1808         DRM_FORMAT_XRGB8888,
1809         DRM_FORMAT_YUYV,
1810         DRM_FORMAT_YVYU,
1811         DRM_FORMAT_UYVY,
1812         DRM_FORMAT_VYUY,
1813 };
1814
1815 static const u32 vlv_plane_formats[] = {
1816         DRM_FORMAT_RGB565,
1817         DRM_FORMAT_ABGR8888,
1818         DRM_FORMAT_ARGB8888,
1819         DRM_FORMAT_XBGR8888,
1820         DRM_FORMAT_XRGB8888,
1821         DRM_FORMAT_XBGR2101010,
1822         DRM_FORMAT_ABGR2101010,
1823         DRM_FORMAT_YUYV,
1824         DRM_FORMAT_YVYU,
1825         DRM_FORMAT_UYVY,
1826         DRM_FORMAT_VYUY,
1827 };
1828
1829 static const u32 skl_plane_formats[] = {
1830         DRM_FORMAT_C8,
1831         DRM_FORMAT_RGB565,
1832         DRM_FORMAT_XRGB8888,
1833         DRM_FORMAT_XBGR8888,
1834         DRM_FORMAT_ARGB8888,
1835         DRM_FORMAT_ABGR8888,
1836         DRM_FORMAT_XRGB2101010,
1837         DRM_FORMAT_XBGR2101010,
1838         DRM_FORMAT_YUYV,
1839         DRM_FORMAT_YVYU,
1840         DRM_FORMAT_UYVY,
1841         DRM_FORMAT_VYUY,
1842 };
1843
1844 static const u32 icl_plane_formats[] = {
1845         DRM_FORMAT_C8,
1846         DRM_FORMAT_RGB565,
1847         DRM_FORMAT_XRGB8888,
1848         DRM_FORMAT_XBGR8888,
1849         DRM_FORMAT_ARGB8888,
1850         DRM_FORMAT_ABGR8888,
1851         DRM_FORMAT_XRGB2101010,
1852         DRM_FORMAT_XBGR2101010,
1853         DRM_FORMAT_YUYV,
1854         DRM_FORMAT_YVYU,
1855         DRM_FORMAT_UYVY,
1856         DRM_FORMAT_VYUY,
1857         DRM_FORMAT_Y210,
1858         DRM_FORMAT_Y212,
1859         DRM_FORMAT_Y216,
1860         DRM_FORMAT_XVYU2101010,
1861         DRM_FORMAT_XVYU12_16161616,
1862         DRM_FORMAT_XVYU16161616,
1863 };
1864
1865 static const u32 icl_hdr_plane_formats[] = {
1866         DRM_FORMAT_C8,
1867         DRM_FORMAT_RGB565,
1868         DRM_FORMAT_XRGB8888,
1869         DRM_FORMAT_XBGR8888,
1870         DRM_FORMAT_ARGB8888,
1871         DRM_FORMAT_ABGR8888,
1872         DRM_FORMAT_XRGB2101010,
1873         DRM_FORMAT_XBGR2101010,
1874         DRM_FORMAT_XRGB16161616F,
1875         DRM_FORMAT_XBGR16161616F,
1876         DRM_FORMAT_ARGB16161616F,
1877         DRM_FORMAT_ABGR16161616F,
1878         DRM_FORMAT_YUYV,
1879         DRM_FORMAT_YVYU,
1880         DRM_FORMAT_UYVY,
1881         DRM_FORMAT_VYUY,
1882         DRM_FORMAT_Y210,
1883         DRM_FORMAT_Y212,
1884         DRM_FORMAT_Y216,
1885         DRM_FORMAT_XVYU2101010,
1886         DRM_FORMAT_XVYU12_16161616,
1887         DRM_FORMAT_XVYU16161616,
1888 };
1889
1890 static const u32 skl_planar_formats[] = {
1891         DRM_FORMAT_C8,
1892         DRM_FORMAT_RGB565,
1893         DRM_FORMAT_XRGB8888,
1894         DRM_FORMAT_XBGR8888,
1895         DRM_FORMAT_ARGB8888,
1896         DRM_FORMAT_ABGR8888,
1897         DRM_FORMAT_XRGB2101010,
1898         DRM_FORMAT_XBGR2101010,
1899         DRM_FORMAT_YUYV,
1900         DRM_FORMAT_YVYU,
1901         DRM_FORMAT_UYVY,
1902         DRM_FORMAT_VYUY,
1903         DRM_FORMAT_NV12,
1904 };
1905
1906 static const u32 glk_planar_formats[] = {
1907         DRM_FORMAT_C8,
1908         DRM_FORMAT_RGB565,
1909         DRM_FORMAT_XRGB8888,
1910         DRM_FORMAT_XBGR8888,
1911         DRM_FORMAT_ARGB8888,
1912         DRM_FORMAT_ABGR8888,
1913         DRM_FORMAT_XRGB2101010,
1914         DRM_FORMAT_XBGR2101010,
1915         DRM_FORMAT_YUYV,
1916         DRM_FORMAT_YVYU,
1917         DRM_FORMAT_UYVY,
1918         DRM_FORMAT_VYUY,
1919         DRM_FORMAT_NV12,
1920         DRM_FORMAT_P010,
1921         DRM_FORMAT_P012,
1922         DRM_FORMAT_P016,
1923 };
1924
1925 static const u32 icl_planar_formats[] = {
1926         DRM_FORMAT_C8,
1927         DRM_FORMAT_RGB565,
1928         DRM_FORMAT_XRGB8888,
1929         DRM_FORMAT_XBGR8888,
1930         DRM_FORMAT_ARGB8888,
1931         DRM_FORMAT_ABGR8888,
1932         DRM_FORMAT_XRGB2101010,
1933         DRM_FORMAT_XBGR2101010,
1934         DRM_FORMAT_YUYV,
1935         DRM_FORMAT_YVYU,
1936         DRM_FORMAT_UYVY,
1937         DRM_FORMAT_VYUY,
1938         DRM_FORMAT_NV12,
1939         DRM_FORMAT_P010,
1940         DRM_FORMAT_P012,
1941         DRM_FORMAT_P016,
1942         DRM_FORMAT_Y210,
1943         DRM_FORMAT_Y212,
1944         DRM_FORMAT_Y216,
1945         DRM_FORMAT_XVYU2101010,
1946         DRM_FORMAT_XVYU12_16161616,
1947         DRM_FORMAT_XVYU16161616,
1948 };
1949
1950 static const u32 icl_hdr_planar_formats[] = {
1951         DRM_FORMAT_C8,
1952         DRM_FORMAT_RGB565,
1953         DRM_FORMAT_XRGB8888,
1954         DRM_FORMAT_XBGR8888,
1955         DRM_FORMAT_ARGB8888,
1956         DRM_FORMAT_ABGR8888,
1957         DRM_FORMAT_XRGB2101010,
1958         DRM_FORMAT_XBGR2101010,
1959         DRM_FORMAT_XRGB16161616F,
1960         DRM_FORMAT_XBGR16161616F,
1961         DRM_FORMAT_ARGB16161616F,
1962         DRM_FORMAT_ABGR16161616F,
1963         DRM_FORMAT_YUYV,
1964         DRM_FORMAT_YVYU,
1965         DRM_FORMAT_UYVY,
1966         DRM_FORMAT_VYUY,
1967         DRM_FORMAT_NV12,
1968         DRM_FORMAT_P010,
1969         DRM_FORMAT_P012,
1970         DRM_FORMAT_P016,
1971         DRM_FORMAT_Y210,
1972         DRM_FORMAT_Y212,
1973         DRM_FORMAT_Y216,
1974         DRM_FORMAT_XVYU2101010,
1975         DRM_FORMAT_XVYU12_16161616,
1976         DRM_FORMAT_XVYU16161616,
1977 };
1978
1979 static const u64 skl_plane_format_modifiers_noccs[] = {
1980         I915_FORMAT_MOD_Yf_TILED,
1981         I915_FORMAT_MOD_Y_TILED,
1982         I915_FORMAT_MOD_X_TILED,
1983         DRM_FORMAT_MOD_LINEAR,
1984         DRM_FORMAT_MOD_INVALID
1985 };
1986
1987 static const u64 skl_plane_format_modifiers_ccs[] = {
1988         I915_FORMAT_MOD_Yf_TILED_CCS,
1989         I915_FORMAT_MOD_Y_TILED_CCS,
1990         I915_FORMAT_MOD_Yf_TILED,
1991         I915_FORMAT_MOD_Y_TILED,
1992         I915_FORMAT_MOD_X_TILED,
1993         DRM_FORMAT_MOD_LINEAR,
1994         DRM_FORMAT_MOD_INVALID
1995 };
1996
1997 static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane,
1998                                             u32 format, u64 modifier)
1999 {
2000         switch (modifier) {
2001         case DRM_FORMAT_MOD_LINEAR:
2002         case I915_FORMAT_MOD_X_TILED:
2003                 break;
2004         default:
2005                 return false;
2006         }
2007
2008         switch (format) {
2009         case DRM_FORMAT_XRGB8888:
2010         case DRM_FORMAT_YUYV:
2011         case DRM_FORMAT_YVYU:
2012         case DRM_FORMAT_UYVY:
2013         case DRM_FORMAT_VYUY:
2014                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
2015                     modifier == I915_FORMAT_MOD_X_TILED)
2016                         return true;
2017                 /* fall through */
2018         default:
2019                 return false;
2020         }
2021 }
2022
2023 static bool snb_sprite_format_mod_supported(struct drm_plane *_plane,
2024                                             u32 format, u64 modifier)
2025 {
2026         switch (modifier) {
2027         case DRM_FORMAT_MOD_LINEAR:
2028         case I915_FORMAT_MOD_X_TILED:
2029                 break;
2030         default:
2031                 return false;
2032         }
2033
2034         switch (format) {
2035         case DRM_FORMAT_XRGB8888:
2036         case DRM_FORMAT_XBGR8888:
2037         case DRM_FORMAT_YUYV:
2038         case DRM_FORMAT_YVYU:
2039         case DRM_FORMAT_UYVY:
2040         case DRM_FORMAT_VYUY:
2041                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
2042                     modifier == I915_FORMAT_MOD_X_TILED)
2043                         return true;
2044                 /* fall through */
2045         default:
2046                 return false;
2047         }
2048 }
2049
2050 static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane,
2051                                             u32 format, u64 modifier)
2052 {
2053         switch (modifier) {
2054         case DRM_FORMAT_MOD_LINEAR:
2055         case I915_FORMAT_MOD_X_TILED:
2056                 break;
2057         default:
2058                 return false;
2059         }
2060
2061         switch (format) {
2062         case DRM_FORMAT_RGB565:
2063         case DRM_FORMAT_ABGR8888:
2064         case DRM_FORMAT_ARGB8888:
2065         case DRM_FORMAT_XBGR8888:
2066         case DRM_FORMAT_XRGB8888:
2067         case DRM_FORMAT_XBGR2101010:
2068         case DRM_FORMAT_ABGR2101010:
2069         case DRM_FORMAT_YUYV:
2070         case DRM_FORMAT_YVYU:
2071         case DRM_FORMAT_UYVY:
2072         case DRM_FORMAT_VYUY:
2073                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
2074                     modifier == I915_FORMAT_MOD_X_TILED)
2075                         return true;
2076                 /* fall through */
2077         default:
2078                 return false;
2079         }
2080 }
2081
2082 static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
2083                                            u32 format, u64 modifier)
2084 {
2085         struct intel_plane *plane = to_intel_plane(_plane);
2086
2087         switch (modifier) {
2088         case DRM_FORMAT_MOD_LINEAR:
2089         case I915_FORMAT_MOD_X_TILED:
2090         case I915_FORMAT_MOD_Y_TILED:
2091         case I915_FORMAT_MOD_Yf_TILED:
2092                 break;
2093         case I915_FORMAT_MOD_Y_TILED_CCS:
2094         case I915_FORMAT_MOD_Yf_TILED_CCS:
2095                 if (!plane->has_ccs)
2096                         return false;
2097                 break;
2098         default:
2099                 return false;
2100         }
2101
2102         switch (format) {
2103         case DRM_FORMAT_XRGB8888:
2104         case DRM_FORMAT_XBGR8888:
2105         case DRM_FORMAT_ARGB8888:
2106         case DRM_FORMAT_ABGR8888:
2107                 if (is_ccs_modifier(modifier))
2108                         return true;
2109                 /* fall through */
2110         case DRM_FORMAT_RGB565:
2111         case DRM_FORMAT_XRGB2101010:
2112         case DRM_FORMAT_XBGR2101010:
2113         case DRM_FORMAT_YUYV:
2114         case DRM_FORMAT_YVYU:
2115         case DRM_FORMAT_UYVY:
2116         case DRM_FORMAT_VYUY:
2117         case DRM_FORMAT_NV12:
2118         case DRM_FORMAT_P010:
2119         case DRM_FORMAT_P012:
2120         case DRM_FORMAT_P016:
2121         case DRM_FORMAT_XVYU2101010:
2122                 if (modifier == I915_FORMAT_MOD_Yf_TILED)
2123                         return true;
2124                 /* fall through */
2125         case DRM_FORMAT_C8:
2126         case DRM_FORMAT_XBGR16161616F:
2127         case DRM_FORMAT_ABGR16161616F:
2128         case DRM_FORMAT_XRGB16161616F:
2129         case DRM_FORMAT_ARGB16161616F:
2130         case DRM_FORMAT_Y210:
2131         case DRM_FORMAT_Y212:
2132         case DRM_FORMAT_Y216:
2133         case DRM_FORMAT_XVYU12_16161616:
2134         case DRM_FORMAT_XVYU16161616:
2135                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
2136                     modifier == I915_FORMAT_MOD_X_TILED ||
2137                     modifier == I915_FORMAT_MOD_Y_TILED)
2138                         return true;
2139                 /* fall through */
2140         default:
2141                 return false;
2142         }
2143 }
2144
2145 static const struct drm_plane_funcs g4x_sprite_funcs = {
2146         .update_plane = drm_atomic_helper_update_plane,
2147         .disable_plane = drm_atomic_helper_disable_plane,
2148         .destroy = intel_plane_destroy,
2149         .atomic_get_property = intel_plane_atomic_get_property,
2150         .atomic_set_property = intel_plane_atomic_set_property,
2151         .atomic_duplicate_state = intel_plane_duplicate_state,
2152         .atomic_destroy_state = intel_plane_destroy_state,
2153         .format_mod_supported = g4x_sprite_format_mod_supported,
2154 };
2155
2156 static const struct drm_plane_funcs snb_sprite_funcs = {
2157         .update_plane = drm_atomic_helper_update_plane,
2158         .disable_plane = drm_atomic_helper_disable_plane,
2159         .destroy = intel_plane_destroy,
2160         .atomic_get_property = intel_plane_atomic_get_property,
2161         .atomic_set_property = intel_plane_atomic_set_property,
2162         .atomic_duplicate_state = intel_plane_duplicate_state,
2163         .atomic_destroy_state = intel_plane_destroy_state,
2164         .format_mod_supported = snb_sprite_format_mod_supported,
2165 };
2166
2167 static const struct drm_plane_funcs vlv_sprite_funcs = {
2168         .update_plane = drm_atomic_helper_update_plane,
2169         .disable_plane = drm_atomic_helper_disable_plane,
2170         .destroy = intel_plane_destroy,
2171         .atomic_get_property = intel_plane_atomic_get_property,
2172         .atomic_set_property = intel_plane_atomic_set_property,
2173         .atomic_duplicate_state = intel_plane_duplicate_state,
2174         .atomic_destroy_state = intel_plane_destroy_state,
2175         .format_mod_supported = vlv_sprite_format_mod_supported,
2176 };
2177
2178 static const struct drm_plane_funcs skl_plane_funcs = {
2179         .update_plane = drm_atomic_helper_update_plane,
2180         .disable_plane = drm_atomic_helper_disable_plane,
2181         .destroy = intel_plane_destroy,
2182         .atomic_get_property = intel_plane_atomic_get_property,
2183         .atomic_set_property = intel_plane_atomic_set_property,
2184         .atomic_duplicate_state = intel_plane_duplicate_state,
2185         .atomic_destroy_state = intel_plane_destroy_state,
2186         .format_mod_supported = skl_plane_format_mod_supported,
2187 };
2188
2189 static bool skl_plane_has_fbc(struct drm_i915_private *dev_priv,
2190                               enum pipe pipe, enum plane_id plane_id)
2191 {
2192         if (!HAS_FBC(dev_priv))
2193                 return false;
2194
2195         return pipe == PIPE_A && plane_id == PLANE_PRIMARY;
2196 }
2197
2198 static bool skl_plane_has_planar(struct drm_i915_private *dev_priv,
2199                                  enum pipe pipe, enum plane_id plane_id)
2200 {
2201         if (INTEL_GEN(dev_priv) >= 11)
2202                 return plane_id <= PLANE_SPRITE3;
2203
2204         /* Display WA #0870: skl, bxt */
2205         if (IS_SKYLAKE(dev_priv) || IS_BROXTON(dev_priv))
2206                 return false;
2207
2208         if (IS_GEN(dev_priv, 9) && !IS_GEMINILAKE(dev_priv) && pipe == PIPE_C)
2209                 return false;
2210
2211         if (plane_id != PLANE_PRIMARY && plane_id != PLANE_SPRITE0)
2212                 return false;
2213
2214         return true;
2215 }
2216
2217 static bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
2218                               enum pipe pipe, enum plane_id plane_id)
2219 {
2220         if (plane_id == PLANE_CURSOR)
2221                 return false;
2222
2223         if (INTEL_GEN(dev_priv) >= 10)
2224                 return true;
2225
2226         if (IS_GEMINILAKE(dev_priv))
2227                 return pipe != PIPE_C;
2228
2229         return pipe != PIPE_C &&
2230                 (plane_id == PLANE_PRIMARY ||
2231                  plane_id == PLANE_SPRITE0);
2232 }
2233
2234 struct intel_plane *
2235 skl_universal_plane_create(struct drm_i915_private *dev_priv,
2236                            enum pipe pipe, enum plane_id plane_id)
2237 {
2238         struct intel_plane *plane;
2239         enum drm_plane_type plane_type;
2240         unsigned int supported_rotations;
2241         unsigned int possible_crtcs;
2242         const u64 *modifiers;
2243         const u32 *formats;
2244         int num_formats;
2245         int ret;
2246
2247         plane = intel_plane_alloc();
2248         if (IS_ERR(plane))
2249                 return plane;
2250
2251         plane->pipe = pipe;
2252         plane->id = plane_id;
2253         plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane_id);
2254
2255         plane->has_fbc = skl_plane_has_fbc(dev_priv, pipe, plane_id);
2256         if (plane->has_fbc) {
2257                 struct intel_fbc *fbc = &dev_priv->fbc;
2258
2259                 fbc->possible_framebuffer_bits |= plane->frontbuffer_bit;
2260         }
2261
2262         plane->max_stride = skl_plane_max_stride;
2263         plane->update_plane = skl_update_plane;
2264         plane->disable_plane = skl_disable_plane;
2265         plane->get_hw_state = skl_plane_get_hw_state;
2266         plane->check_plane = skl_plane_check;
2267         if (icl_is_nv12_y_plane(plane_id))
2268                 plane->update_slave = icl_update_slave;
2269
2270         if (skl_plane_has_planar(dev_priv, pipe, plane_id)) {
2271                 if (icl_is_hdr_plane(dev_priv, plane_id)) {
2272                         formats = icl_hdr_planar_formats;
2273                         num_formats = ARRAY_SIZE(icl_hdr_planar_formats);
2274                 } else if (INTEL_GEN(dev_priv) >= 11) {
2275                         formats = icl_planar_formats;
2276                         num_formats = ARRAY_SIZE(icl_planar_formats);
2277                 } else if (INTEL_GEN(dev_priv) == 10 || IS_GEMINILAKE(dev_priv)) {
2278                         formats = glk_planar_formats;
2279                         num_formats = ARRAY_SIZE(glk_planar_formats);
2280                 } else {
2281                         formats = skl_planar_formats;
2282                         num_formats = ARRAY_SIZE(skl_planar_formats);
2283                 }
2284         } else if (icl_is_hdr_plane(dev_priv, plane_id)) {
2285                 formats = icl_hdr_plane_formats;
2286                 num_formats = ARRAY_SIZE(icl_hdr_plane_formats);
2287         } else if (INTEL_GEN(dev_priv) >= 11) {
2288                 formats = icl_plane_formats;
2289                 num_formats = ARRAY_SIZE(icl_plane_formats);
2290         } else {
2291                 formats = skl_plane_formats;
2292                 num_formats = ARRAY_SIZE(skl_plane_formats);
2293         }
2294
2295         plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe, plane_id);
2296         if (plane->has_ccs)
2297                 modifiers = skl_plane_format_modifiers_ccs;
2298         else
2299                 modifiers = skl_plane_format_modifiers_noccs;
2300
2301         if (plane_id == PLANE_PRIMARY)
2302                 plane_type = DRM_PLANE_TYPE_PRIMARY;
2303         else
2304                 plane_type = DRM_PLANE_TYPE_OVERLAY;
2305
2306         possible_crtcs = BIT(pipe);
2307
2308         ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
2309                                        possible_crtcs, &skl_plane_funcs,
2310                                        formats, num_formats, modifiers,
2311                                        plane_type,
2312                                        "plane %d%c", plane_id + 1,
2313                                        pipe_name(pipe));
2314         if (ret)
2315                 goto fail;
2316
2317         supported_rotations =
2318                 DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
2319                 DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
2320
2321         if (INTEL_GEN(dev_priv) >= 10)
2322                 supported_rotations |= DRM_MODE_REFLECT_X;
2323
2324         drm_plane_create_rotation_property(&plane->base,
2325                                            DRM_MODE_ROTATE_0,
2326                                            supported_rotations);
2327
2328         drm_plane_create_color_properties(&plane->base,
2329                                           BIT(DRM_COLOR_YCBCR_BT601) |
2330                                           BIT(DRM_COLOR_YCBCR_BT709),
2331                                           BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
2332                                           BIT(DRM_COLOR_YCBCR_FULL_RANGE),
2333                                           DRM_COLOR_YCBCR_BT709,
2334                                           DRM_COLOR_YCBCR_LIMITED_RANGE);
2335
2336         drm_plane_create_alpha_property(&plane->base);
2337         drm_plane_create_blend_mode_property(&plane->base,
2338                                              BIT(DRM_MODE_BLEND_PIXEL_NONE) |
2339                                              BIT(DRM_MODE_BLEND_PREMULTI) |
2340                                              BIT(DRM_MODE_BLEND_COVERAGE));
2341
2342         drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
2343
2344         return plane;
2345
2346 fail:
2347         intel_plane_free(plane);
2348
2349         return ERR_PTR(ret);
2350 }
2351
2352 struct intel_plane *
2353 intel_sprite_plane_create(struct drm_i915_private *dev_priv,
2354                           enum pipe pipe, int sprite)
2355 {
2356         struct intel_plane *plane;
2357         const struct drm_plane_funcs *plane_funcs;
2358         unsigned long possible_crtcs;
2359         unsigned int supported_rotations;
2360         const u64 *modifiers;
2361         const u32 *formats;
2362         int num_formats;
2363         int ret;
2364
2365         if (INTEL_GEN(dev_priv) >= 9)
2366                 return skl_universal_plane_create(dev_priv, pipe,
2367                                                   PLANE_SPRITE0 + sprite);
2368
2369         plane = intel_plane_alloc();
2370         if (IS_ERR(plane))
2371                 return plane;
2372
2373         if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
2374                 plane->max_stride = i9xx_plane_max_stride;
2375                 plane->update_plane = vlv_update_plane;
2376                 plane->disable_plane = vlv_disable_plane;
2377                 plane->get_hw_state = vlv_plane_get_hw_state;
2378                 plane->check_plane = vlv_sprite_check;
2379
2380                 formats = vlv_plane_formats;
2381                 num_formats = ARRAY_SIZE(vlv_plane_formats);
2382                 modifiers = i9xx_plane_format_modifiers;
2383
2384                 plane_funcs = &vlv_sprite_funcs;
2385         } else if (INTEL_GEN(dev_priv) >= 7) {
2386                 plane->max_stride = g4x_sprite_max_stride;
2387                 plane->update_plane = ivb_update_plane;
2388                 plane->disable_plane = ivb_disable_plane;
2389                 plane->get_hw_state = ivb_plane_get_hw_state;
2390                 plane->check_plane = g4x_sprite_check;
2391
2392                 formats = snb_plane_formats;
2393                 num_formats = ARRAY_SIZE(snb_plane_formats);
2394                 modifiers = i9xx_plane_format_modifiers;
2395
2396                 plane_funcs = &snb_sprite_funcs;
2397         } else {
2398                 plane->max_stride = g4x_sprite_max_stride;
2399                 plane->update_plane = g4x_update_plane;
2400                 plane->disable_plane = g4x_disable_plane;
2401                 plane->get_hw_state = g4x_plane_get_hw_state;
2402                 plane->check_plane = g4x_sprite_check;
2403
2404                 modifiers = i9xx_plane_format_modifiers;
2405                 if (IS_GEN(dev_priv, 6)) {
2406                         formats = snb_plane_formats;
2407                         num_formats = ARRAY_SIZE(snb_plane_formats);
2408
2409                         plane_funcs = &snb_sprite_funcs;
2410                 } else {
2411                         formats = g4x_plane_formats;
2412                         num_formats = ARRAY_SIZE(g4x_plane_formats);
2413
2414                         plane_funcs = &g4x_sprite_funcs;
2415                 }
2416         }
2417
2418         if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
2419                 supported_rotations =
2420                         DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
2421                         DRM_MODE_REFLECT_X;
2422         } else {
2423                 supported_rotations =
2424                         DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
2425         }
2426
2427         plane->pipe = pipe;
2428         plane->id = PLANE_SPRITE0 + sprite;
2429         plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
2430
2431         possible_crtcs = BIT(pipe);
2432
2433         ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
2434                                        possible_crtcs, plane_funcs,
2435                                        formats, num_formats, modifiers,
2436                                        DRM_PLANE_TYPE_OVERLAY,
2437                                        "sprite %c", sprite_name(pipe, sprite));
2438         if (ret)
2439                 goto fail;
2440
2441         drm_plane_create_rotation_property(&plane->base,
2442                                            DRM_MODE_ROTATE_0,
2443                                            supported_rotations);
2444
2445         drm_plane_create_color_properties(&plane->base,
2446                                           BIT(DRM_COLOR_YCBCR_BT601) |
2447                                           BIT(DRM_COLOR_YCBCR_BT709),
2448                                           BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
2449                                           BIT(DRM_COLOR_YCBCR_FULL_RANGE),
2450                                           DRM_COLOR_YCBCR_BT709,
2451                                           DRM_COLOR_YCBCR_LIMITED_RANGE);
2452
2453         drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
2454
2455         return plane;
2456
2457 fail:
2458         intel_plane_free(plane);
2459
2460         return ERR_PTR(ret);
2461 }