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