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