Merge tag 'drm-intel-next-2018-09-21' of git://anongit.freedesktop.org/drm/drm-intel...
[muen/linux.git] / drivers / gpu / drm / i915 / intel_sprite.c
1 /*
2  * Copyright © 2011 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  *
23  * Authors:
24  *   Jesse Barnes <jbarnes@virtuousgeek.org>
25  *
26  * New plane/sprite handling.
27  *
28  * The older chips had a separate interface for programming plane related
29  * registers; newer ones are much simpler and we can use the new DRM plane
30  * support.
31  */
32 #include <drm/drmP.h>
33 #include <drm/drm_atomic_helper.h>
34 #include <drm/drm_crtc.h>
35 #include <drm/drm_fourcc.h>
36 #include <drm/drm_rect.h>
37 #include <drm/drm_atomic.h>
38 #include <drm/drm_plane_helper.h>
39 #include "intel_drv.h"
40 #include "intel_frontbuffer.h"
41 #include <drm/i915_drm.h>
42 #include "i915_drv.h"
43
44 int intel_usecs_to_scanlines(const struct drm_display_mode *adjusted_mode,
45                              int usecs)
46 {
47         /* paranoia */
48         if (!adjusted_mode->crtc_htotal)
49                 return 1;
50
51         return DIV_ROUND_UP(usecs * adjusted_mode->crtc_clock,
52                             1000 * adjusted_mode->crtc_htotal);
53 }
54
55 /* FIXME: We should instead only take spinlocks once for the entire update
56  * instead of once per mmio. */
57 #if IS_ENABLED(CONFIG_PROVE_LOCKING)
58 #define VBLANK_EVASION_TIME_US 250
59 #else
60 #define VBLANK_EVASION_TIME_US 100
61 #endif
62
63 /**
64  * intel_pipe_update_start() - start update of a set of display registers
65  * @new_crtc_state: the new crtc state
66  *
67  * Mark the start of an update to pipe registers that should be updated
68  * atomically regarding vblank. If the next vblank will happens within
69  * the next 100 us, this function waits until the vblank passes.
70  *
71  * After a successful call to this function, interrupts will be disabled
72  * until a subsequent call to intel_pipe_update_end(). That is done to
73  * avoid random delays.
74  */
75 void intel_pipe_update_start(const struct intel_crtc_state *new_crtc_state)
76 {
77         struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
78         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
79         const struct drm_display_mode *adjusted_mode = &new_crtc_state->base.adjusted_mode;
80         long timeout = msecs_to_jiffies_timeout(1);
81         int scanline, min, max, vblank_start;
82         wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
83         bool need_vlv_dsi_wa = (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
84                 intel_crtc_has_type(new_crtc_state, INTEL_OUTPUT_DSI);
85         DEFINE_WAIT(wait);
86         u32 psr_status;
87
88         vblank_start = adjusted_mode->crtc_vblank_start;
89         if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE)
90                 vblank_start = DIV_ROUND_UP(vblank_start, 2);
91
92         /* FIXME needs to be calibrated sensibly */
93         min = vblank_start - intel_usecs_to_scanlines(adjusted_mode,
94                                                       VBLANK_EVASION_TIME_US);
95         max = vblank_start - 1;
96
97         if (min <= 0 || max <= 0)
98                 goto irq_disable;
99
100         if (WARN_ON(drm_crtc_vblank_get(&crtc->base)))
101                 goto irq_disable;
102
103         /*
104          * Wait for psr to idle out after enabling the VBL interrupts
105          * VBL interrupts will start the PSR exit and prevent a PSR
106          * re-entry as well.
107          */
108         if (intel_psr_wait_for_idle(new_crtc_state, &psr_status))
109                 DRM_ERROR("PSR idle timed out 0x%x, atomic update may fail\n",
110                           psr_status);
111
112         local_irq_disable();
113
114         crtc->debug.min_vbl = min;
115         crtc->debug.max_vbl = max;
116         trace_i915_pipe_update_start(crtc);
117
118         for (;;) {
119                 /*
120                  * prepare_to_wait() has a memory barrier, which guarantees
121                  * other CPUs can see the task state update by the time we
122                  * read the scanline.
123                  */
124                 prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
125
126                 scanline = intel_get_crtc_scanline(crtc);
127                 if (scanline < min || scanline > max)
128                         break;
129
130                 if (!timeout) {
131                         DRM_ERROR("Potential atomic update failure on pipe %c\n",
132                                   pipe_name(crtc->pipe));
133                         break;
134                 }
135
136                 local_irq_enable();
137
138                 timeout = schedule_timeout(timeout);
139
140                 local_irq_disable();
141         }
142
143         finish_wait(wq, &wait);
144
145         drm_crtc_vblank_put(&crtc->base);
146
147         /*
148          * On VLV/CHV DSI the scanline counter would appear to
149          * increment approx. 1/3 of a scanline before start of vblank.
150          * The registers still get latched at start of vblank however.
151          * This means we must not write any registers on the first
152          * line of vblank (since not the whole line is actually in
153          * vblank). And unfortunately we can't use the interrupt to
154          * wait here since it will fire too soon. We could use the
155          * frame start interrupt instead since it will fire after the
156          * critical scanline, but that would require more changes
157          * in the interrupt code. So for now we'll just do the nasty
158          * thing and poll for the bad scanline to pass us by.
159          *
160          * FIXME figure out if BXT+ DSI suffers from this as well
161          */
162         while (need_vlv_dsi_wa && scanline == vblank_start)
163                 scanline = intel_get_crtc_scanline(crtc);
164
165         crtc->debug.scanline_start = scanline;
166         crtc->debug.start_vbl_time = ktime_get();
167         crtc->debug.start_vbl_count = intel_crtc_get_vblank_counter(crtc);
168
169         trace_i915_pipe_update_vblank_evaded(crtc);
170         return;
171
172 irq_disable:
173         local_irq_disable();
174 }
175
176 /**
177  * intel_pipe_update_end() - end update of a set of display registers
178  * @new_crtc_state: the new crtc state
179  *
180  * Mark the end of an update started with intel_pipe_update_start(). This
181  * re-enables interrupts and verifies the update was actually completed
182  * before a vblank.
183  */
184 void intel_pipe_update_end(struct intel_crtc_state *new_crtc_state)
185 {
186         struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->base.crtc);
187         enum pipe pipe = crtc->pipe;
188         int scanline_end = intel_get_crtc_scanline(crtc);
189         u32 end_vbl_count = intel_crtc_get_vblank_counter(crtc);
190         ktime_t end_vbl_time = ktime_get();
191         struct drm_i915_private *dev_priv = to_i915(crtc->base.dev);
192
193         trace_i915_pipe_update_end(crtc, end_vbl_count, scanline_end);
194
195         /* We're still in the vblank-evade critical section, this can't race.
196          * Would be slightly nice to just grab the vblank count and arm the
197          * event outside of the critical section - the spinlock might spin for a
198          * while ... */
199         if (new_crtc_state->base.event) {
200                 WARN_ON(drm_crtc_vblank_get(&crtc->base) != 0);
201
202                 spin_lock(&crtc->base.dev->event_lock);
203                 drm_crtc_arm_vblank_event(&crtc->base, new_crtc_state->base.event);
204                 spin_unlock(&crtc->base.dev->event_lock);
205
206                 new_crtc_state->base.event = NULL;
207         }
208
209         local_irq_enable();
210
211         if (intel_vgpu_active(dev_priv))
212                 return;
213
214         if (crtc->debug.start_vbl_count &&
215             crtc->debug.start_vbl_count != end_vbl_count) {
216                 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",
217                           pipe_name(pipe), crtc->debug.start_vbl_count,
218                           end_vbl_count,
219                           ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
220                           crtc->debug.min_vbl, crtc->debug.max_vbl,
221                           crtc->debug.scanline_start, scanline_end);
222         }
223 #ifdef CONFIG_DRM_I915_DEBUG_VBLANK_EVADE
224         else if (ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time) >
225                  VBLANK_EVASION_TIME_US)
226                 DRM_WARN("Atomic update on pipe (%c) took %lld us, max time under evasion is %u us\n",
227                          pipe_name(pipe),
228                          ktime_us_delta(end_vbl_time, crtc->debug.start_vbl_time),
229                          VBLANK_EVASION_TIME_US);
230 #endif
231 }
232
233 int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
234 {
235         const struct drm_framebuffer *fb = plane_state->base.fb;
236         struct drm_rect *src = &plane_state->base.src;
237         u32 src_x, src_y, src_w, src_h;
238
239         /*
240          * Hardware doesn't handle subpixel coordinates.
241          * Adjust to (macro)pixel boundary, but be careful not to
242          * increase the source viewport size, because that could
243          * push the downscaling factor out of bounds.
244          */
245         src_x = src->x1 >> 16;
246         src_w = drm_rect_width(src) >> 16;
247         src_y = src->y1 >> 16;
248         src_h = drm_rect_height(src) >> 16;
249
250         src->x1 = src_x << 16;
251         src->x2 = (src_x + src_w) << 16;
252         src->y1 = src_y << 16;
253         src->y2 = (src_y + src_h) << 16;
254
255         if (fb->format->is_yuv &&
256             fb->format->format != DRM_FORMAT_NV12 &&
257             (src_x & 1 || src_w & 1)) {
258                 DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of 2 for YUV planes\n",
259                               src_x, src_w);
260                 return -EINVAL;
261         }
262
263         return 0;
264 }
265
266 unsigned int
267 skl_plane_max_stride(struct intel_plane *plane,
268                      u32 pixel_format, u64 modifier,
269                      unsigned int rotation)
270 {
271         int cpp = drm_format_plane_cpp(pixel_format, 0);
272
273         /*
274          * "The stride in bytes must not exceed the
275          * of the size of 8K pixels and 32K bytes."
276          */
277         if (drm_rotation_90_or_270(rotation))
278                 return min(8192, 32768 / cpp);
279         else
280                 return min(8192 * cpp, 32768);
281 }
282
283 void
284 skl_update_plane(struct intel_plane *plane,
285                  const struct intel_crtc_state *crtc_state,
286                  const struct intel_plane_state *plane_state)
287 {
288         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
289         const struct drm_framebuffer *fb = plane_state->base.fb;
290         enum plane_id plane_id = plane->id;
291         enum pipe pipe = plane->pipe;
292         u32 plane_ctl = plane_state->ctl;
293         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
294         u32 surf_addr = plane_state->color_plane[0].offset;
295         u32 stride = skl_plane_stride(plane_state, 0);
296         u32 aux_stride = skl_plane_stride(plane_state, 1);
297         int crtc_x = plane_state->base.dst.x1;
298         int crtc_y = plane_state->base.dst.y1;
299         uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
300         uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
301         uint32_t x = plane_state->color_plane[0].x;
302         uint32_t y = plane_state->color_plane[0].y;
303         uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
304         uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
305         unsigned long irqflags;
306
307         /* Sizes are 0 based */
308         src_w--;
309         src_h--;
310         crtc_w--;
311         crtc_h--;
312
313         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
314
315         if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
316                 I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
317                               plane_state->color_ctl);
318
319         if (key->flags) {
320                 I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
321                 I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), key->max_value);
322                 I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), key->channel_mask);
323         }
324
325         I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
326         I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
327         I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
328         I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
329                       (plane_state->color_plane[1].offset - surf_addr) | aux_stride);
330         I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
331                       (plane_state->color_plane[1].y << 16) |
332                       plane_state->color_plane[1].x);
333
334         /* program plane scaler */
335         if (plane_state->scaler_id >= 0) {
336                 int scaler_id = plane_state->scaler_id;
337                 const struct intel_scaler *scaler =
338                         &crtc_state->scaler_state.scalers[scaler_id];
339                 u16 y_hphase, uv_rgb_hphase;
340                 u16 y_vphase, uv_rgb_vphase;
341
342                 /* TODO: handle sub-pixel coordinates */
343                 if (fb->format->format == DRM_FORMAT_NV12) {
344                         y_hphase = skl_scaler_calc_phase(1, false);
345                         y_vphase = skl_scaler_calc_phase(1, false);
346
347                         /* MPEG2 chroma siting convention */
348                         uv_rgb_hphase = skl_scaler_calc_phase(2, true);
349                         uv_rgb_vphase = skl_scaler_calc_phase(2, false);
350                 } else {
351                         /* not used */
352                         y_hphase = 0;
353                         y_vphase = 0;
354
355                         uv_rgb_hphase = skl_scaler_calc_phase(1, false);
356                         uv_rgb_vphase = skl_scaler_calc_phase(1, false);
357                 }
358
359                 I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
360                               PS_SCALER_EN | PS_PLANE_SEL(plane_id) | scaler->mode);
361                 I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
362                 I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
363                               PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
364                 I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
365                               PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
366                 I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
367                 I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id),
368                               ((crtc_w + 1) << 16)|(crtc_h + 1));
369
370                 I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0);
371         } else {
372                 I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
373         }
374
375         I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
376         I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
377                       intel_plane_ggtt_offset(plane_state) + surf_addr);
378         POSTING_READ_FW(PLANE_SURF(pipe, plane_id));
379
380         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
381 }
382
383 void
384 skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
385 {
386         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
387         enum plane_id plane_id = plane->id;
388         enum pipe pipe = plane->pipe;
389         unsigned long irqflags;
390
391         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
392
393         I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0);
394
395         I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0);
396         POSTING_READ_FW(PLANE_SURF(pipe, plane_id));
397
398         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
399 }
400
401 bool
402 skl_plane_get_hw_state(struct intel_plane *plane,
403                        enum pipe *pipe)
404 {
405         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
406         enum intel_display_power_domain power_domain;
407         enum plane_id plane_id = plane->id;
408         bool ret;
409
410         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
411         if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
412                 return false;
413
414         ret = I915_READ(PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE;
415
416         *pipe = plane->pipe;
417
418         intel_display_power_put(dev_priv, power_domain);
419
420         return ret;
421 }
422
423 static void
424 chv_update_csc(const struct intel_plane_state *plane_state)
425 {
426         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
427         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
428         const struct drm_framebuffer *fb = plane_state->base.fb;
429         enum plane_id plane_id = plane->id;
430         /*
431          * |r|   | c0 c1 c2 |   |cr|
432          * |g| = | c3 c4 c5 | x |y |
433          * |b|   | c6 c7 c8 |   |cb|
434          *
435          * Coefficients are s3.12.
436          *
437          * Cb and Cr apparently come in as signed already, and
438          * we always get full range data in on account of CLRC0/1.
439          */
440         static const s16 csc_matrix[][9] = {
441                 /* BT.601 full range YCbCr -> full range RGB */
442                 [DRM_COLOR_YCBCR_BT601] = {
443                          5743, 4096,     0,
444                         -2925, 4096, -1410,
445                             0, 4096,  7258,
446                 },
447                 /* BT.709 full range YCbCr -> full range RGB */
448                 [DRM_COLOR_YCBCR_BT709] = {
449                          6450, 4096,     0,
450                         -1917, 4096,  -767,
451                             0, 4096,  7601,
452                 },
453         };
454         const s16 *csc = csc_matrix[plane_state->base.color_encoding];
455
456         /* Seems RGB data bypasses the CSC always */
457         if (!fb->format->is_yuv)
458                 return;
459
460         I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
461         I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
462         I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
463
464         I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(csc[1]) | SPCSC_C0(csc[0]));
465         I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(csc[3]) | SPCSC_C0(csc[2]));
466         I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(csc[5]) | SPCSC_C0(csc[4]));
467         I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(csc[7]) | SPCSC_C0(csc[6]));
468         I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(csc[8]));
469
470         I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(1023) | SPCSC_IMIN(0));
471         I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
472         I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
473
474         I915_WRITE_FW(SPCSCYGOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
475         I915_WRITE_FW(SPCSCCBOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
476         I915_WRITE_FW(SPCSCCROCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
477 }
478
479 #define SIN_0 0
480 #define COS_0 1
481
482 static void
483 vlv_update_clrc(const struct intel_plane_state *plane_state)
484 {
485         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
486         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
487         const struct drm_framebuffer *fb = plane_state->base.fb;
488         enum pipe pipe = plane->pipe;
489         enum plane_id plane_id = plane->id;
490         int contrast, brightness, sh_scale, sh_sin, sh_cos;
491
492         if (fb->format->is_yuv &&
493             plane_state->base.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) {
494                 /*
495                  * Expand limited range to full range:
496                  * Contrast is applied first and is used to expand Y range.
497                  * Brightness is applied second and is used to remove the
498                  * offset from Y. Saturation/hue is used to expand CbCr range.
499                  */
500                 contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16);
501                 brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16);
502                 sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128);
503                 sh_sin = SIN_0 * sh_scale;
504                 sh_cos = COS_0 * sh_scale;
505         } else {
506                 /* Pass-through everything. */
507                 contrast = 1 << 6;
508                 brightness = 0;
509                 sh_scale = 1 << 7;
510                 sh_sin = SIN_0 * sh_scale;
511                 sh_cos = COS_0 * sh_scale;
512         }
513
514         /* FIXME these register are single buffered :( */
515         I915_WRITE_FW(SPCLRC0(pipe, plane_id),
516                       SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness));
517         I915_WRITE_FW(SPCLRC1(pipe, plane_id),
518                       SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos));
519 }
520
521 static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state,
522                           const struct intel_plane_state *plane_state)
523 {
524         const struct drm_framebuffer *fb = plane_state->base.fb;
525         unsigned int rotation = plane_state->base.rotation;
526         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
527         u32 sprctl;
528
529         sprctl = SP_ENABLE | SP_GAMMA_ENABLE;
530
531         switch (fb->format->format) {
532         case DRM_FORMAT_YUYV:
533                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
534                 break;
535         case DRM_FORMAT_YVYU:
536                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
537                 break;
538         case DRM_FORMAT_UYVY:
539                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
540                 break;
541         case DRM_FORMAT_VYUY:
542                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
543                 break;
544         case DRM_FORMAT_RGB565:
545                 sprctl |= SP_FORMAT_BGR565;
546                 break;
547         case DRM_FORMAT_XRGB8888:
548                 sprctl |= SP_FORMAT_BGRX8888;
549                 break;
550         case DRM_FORMAT_ARGB8888:
551                 sprctl |= SP_FORMAT_BGRA8888;
552                 break;
553         case DRM_FORMAT_XBGR2101010:
554                 sprctl |= SP_FORMAT_RGBX1010102;
555                 break;
556         case DRM_FORMAT_ABGR2101010:
557                 sprctl |= SP_FORMAT_RGBA1010102;
558                 break;
559         case DRM_FORMAT_XBGR8888:
560                 sprctl |= SP_FORMAT_RGBX8888;
561                 break;
562         case DRM_FORMAT_ABGR8888:
563                 sprctl |= SP_FORMAT_RGBA8888;
564                 break;
565         default:
566                 MISSING_CASE(fb->format->format);
567                 return 0;
568         }
569
570         if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
571                 sprctl |= SP_YUV_FORMAT_BT709;
572
573         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
574                 sprctl |= SP_TILED;
575
576         if (rotation & DRM_MODE_ROTATE_180)
577                 sprctl |= SP_ROTATE_180;
578
579         if (rotation & DRM_MODE_REFLECT_X)
580                 sprctl |= SP_MIRROR;
581
582         if (key->flags & I915_SET_COLORKEY_SOURCE)
583                 sprctl |= SP_SOURCE_KEY;
584
585         return sprctl;
586 }
587
588 static void
589 vlv_update_plane(struct intel_plane *plane,
590                  const struct intel_crtc_state *crtc_state,
591                  const struct intel_plane_state *plane_state)
592 {
593         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
594         const struct drm_framebuffer *fb = plane_state->base.fb;
595         enum pipe pipe = plane->pipe;
596         enum plane_id plane_id = plane->id;
597         u32 sprctl = plane_state->ctl;
598         u32 sprsurf_offset = plane_state->color_plane[0].offset;
599         u32 linear_offset;
600         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
601         int crtc_x = plane_state->base.dst.x1;
602         int crtc_y = plane_state->base.dst.y1;
603         uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
604         uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
605         uint32_t x = plane_state->color_plane[0].x;
606         uint32_t y = plane_state->color_plane[0].y;
607         unsigned long irqflags;
608
609         /* Sizes are 0 based */
610         crtc_w--;
611         crtc_h--;
612
613         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
614
615         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
616
617         vlv_update_clrc(plane_state);
618
619         if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
620                 chv_update_csc(plane_state);
621
622         if (key->flags) {
623                 I915_WRITE_FW(SPKEYMINVAL(pipe, plane_id), key->min_value);
624                 I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value);
625                 I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask);
626         }
627         I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
628                       plane_state->color_plane[0].stride);
629         I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
630
631         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
632                 I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
633         else
634                 I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
635
636         I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
637
638         I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
639         I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl);
640         I915_WRITE_FW(SPSURF(pipe, plane_id),
641                       intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
642         POSTING_READ_FW(SPSURF(pipe, plane_id));
643
644         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
645 }
646
647 static void
648 vlv_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
649 {
650         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
651         enum pipe pipe = plane->pipe;
652         enum plane_id plane_id = plane->id;
653         unsigned long irqflags;
654
655         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
656
657         I915_WRITE_FW(SPCNTR(pipe, plane_id), 0);
658
659         I915_WRITE_FW(SPSURF(pipe, plane_id), 0);
660         POSTING_READ_FW(SPSURF(pipe, plane_id));
661
662         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
663 }
664
665 static bool
666 vlv_plane_get_hw_state(struct intel_plane *plane,
667                        enum pipe *pipe)
668 {
669         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
670         enum intel_display_power_domain power_domain;
671         enum plane_id plane_id = plane->id;
672         bool ret;
673
674         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
675         if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
676                 return false;
677
678         ret = I915_READ(SPCNTR(plane->pipe, plane_id)) & SP_ENABLE;
679
680         *pipe = plane->pipe;
681
682         intel_display_power_put(dev_priv, power_domain);
683
684         return ret;
685 }
686
687 static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
688                           const struct intel_plane_state *plane_state)
689 {
690         struct drm_i915_private *dev_priv =
691                 to_i915(plane_state->base.plane->dev);
692         const struct drm_framebuffer *fb = plane_state->base.fb;
693         unsigned int rotation = plane_state->base.rotation;
694         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
695         u32 sprctl;
696
697         sprctl = SPRITE_ENABLE | SPRITE_GAMMA_ENABLE;
698
699         if (IS_IVYBRIDGE(dev_priv))
700                 sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
701
702         if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
703                 sprctl |= SPRITE_PIPE_CSC_ENABLE;
704
705         switch (fb->format->format) {
706         case DRM_FORMAT_XBGR8888:
707                 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
708                 break;
709         case DRM_FORMAT_XRGB8888:
710                 sprctl |= SPRITE_FORMAT_RGBX888;
711                 break;
712         case DRM_FORMAT_YUYV:
713                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
714                 break;
715         case DRM_FORMAT_YVYU:
716                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
717                 break;
718         case DRM_FORMAT_UYVY:
719                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
720                 break;
721         case DRM_FORMAT_VYUY:
722                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
723                 break;
724         default:
725                 MISSING_CASE(fb->format->format);
726                 return 0;
727         }
728
729         if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
730                 sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
731
732         if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
733                 sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE;
734
735         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
736                 sprctl |= SPRITE_TILED;
737
738         if (rotation & DRM_MODE_ROTATE_180)
739                 sprctl |= SPRITE_ROTATE_180;
740
741         if (key->flags & I915_SET_COLORKEY_DESTINATION)
742                 sprctl |= SPRITE_DEST_KEY;
743         else if (key->flags & I915_SET_COLORKEY_SOURCE)
744                 sprctl |= SPRITE_SOURCE_KEY;
745
746         return sprctl;
747 }
748
749 static void
750 ivb_update_plane(struct intel_plane *plane,
751                  const struct intel_crtc_state *crtc_state,
752                  const struct intel_plane_state *plane_state)
753 {
754         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
755         const struct drm_framebuffer *fb = plane_state->base.fb;
756         enum pipe pipe = plane->pipe;
757         u32 sprctl = plane_state->ctl, sprscale = 0;
758         u32 sprsurf_offset = plane_state->color_plane[0].offset;
759         u32 linear_offset;
760         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
761         int crtc_x = plane_state->base.dst.x1;
762         int crtc_y = plane_state->base.dst.y1;
763         uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
764         uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
765         uint32_t x = plane_state->color_plane[0].x;
766         uint32_t y = plane_state->color_plane[0].y;
767         uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
768         uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
769         unsigned long irqflags;
770
771         /* Sizes are 0 based */
772         src_w--;
773         src_h--;
774         crtc_w--;
775         crtc_h--;
776
777         if (crtc_w != src_w || crtc_h != src_h)
778                 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
779
780         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
781
782         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
783
784         if (key->flags) {
785                 I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value);
786                 I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value);
787                 I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask);
788         }
789
790         I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
791         I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
792
793         /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
794          * register */
795         if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
796                 I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x);
797         else if (fb->modifier == I915_FORMAT_MOD_X_TILED)
798                 I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x);
799         else
800                 I915_WRITE_FW(SPRLINOFF(pipe), linear_offset);
801
802         I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
803         if (IS_IVYBRIDGE(dev_priv))
804                 I915_WRITE_FW(SPRSCALE(pipe), sprscale);
805         I915_WRITE_FW(SPRCTL(pipe), sprctl);
806         I915_WRITE_FW(SPRSURF(pipe),
807                       intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
808         POSTING_READ_FW(SPRSURF(pipe));
809
810         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
811 }
812
813 static void
814 ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
815 {
816         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
817         enum pipe pipe = plane->pipe;
818         unsigned long irqflags;
819
820         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
821
822         I915_WRITE_FW(SPRCTL(pipe), 0);
823         /* Can't leave the scaler enabled... */
824         if (IS_IVYBRIDGE(dev_priv))
825                 I915_WRITE_FW(SPRSCALE(pipe), 0);
826
827         I915_WRITE_FW(SPRSURF(pipe), 0);
828         POSTING_READ_FW(SPRSURF(pipe));
829
830         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
831 }
832
833 static bool
834 ivb_plane_get_hw_state(struct intel_plane *plane,
835                        enum pipe *pipe)
836 {
837         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
838         enum intel_display_power_domain power_domain;
839         bool ret;
840
841         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
842         if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
843                 return false;
844
845         ret =  I915_READ(SPRCTL(plane->pipe)) & SPRITE_ENABLE;
846
847         *pipe = plane->pipe;
848
849         intel_display_power_put(dev_priv, power_domain);
850
851         return ret;
852 }
853
854 static unsigned int
855 g4x_sprite_max_stride(struct intel_plane *plane,
856                       u32 pixel_format, u64 modifier,
857                       unsigned int rotation)
858 {
859         return 16384;
860 }
861
862 static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state,
863                           const struct intel_plane_state *plane_state)
864 {
865         struct drm_i915_private *dev_priv =
866                 to_i915(plane_state->base.plane->dev);
867         const struct drm_framebuffer *fb = plane_state->base.fb;
868         unsigned int rotation = plane_state->base.rotation;
869         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
870         u32 dvscntr;
871
872         dvscntr = DVS_ENABLE | DVS_GAMMA_ENABLE;
873
874         if (IS_GEN6(dev_priv))
875                 dvscntr |= DVS_TRICKLE_FEED_DISABLE;
876
877         switch (fb->format->format) {
878         case DRM_FORMAT_XBGR8888:
879                 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
880                 break;
881         case DRM_FORMAT_XRGB8888:
882                 dvscntr |= DVS_FORMAT_RGBX888;
883                 break;
884         case DRM_FORMAT_YUYV:
885                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
886                 break;
887         case DRM_FORMAT_YVYU:
888                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
889                 break;
890         case DRM_FORMAT_UYVY:
891                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
892                 break;
893         case DRM_FORMAT_VYUY:
894                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
895                 break;
896         default:
897                 MISSING_CASE(fb->format->format);
898                 return 0;
899         }
900
901         if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
902                 dvscntr |= DVS_YUV_FORMAT_BT709;
903
904         if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
905                 dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE;
906
907         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
908                 dvscntr |= DVS_TILED;
909
910         if (rotation & DRM_MODE_ROTATE_180)
911                 dvscntr |= DVS_ROTATE_180;
912
913         if (key->flags & I915_SET_COLORKEY_DESTINATION)
914                 dvscntr |= DVS_DEST_KEY;
915         else if (key->flags & I915_SET_COLORKEY_SOURCE)
916                 dvscntr |= DVS_SOURCE_KEY;
917
918         return dvscntr;
919 }
920
921 static void
922 g4x_update_plane(struct intel_plane *plane,
923                  const struct intel_crtc_state *crtc_state,
924                  const struct intel_plane_state *plane_state)
925 {
926         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
927         const struct drm_framebuffer *fb = plane_state->base.fb;
928         enum pipe pipe = plane->pipe;
929         u32 dvscntr = plane_state->ctl, dvsscale = 0;
930         u32 dvssurf_offset = plane_state->color_plane[0].offset;
931         u32 linear_offset;
932         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
933         int crtc_x = plane_state->base.dst.x1;
934         int crtc_y = plane_state->base.dst.y1;
935         uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
936         uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
937         uint32_t x = plane_state->color_plane[0].x;
938         uint32_t y = plane_state->color_plane[0].y;
939         uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
940         uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
941         unsigned long irqflags;
942
943         /* Sizes are 0 based */
944         src_w--;
945         src_h--;
946         crtc_w--;
947         crtc_h--;
948
949         if (crtc_w != src_w || crtc_h != src_h)
950                 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
951
952         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
953
954         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
955
956         if (key->flags) {
957                 I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value);
958                 I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value);
959                 I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask);
960         }
961
962         I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
963         I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
964
965         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
966                 I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
967         else
968                 I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
969
970         I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
971         I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
972         I915_WRITE_FW(DVSCNTR(pipe), dvscntr);
973         I915_WRITE_FW(DVSSURF(pipe),
974                       intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
975         POSTING_READ_FW(DVSSURF(pipe));
976
977         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
978 }
979
980 static void
981 g4x_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
982 {
983         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
984         enum pipe pipe = plane->pipe;
985         unsigned long irqflags;
986
987         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
988
989         I915_WRITE_FW(DVSCNTR(pipe), 0);
990         /* Disable the scaler */
991         I915_WRITE_FW(DVSSCALE(pipe), 0);
992
993         I915_WRITE_FW(DVSSURF(pipe), 0);
994         POSTING_READ_FW(DVSSURF(pipe));
995
996         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
997 }
998
999 static bool
1000 g4x_plane_get_hw_state(struct intel_plane *plane,
1001                        enum pipe *pipe)
1002 {
1003         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1004         enum intel_display_power_domain power_domain;
1005         bool ret;
1006
1007         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
1008         if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
1009                 return false;
1010
1011         ret = I915_READ(DVSCNTR(plane->pipe)) & DVS_ENABLE;
1012
1013         *pipe = plane->pipe;
1014
1015         intel_display_power_put(dev_priv, power_domain);
1016
1017         return ret;
1018 }
1019
1020 static int
1021 g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
1022                          struct intel_plane_state *plane_state)
1023 {
1024         const struct drm_framebuffer *fb = plane_state->base.fb;
1025         const struct drm_rect *src = &plane_state->base.src;
1026         const struct drm_rect *dst = &plane_state->base.dst;
1027         int src_x, src_y, src_w, src_h, crtc_w, crtc_h;
1028         const struct drm_display_mode *adjusted_mode =
1029                 &crtc_state->base.adjusted_mode;
1030         unsigned int cpp = fb->format->cpp[0];
1031         unsigned int width_bytes;
1032         int min_width, min_height;
1033
1034         crtc_w = drm_rect_width(dst);
1035         crtc_h = drm_rect_height(dst);
1036
1037         src_x = src->x1 >> 16;
1038         src_y = src->y1 >> 16;
1039         src_w = drm_rect_width(src) >> 16;
1040         src_h = drm_rect_height(src) >> 16;
1041
1042         if (src_w == crtc_w && src_h == crtc_h)
1043                 return 0;
1044
1045         min_width = 3;
1046
1047         if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
1048                 if (src_h & 1) {
1049                         DRM_DEBUG_KMS("Source height must be even with interlaced modes\n");
1050                         return -EINVAL;
1051                 }
1052                 min_height = 6;
1053         } else {
1054                 min_height = 3;
1055         }
1056
1057         width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
1058
1059         if (src_w < min_width || src_h < min_height ||
1060             src_w > 2048 || src_h > 2048) {
1061                 DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
1062                               src_w, src_h, min_width, min_height, 2048, 2048);
1063                 return -EINVAL;
1064         }
1065
1066         if (width_bytes > 4096) {
1067                 DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n",
1068                               width_bytes, 4096);
1069                 return -EINVAL;
1070         }
1071
1072         if (width_bytes > 4096 || fb->pitches[0] > 4096) {
1073                 DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n",
1074                               fb->pitches[0], 4096);
1075                 return -EINVAL;
1076         }
1077
1078         return 0;
1079 }
1080
1081 static int
1082 g4x_sprite_check(struct intel_crtc_state *crtc_state,
1083                  struct intel_plane_state *plane_state)
1084 {
1085         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1086         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1087         int max_scale, min_scale;
1088         int ret;
1089
1090         if (INTEL_GEN(dev_priv) < 7) {
1091                 min_scale = 1;
1092                 max_scale = 16 << 16;
1093         } else if (IS_IVYBRIDGE(dev_priv)) {
1094                 min_scale = 1;
1095                 max_scale = 2 << 16;
1096         } else {
1097                 min_scale = DRM_PLANE_HELPER_NO_SCALING;
1098                 max_scale = DRM_PLANE_HELPER_NO_SCALING;
1099         }
1100
1101         ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1102                                                   &crtc_state->base,
1103                                                   min_scale, max_scale,
1104                                                   true, true);
1105         if (ret)
1106                 return ret;
1107
1108         if (!plane_state->base.visible)
1109                 return 0;
1110
1111         ret = intel_plane_check_src_coordinates(plane_state);
1112         if (ret)
1113                 return ret;
1114
1115         ret = g4x_sprite_check_scaling(crtc_state, plane_state);
1116         if (ret)
1117                 return ret;
1118
1119         ret = i9xx_check_plane_surface(plane_state);
1120         if (ret)
1121                 return ret;
1122
1123         if (INTEL_GEN(dev_priv) >= 7)
1124                 plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state);
1125         else
1126                 plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state);
1127
1128         return 0;
1129 }
1130
1131 int chv_plane_check_rotation(const struct intel_plane_state *plane_state)
1132 {
1133         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1134         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1135         unsigned int rotation = plane_state->base.rotation;
1136
1137         /* CHV ignores the mirror bit when the rotate bit is set :( */
1138         if (IS_CHERRYVIEW(dev_priv) &&
1139             rotation & DRM_MODE_ROTATE_180 &&
1140             rotation & DRM_MODE_REFLECT_X) {
1141                 DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n");
1142                 return -EINVAL;
1143         }
1144
1145         return 0;
1146 }
1147
1148 static int
1149 vlv_sprite_check(struct intel_crtc_state *crtc_state,
1150                  struct intel_plane_state *plane_state)
1151 {
1152         int ret;
1153
1154         ret = chv_plane_check_rotation(plane_state);
1155         if (ret)
1156                 return ret;
1157
1158         ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1159                                                   &crtc_state->base,
1160                                                   DRM_PLANE_HELPER_NO_SCALING,
1161                                                   DRM_PLANE_HELPER_NO_SCALING,
1162                                                   true, true);
1163         if (ret)
1164                 return ret;
1165
1166         if (!plane_state->base.visible)
1167                 return 0;
1168
1169         ret = intel_plane_check_src_coordinates(plane_state);
1170         if (ret)
1171                 return ret;
1172
1173         ret = i9xx_check_plane_surface(plane_state);
1174         if (ret)
1175                 return ret;
1176
1177         plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state);
1178
1179         return 0;
1180 }
1181
1182 static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
1183                               const struct intel_plane_state *plane_state)
1184 {
1185         const struct drm_framebuffer *fb = plane_state->base.fb;
1186         unsigned int rotation = plane_state->base.rotation;
1187         struct drm_format_name_buf format_name;
1188
1189         if (!fb)
1190                 return 0;
1191
1192         if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) &&
1193             is_ccs_modifier(fb->modifier)) {
1194                 DRM_DEBUG_KMS("RC support only with 0/180 degree rotation (%x)\n",
1195                               rotation);
1196                 return -EINVAL;
1197         }
1198
1199         if (rotation & DRM_MODE_REFLECT_X &&
1200             fb->modifier == DRM_FORMAT_MOD_LINEAR) {
1201                 DRM_DEBUG_KMS("horizontal flip is not supported with linear surface formats\n");
1202                 return -EINVAL;
1203         }
1204
1205         if (drm_rotation_90_or_270(rotation)) {
1206                 if (fb->modifier != I915_FORMAT_MOD_Y_TILED &&
1207                     fb->modifier != I915_FORMAT_MOD_Yf_TILED) {
1208                         DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n");
1209                         return -EINVAL;
1210                 }
1211
1212                 /*
1213                  * 90/270 is not allowed with RGB64 16:16:16:16,
1214                  * RGB 16-bit 5:6:5, and Indexed 8-bit.
1215                  * TBD: Add RGB64 case once its added in supported format list.
1216                  */
1217                 switch (fb->format->format) {
1218                 case DRM_FORMAT_C8:
1219                 case DRM_FORMAT_RGB565:
1220                         DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n",
1221                                       drm_get_format_name(fb->format->format,
1222                                                           &format_name));
1223                         return -EINVAL;
1224                 default:
1225                         break;
1226                 }
1227         }
1228
1229         /* Y-tiling is not supported in IF-ID Interlace mode */
1230         if (crtc_state->base.enable &&
1231             crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
1232             (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
1233              fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
1234              fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
1235              fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS)) {
1236                 DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n");
1237                 return -EINVAL;
1238         }
1239
1240         return 0;
1241 }
1242
1243 static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state,
1244                                            const struct intel_plane_state *plane_state)
1245 {
1246         struct drm_i915_private *dev_priv =
1247                 to_i915(plane_state->base.plane->dev);
1248         int crtc_x = plane_state->base.dst.x1;
1249         int crtc_w = drm_rect_width(&plane_state->base.dst);
1250         int pipe_src_w = crtc_state->pipe_src_w;
1251
1252         /*
1253          * Display WA #1175: cnl,glk
1254          * Planes other than the cursor may cause FIFO underflow and display
1255          * corruption if starting less than 4 pixels from the right edge of
1256          * the screen.
1257          * Besides the above WA fix the similar problem, where planes other
1258          * than the cursor ending less than 4 pixels from the left edge of the
1259          * screen may cause FIFO underflow and display corruption.
1260          */
1261         if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
1262             (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
1263                 DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n",
1264                               crtc_x + crtc_w < 4 ? "end" : "start",
1265                               crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x,
1266                               4, pipe_src_w - 4);
1267                 return -ERANGE;
1268         }
1269
1270         return 0;
1271 }
1272
1273 int skl_plane_check(struct intel_crtc_state *crtc_state,
1274                     struct intel_plane_state *plane_state)
1275 {
1276         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1277         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1278         int max_scale, min_scale;
1279         int ret;
1280
1281         ret = skl_plane_check_fb(crtc_state, plane_state);
1282         if (ret)
1283                 return ret;
1284
1285         /* use scaler when colorkey is not required */
1286         if (!plane_state->ckey.flags) {
1287                 const struct drm_framebuffer *fb = plane_state->base.fb;
1288
1289                 min_scale = 1;
1290                 max_scale = skl_max_scale(crtc_state,
1291                                           fb ? fb->format->format : 0);
1292         } else {
1293                 min_scale = DRM_PLANE_HELPER_NO_SCALING;
1294                 max_scale = DRM_PLANE_HELPER_NO_SCALING;
1295         }
1296
1297         ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1298                                                   &crtc_state->base,
1299                                                   min_scale, max_scale,
1300                                                   true, true);
1301         if (ret)
1302                 return ret;
1303
1304         if (!plane_state->base.visible)
1305                 return 0;
1306
1307         ret = skl_plane_check_dst_coordinates(crtc_state, plane_state);
1308         if (ret)
1309                 return ret;
1310
1311         ret = intel_plane_check_src_coordinates(plane_state);
1312         if (ret)
1313                 return ret;
1314
1315         ret = skl_check_plane_surface(plane_state);
1316         if (ret)
1317                 return ret;
1318
1319         plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
1320
1321         if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
1322                 plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
1323                                                              plane_state);
1324
1325         return 0;
1326 }
1327
1328 static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv)
1329 {
1330         return INTEL_GEN(dev_priv) >= 9;
1331 }
1332
1333 static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
1334                                  const struct drm_intel_sprite_colorkey *set)
1335 {
1336         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1337         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1338         struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1339
1340         *key = *set;
1341
1342         /*
1343          * We want src key enabled on the
1344          * sprite and not on the primary.
1345          */
1346         if (plane->id == PLANE_PRIMARY &&
1347             set->flags & I915_SET_COLORKEY_SOURCE)
1348                 key->flags = 0;
1349
1350         /*
1351          * On SKL+ we want dst key enabled on
1352          * the primary and not on the sprite.
1353          */
1354         if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_PRIMARY &&
1355             set->flags & I915_SET_COLORKEY_DESTINATION)
1356                 key->flags = 0;
1357 }
1358
1359 int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
1360                                     struct drm_file *file_priv)
1361 {
1362         struct drm_i915_private *dev_priv = to_i915(dev);
1363         struct drm_intel_sprite_colorkey *set = data;
1364         struct drm_plane *plane;
1365         struct drm_plane_state *plane_state;
1366         struct drm_atomic_state *state;
1367         struct drm_modeset_acquire_ctx ctx;
1368         int ret = 0;
1369
1370         /* ignore the pointless "none" flag */
1371         set->flags &= ~I915_SET_COLORKEY_NONE;
1372
1373         if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
1374                 return -EINVAL;
1375
1376         /* Make sure we don't try to enable both src & dest simultaneously */
1377         if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
1378                 return -EINVAL;
1379
1380         if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
1381             set->flags & I915_SET_COLORKEY_DESTINATION)
1382                 return -EINVAL;
1383
1384         plane = drm_plane_find(dev, file_priv, set->plane_id);
1385         if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
1386                 return -ENOENT;
1387
1388         /*
1389          * SKL+ only plane 2 can do destination keying against plane 1.
1390          * Also multiple planes can't do destination keying on the same
1391          * pipe simultaneously.
1392          */
1393         if (INTEL_GEN(dev_priv) >= 9 &&
1394             to_intel_plane(plane)->id >= PLANE_SPRITE1 &&
1395             set->flags & I915_SET_COLORKEY_DESTINATION)
1396                 return -EINVAL;
1397
1398         drm_modeset_acquire_init(&ctx, 0);
1399
1400         state = drm_atomic_state_alloc(plane->dev);
1401         if (!state) {
1402                 ret = -ENOMEM;
1403                 goto out;
1404         }
1405         state->acquire_ctx = &ctx;
1406
1407         while (1) {
1408                 plane_state = drm_atomic_get_plane_state(state, plane);
1409                 ret = PTR_ERR_OR_ZERO(plane_state);
1410                 if (!ret)
1411                         intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
1412
1413                 /*
1414                  * On some platforms we have to configure
1415                  * the dst colorkey on the primary plane.
1416                  */
1417                 if (!ret && has_dst_key_in_primary_plane(dev_priv)) {
1418                         struct intel_crtc *crtc =
1419                                 intel_get_crtc_for_pipe(dev_priv,
1420                                                         to_intel_plane(plane)->pipe);
1421
1422                         plane_state = drm_atomic_get_plane_state(state,
1423                                                                  crtc->base.primary);
1424                         ret = PTR_ERR_OR_ZERO(plane_state);
1425                         if (!ret)
1426                                 intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
1427                 }
1428
1429                 if (!ret)
1430                         ret = drm_atomic_commit(state);
1431
1432                 if (ret != -EDEADLK)
1433                         break;
1434
1435                 drm_atomic_state_clear(state);
1436                 drm_modeset_backoff(&ctx);
1437         }
1438
1439         drm_atomic_state_put(state);
1440 out:
1441         drm_modeset_drop_locks(&ctx);
1442         drm_modeset_acquire_fini(&ctx);
1443         return ret;
1444 }
1445
1446 static const uint32_t g4x_plane_formats[] = {
1447         DRM_FORMAT_XRGB8888,
1448         DRM_FORMAT_YUYV,
1449         DRM_FORMAT_YVYU,
1450         DRM_FORMAT_UYVY,
1451         DRM_FORMAT_VYUY,
1452 };
1453
1454 static const uint64_t i9xx_plane_format_modifiers[] = {
1455         I915_FORMAT_MOD_X_TILED,
1456         DRM_FORMAT_MOD_LINEAR,
1457         DRM_FORMAT_MOD_INVALID
1458 };
1459
1460 static const uint32_t snb_plane_formats[] = {
1461         DRM_FORMAT_XBGR8888,
1462         DRM_FORMAT_XRGB8888,
1463         DRM_FORMAT_YUYV,
1464         DRM_FORMAT_YVYU,
1465         DRM_FORMAT_UYVY,
1466         DRM_FORMAT_VYUY,
1467 };
1468
1469 static const uint32_t vlv_plane_formats[] = {
1470         DRM_FORMAT_RGB565,
1471         DRM_FORMAT_ABGR8888,
1472         DRM_FORMAT_ARGB8888,
1473         DRM_FORMAT_XBGR8888,
1474         DRM_FORMAT_XRGB8888,
1475         DRM_FORMAT_XBGR2101010,
1476         DRM_FORMAT_ABGR2101010,
1477         DRM_FORMAT_YUYV,
1478         DRM_FORMAT_YVYU,
1479         DRM_FORMAT_UYVY,
1480         DRM_FORMAT_VYUY,
1481 };
1482
1483 static uint32_t skl_plane_formats[] = {
1484         DRM_FORMAT_RGB565,
1485         DRM_FORMAT_ABGR8888,
1486         DRM_FORMAT_ARGB8888,
1487         DRM_FORMAT_XBGR8888,
1488         DRM_FORMAT_XRGB8888,
1489         DRM_FORMAT_YUYV,
1490         DRM_FORMAT_YVYU,
1491         DRM_FORMAT_UYVY,
1492         DRM_FORMAT_VYUY,
1493 };
1494
1495 static uint32_t skl_planar_formats[] = {
1496         DRM_FORMAT_RGB565,
1497         DRM_FORMAT_ABGR8888,
1498         DRM_FORMAT_ARGB8888,
1499         DRM_FORMAT_XBGR8888,
1500         DRM_FORMAT_XRGB8888,
1501         DRM_FORMAT_YUYV,
1502         DRM_FORMAT_YVYU,
1503         DRM_FORMAT_UYVY,
1504         DRM_FORMAT_VYUY,
1505         DRM_FORMAT_NV12,
1506 };
1507
1508 static const uint64_t skl_plane_format_modifiers_noccs[] = {
1509         I915_FORMAT_MOD_Yf_TILED,
1510         I915_FORMAT_MOD_Y_TILED,
1511         I915_FORMAT_MOD_X_TILED,
1512         DRM_FORMAT_MOD_LINEAR,
1513         DRM_FORMAT_MOD_INVALID
1514 };
1515
1516 static const uint64_t skl_plane_format_modifiers_ccs[] = {
1517         I915_FORMAT_MOD_Yf_TILED_CCS,
1518         I915_FORMAT_MOD_Y_TILED_CCS,
1519         I915_FORMAT_MOD_Yf_TILED,
1520         I915_FORMAT_MOD_Y_TILED,
1521         I915_FORMAT_MOD_X_TILED,
1522         DRM_FORMAT_MOD_LINEAR,
1523         DRM_FORMAT_MOD_INVALID
1524 };
1525
1526 static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane,
1527                                             u32 format, u64 modifier)
1528 {
1529         switch (modifier) {
1530         case DRM_FORMAT_MOD_LINEAR:
1531         case I915_FORMAT_MOD_X_TILED:
1532                 break;
1533         default:
1534                 return false;
1535         }
1536
1537         switch (format) {
1538         case DRM_FORMAT_XRGB8888:
1539         case DRM_FORMAT_YUYV:
1540         case DRM_FORMAT_YVYU:
1541         case DRM_FORMAT_UYVY:
1542         case DRM_FORMAT_VYUY:
1543                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
1544                     modifier == I915_FORMAT_MOD_X_TILED)
1545                         return true;
1546                 /* fall through */
1547         default:
1548                 return false;
1549         }
1550 }
1551
1552 static bool snb_sprite_format_mod_supported(struct drm_plane *_plane,
1553                                             u32 format, u64 modifier)
1554 {
1555         switch (modifier) {
1556         case DRM_FORMAT_MOD_LINEAR:
1557         case I915_FORMAT_MOD_X_TILED:
1558                 break;
1559         default:
1560                 return false;
1561         }
1562
1563         switch (format) {
1564         case DRM_FORMAT_XRGB8888:
1565         case DRM_FORMAT_XBGR8888:
1566         case DRM_FORMAT_YUYV:
1567         case DRM_FORMAT_YVYU:
1568         case DRM_FORMAT_UYVY:
1569         case DRM_FORMAT_VYUY:
1570                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
1571                     modifier == I915_FORMAT_MOD_X_TILED)
1572                         return true;
1573                 /* fall through */
1574         default:
1575                 return false;
1576         }
1577 }
1578
1579 static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane,
1580                                             u32 format, u64 modifier)
1581 {
1582         switch (modifier) {
1583         case DRM_FORMAT_MOD_LINEAR:
1584         case I915_FORMAT_MOD_X_TILED:
1585                 break;
1586         default:
1587                 return false;
1588         }
1589
1590         switch (format) {
1591         case DRM_FORMAT_RGB565:
1592         case DRM_FORMAT_ABGR8888:
1593         case DRM_FORMAT_ARGB8888:
1594         case DRM_FORMAT_XBGR8888:
1595         case DRM_FORMAT_XRGB8888:
1596         case DRM_FORMAT_XBGR2101010:
1597         case DRM_FORMAT_ABGR2101010:
1598         case DRM_FORMAT_YUYV:
1599         case DRM_FORMAT_YVYU:
1600         case DRM_FORMAT_UYVY:
1601         case DRM_FORMAT_VYUY:
1602                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
1603                     modifier == I915_FORMAT_MOD_X_TILED)
1604                         return true;
1605                 /* fall through */
1606         default:
1607                 return false;
1608         }
1609 }
1610
1611 static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
1612                                            u32 format, u64 modifier)
1613 {
1614         struct intel_plane *plane = to_intel_plane(_plane);
1615
1616         switch (modifier) {
1617         case DRM_FORMAT_MOD_LINEAR:
1618         case I915_FORMAT_MOD_X_TILED:
1619         case I915_FORMAT_MOD_Y_TILED:
1620         case I915_FORMAT_MOD_Yf_TILED:
1621                 break;
1622         case I915_FORMAT_MOD_Y_TILED_CCS:
1623         case I915_FORMAT_MOD_Yf_TILED_CCS:
1624                 if (!plane->has_ccs)
1625                         return false;
1626                 break;
1627         default:
1628                 return false;
1629         }
1630
1631         switch (format) {
1632         case DRM_FORMAT_XRGB8888:
1633         case DRM_FORMAT_XBGR8888:
1634         case DRM_FORMAT_ARGB8888:
1635         case DRM_FORMAT_ABGR8888:
1636                 if (is_ccs_modifier(modifier))
1637                         return true;
1638                 /* fall through */
1639         case DRM_FORMAT_RGB565:
1640         case DRM_FORMAT_XRGB2101010:
1641         case DRM_FORMAT_XBGR2101010:
1642         case DRM_FORMAT_YUYV:
1643         case DRM_FORMAT_YVYU:
1644         case DRM_FORMAT_UYVY:
1645         case DRM_FORMAT_VYUY:
1646         case DRM_FORMAT_NV12:
1647                 if (modifier == I915_FORMAT_MOD_Yf_TILED)
1648                         return true;
1649                 /* fall through */
1650         case DRM_FORMAT_C8:
1651                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
1652                     modifier == I915_FORMAT_MOD_X_TILED ||
1653                     modifier == I915_FORMAT_MOD_Y_TILED)
1654                         return true;
1655                 /* fall through */
1656         default:
1657                 return false;
1658         }
1659 }
1660
1661 static const struct drm_plane_funcs g4x_sprite_funcs = {
1662         .update_plane = drm_atomic_helper_update_plane,
1663         .disable_plane = drm_atomic_helper_disable_plane,
1664         .destroy = intel_plane_destroy,
1665         .atomic_get_property = intel_plane_atomic_get_property,
1666         .atomic_set_property = intel_plane_atomic_set_property,
1667         .atomic_duplicate_state = intel_plane_duplicate_state,
1668         .atomic_destroy_state = intel_plane_destroy_state,
1669         .format_mod_supported = g4x_sprite_format_mod_supported,
1670 };
1671
1672 static const struct drm_plane_funcs snb_sprite_funcs = {
1673         .update_plane = drm_atomic_helper_update_plane,
1674         .disable_plane = drm_atomic_helper_disable_plane,
1675         .destroy = intel_plane_destroy,
1676         .atomic_get_property = intel_plane_atomic_get_property,
1677         .atomic_set_property = intel_plane_atomic_set_property,
1678         .atomic_duplicate_state = intel_plane_duplicate_state,
1679         .atomic_destroy_state = intel_plane_destroy_state,
1680         .format_mod_supported = snb_sprite_format_mod_supported,
1681 };
1682
1683 static const struct drm_plane_funcs vlv_sprite_funcs = {
1684         .update_plane = drm_atomic_helper_update_plane,
1685         .disable_plane = drm_atomic_helper_disable_plane,
1686         .destroy = intel_plane_destroy,
1687         .atomic_get_property = intel_plane_atomic_get_property,
1688         .atomic_set_property = intel_plane_atomic_set_property,
1689         .atomic_duplicate_state = intel_plane_duplicate_state,
1690         .atomic_destroy_state = intel_plane_destroy_state,
1691         .format_mod_supported = vlv_sprite_format_mod_supported,
1692 };
1693
1694 static const struct drm_plane_funcs skl_plane_funcs = {
1695         .update_plane = drm_atomic_helper_update_plane,
1696         .disable_plane = drm_atomic_helper_disable_plane,
1697         .destroy = intel_plane_destroy,
1698         .atomic_get_property = intel_plane_atomic_get_property,
1699         .atomic_set_property = intel_plane_atomic_set_property,
1700         .atomic_duplicate_state = intel_plane_duplicate_state,
1701         .atomic_destroy_state = intel_plane_destroy_state,
1702         .format_mod_supported = skl_plane_format_mod_supported,
1703 };
1704
1705 bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
1706                        enum pipe pipe, enum plane_id plane_id)
1707 {
1708         if (plane_id == PLANE_CURSOR)
1709                 return false;
1710
1711         if (INTEL_GEN(dev_priv) >= 10)
1712                 return true;
1713
1714         if (IS_GEMINILAKE(dev_priv))
1715                 return pipe != PIPE_C;
1716
1717         return pipe != PIPE_C &&
1718                 (plane_id == PLANE_PRIMARY ||
1719                  plane_id == PLANE_SPRITE0);
1720 }
1721
1722 struct intel_plane *
1723 intel_sprite_plane_create(struct drm_i915_private *dev_priv,
1724                           enum pipe pipe, int plane)
1725 {
1726         struct intel_plane *intel_plane = NULL;
1727         struct intel_plane_state *state = NULL;
1728         const struct drm_plane_funcs *plane_funcs;
1729         unsigned long possible_crtcs;
1730         const uint32_t *plane_formats;
1731         const uint64_t *modifiers;
1732         unsigned int supported_rotations;
1733         int num_plane_formats;
1734         int ret;
1735
1736         intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL);
1737         if (!intel_plane) {
1738                 ret = -ENOMEM;
1739                 goto fail;
1740         }
1741
1742         state = intel_create_plane_state(&intel_plane->base);
1743         if (!state) {
1744                 ret = -ENOMEM;
1745                 goto fail;
1746         }
1747         intel_plane->base.state = &state->base;
1748
1749         if (INTEL_GEN(dev_priv) >= 9) {
1750                 state->scaler_id = -1;
1751
1752                 intel_plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe,
1753                                                          PLANE_SPRITE0 + plane);
1754
1755                 intel_plane->max_stride = skl_plane_max_stride;
1756                 intel_plane->update_plane = skl_update_plane;
1757                 intel_plane->disable_plane = skl_disable_plane;
1758                 intel_plane->get_hw_state = skl_plane_get_hw_state;
1759                 intel_plane->check_plane = skl_plane_check;
1760
1761                 if (skl_plane_has_planar(dev_priv, pipe,
1762                                          PLANE_SPRITE0 + plane)) {
1763                         plane_formats = skl_planar_formats;
1764                         num_plane_formats = ARRAY_SIZE(skl_planar_formats);
1765                 } else {
1766                         plane_formats = skl_plane_formats;
1767                         num_plane_formats = ARRAY_SIZE(skl_plane_formats);
1768                 }
1769
1770                 if (intel_plane->has_ccs)
1771                         modifiers = skl_plane_format_modifiers_ccs;
1772                 else
1773                         modifiers = skl_plane_format_modifiers_noccs;
1774
1775                 plane_funcs = &skl_plane_funcs;
1776         } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
1777                 intel_plane->max_stride = i9xx_plane_max_stride;
1778                 intel_plane->update_plane = vlv_update_plane;
1779                 intel_plane->disable_plane = vlv_disable_plane;
1780                 intel_plane->get_hw_state = vlv_plane_get_hw_state;
1781                 intel_plane->check_plane = vlv_sprite_check;
1782
1783                 plane_formats = vlv_plane_formats;
1784                 num_plane_formats = ARRAY_SIZE(vlv_plane_formats);
1785                 modifiers = i9xx_plane_format_modifiers;
1786
1787                 plane_funcs = &vlv_sprite_funcs;
1788         } else if (INTEL_GEN(dev_priv) >= 7) {
1789                 intel_plane->max_stride = g4x_sprite_max_stride;
1790                 intel_plane->update_plane = ivb_update_plane;
1791                 intel_plane->disable_plane = ivb_disable_plane;
1792                 intel_plane->get_hw_state = ivb_plane_get_hw_state;
1793                 intel_plane->check_plane = g4x_sprite_check;
1794
1795                 plane_formats = snb_plane_formats;
1796                 num_plane_formats = ARRAY_SIZE(snb_plane_formats);
1797                 modifiers = i9xx_plane_format_modifiers;
1798
1799                 plane_funcs = &snb_sprite_funcs;
1800         } else {
1801                 intel_plane->max_stride = g4x_sprite_max_stride;
1802                 intel_plane->update_plane = g4x_update_plane;
1803                 intel_plane->disable_plane = g4x_disable_plane;
1804                 intel_plane->get_hw_state = g4x_plane_get_hw_state;
1805                 intel_plane->check_plane = g4x_sprite_check;
1806
1807                 modifiers = i9xx_plane_format_modifiers;
1808                 if (IS_GEN6(dev_priv)) {
1809                         plane_formats = snb_plane_formats;
1810                         num_plane_formats = ARRAY_SIZE(snb_plane_formats);
1811
1812                         plane_funcs = &snb_sprite_funcs;
1813                 } else {
1814                         plane_formats = g4x_plane_formats;
1815                         num_plane_formats = ARRAY_SIZE(g4x_plane_formats);
1816
1817                         plane_funcs = &g4x_sprite_funcs;
1818                 }
1819         }
1820
1821         if (INTEL_GEN(dev_priv) >= 9) {
1822                 supported_rotations =
1823                         DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
1824                         DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
1825         } else if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
1826                 supported_rotations =
1827                         DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
1828                         DRM_MODE_REFLECT_X;
1829         } else {
1830                 supported_rotations =
1831                         DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
1832         }
1833
1834         intel_plane->pipe = pipe;
1835         intel_plane->i9xx_plane = plane;
1836         intel_plane->id = PLANE_SPRITE0 + plane;
1837         intel_plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, intel_plane->id);
1838
1839         possible_crtcs = (1 << pipe);
1840
1841         if (INTEL_GEN(dev_priv) >= 9)
1842                 ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
1843                                                possible_crtcs, plane_funcs,
1844                                                plane_formats, num_plane_formats,
1845                                                modifiers,
1846                                                DRM_PLANE_TYPE_OVERLAY,
1847                                                "plane %d%c", plane + 2, pipe_name(pipe));
1848         else
1849                 ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
1850                                                possible_crtcs, plane_funcs,
1851                                                plane_formats, num_plane_formats,
1852                                                modifiers,
1853                                                DRM_PLANE_TYPE_OVERLAY,
1854                                                "sprite %c", sprite_name(pipe, plane));
1855         if (ret)
1856                 goto fail;
1857
1858         drm_plane_create_rotation_property(&intel_plane->base,
1859                                            DRM_MODE_ROTATE_0,
1860                                            supported_rotations);
1861
1862         drm_plane_create_color_properties(&intel_plane->base,
1863                                           BIT(DRM_COLOR_YCBCR_BT601) |
1864                                           BIT(DRM_COLOR_YCBCR_BT709),
1865                                           BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
1866                                           BIT(DRM_COLOR_YCBCR_FULL_RANGE),
1867                                           DRM_COLOR_YCBCR_BT709,
1868                                           DRM_COLOR_YCBCR_LIMITED_RANGE);
1869
1870         drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs);
1871
1872         return intel_plane;
1873
1874 fail:
1875         kfree(state);
1876         kfree(intel_plane);
1877
1878         return ERR_PTR(ret);
1879 }