Merge tag 'for-4.20-rc1-tag' of git://git.kernel.org/pub/scm/linux/kernel/git/kdave...
[sfrench/cifs-2.6.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_stride(const struct intel_plane_state *plane_state)
234 {
235         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
236         const struct drm_framebuffer *fb = plane_state->base.fb;
237         unsigned int rotation = plane_state->base.rotation;
238         u32 stride, max_stride;
239
240         /* FIXME other color planes? */
241         stride = plane_state->color_plane[0].stride;
242         max_stride = plane->max_stride(plane, fb->format->format,
243                                        fb->modifier, rotation);
244
245         if (stride > max_stride) {
246                 DRM_DEBUG_KMS("[FB:%d] stride (%d) exceeds [PLANE:%d:%s] max stride (%d)\n",
247                               fb->base.id, stride,
248                               plane->base.base.id, plane->base.name, max_stride);
249                 return -EINVAL;
250         }
251
252         return 0;
253 }
254
255 int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
256 {
257         const struct drm_framebuffer *fb = plane_state->base.fb;
258         struct drm_rect *src = &plane_state->base.src;
259         u32 src_x, src_y, src_w, src_h;
260
261         /*
262          * Hardware doesn't handle subpixel coordinates.
263          * Adjust to (macro)pixel boundary, but be careful not to
264          * increase the source viewport size, because that could
265          * push the downscaling factor out of bounds.
266          */
267         src_x = src->x1 >> 16;
268         src_w = drm_rect_width(src) >> 16;
269         src_y = src->y1 >> 16;
270         src_h = drm_rect_height(src) >> 16;
271
272         src->x1 = src_x << 16;
273         src->x2 = (src_x + src_w) << 16;
274         src->y1 = src_y << 16;
275         src->y2 = (src_y + src_h) << 16;
276
277         if (fb->format->is_yuv &&
278             fb->format->format != DRM_FORMAT_NV12 &&
279             (src_x & 1 || src_w & 1)) {
280                 DRM_DEBUG_KMS("src x/w (%u, %u) must be a multiple of 2 for YUV planes\n",
281                               src_x, src_w);
282                 return -EINVAL;
283         }
284
285         return 0;
286 }
287
288 unsigned int
289 skl_plane_max_stride(struct intel_plane *plane,
290                      u32 pixel_format, u64 modifier,
291                      unsigned int rotation)
292 {
293         int cpp = drm_format_plane_cpp(pixel_format, 0);
294
295         /*
296          * "The stride in bytes must not exceed the
297          * of the size of 8K pixels and 32K bytes."
298          */
299         if (drm_rotation_90_or_270(rotation))
300                 return min(8192, 32768 / cpp);
301         else
302                 return min(8192 * cpp, 32768);
303 }
304
305 void
306 skl_update_plane(struct intel_plane *plane,
307                  const struct intel_crtc_state *crtc_state,
308                  const struct intel_plane_state *plane_state)
309 {
310         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
311         const struct drm_framebuffer *fb = plane_state->base.fb;
312         enum plane_id plane_id = plane->id;
313         enum pipe pipe = plane->pipe;
314         u32 plane_ctl = plane_state->ctl;
315         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
316         u32 surf_addr = plane_state->color_plane[0].offset;
317         u32 stride = skl_plane_stride(plane_state, 0);
318         u32 aux_stride = skl_plane_stride(plane_state, 1);
319         int crtc_x = plane_state->base.dst.x1;
320         int crtc_y = plane_state->base.dst.y1;
321         uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
322         uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
323         uint32_t x = plane_state->color_plane[0].x;
324         uint32_t y = plane_state->color_plane[0].y;
325         uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
326         uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
327         unsigned long irqflags;
328
329         /* Sizes are 0 based */
330         src_w--;
331         src_h--;
332         crtc_w--;
333         crtc_h--;
334
335         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
336
337         if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
338                 I915_WRITE_FW(PLANE_COLOR_CTL(pipe, plane_id),
339                               plane_state->color_ctl);
340
341         if (key->flags) {
342                 I915_WRITE_FW(PLANE_KEYVAL(pipe, plane_id), key->min_value);
343                 I915_WRITE_FW(PLANE_KEYMAX(pipe, plane_id), key->max_value);
344                 I915_WRITE_FW(PLANE_KEYMSK(pipe, plane_id), key->channel_mask);
345         }
346
347         I915_WRITE_FW(PLANE_OFFSET(pipe, plane_id), (y << 16) | x);
348         I915_WRITE_FW(PLANE_STRIDE(pipe, plane_id), stride);
349         I915_WRITE_FW(PLANE_SIZE(pipe, plane_id), (src_h << 16) | src_w);
350         I915_WRITE_FW(PLANE_AUX_DIST(pipe, plane_id),
351                       (plane_state->color_plane[1].offset - surf_addr) | aux_stride);
352         I915_WRITE_FW(PLANE_AUX_OFFSET(pipe, plane_id),
353                       (plane_state->color_plane[1].y << 16) |
354                       plane_state->color_plane[1].x);
355
356         /* program plane scaler */
357         if (plane_state->scaler_id >= 0) {
358                 int scaler_id = plane_state->scaler_id;
359                 const struct intel_scaler *scaler =
360                         &crtc_state->scaler_state.scalers[scaler_id];
361                 u16 y_hphase, uv_rgb_hphase;
362                 u16 y_vphase, uv_rgb_vphase;
363
364                 /* TODO: handle sub-pixel coordinates */
365                 if (fb->format->format == DRM_FORMAT_NV12) {
366                         y_hphase = skl_scaler_calc_phase(1, false);
367                         y_vphase = skl_scaler_calc_phase(1, false);
368
369                         /* MPEG2 chroma siting convention */
370                         uv_rgb_hphase = skl_scaler_calc_phase(2, true);
371                         uv_rgb_vphase = skl_scaler_calc_phase(2, false);
372                 } else {
373                         /* not used */
374                         y_hphase = 0;
375                         y_vphase = 0;
376
377                         uv_rgb_hphase = skl_scaler_calc_phase(1, false);
378                         uv_rgb_vphase = skl_scaler_calc_phase(1, false);
379                 }
380
381                 I915_WRITE_FW(SKL_PS_CTRL(pipe, scaler_id),
382                               PS_SCALER_EN | PS_PLANE_SEL(plane_id) | scaler->mode);
383                 I915_WRITE_FW(SKL_PS_PWR_GATE(pipe, scaler_id), 0);
384                 I915_WRITE_FW(SKL_PS_VPHASE(pipe, scaler_id),
385                               PS_Y_PHASE(y_vphase) | PS_UV_RGB_PHASE(uv_rgb_vphase));
386                 I915_WRITE_FW(SKL_PS_HPHASE(pipe, scaler_id),
387                               PS_Y_PHASE(y_hphase) | PS_UV_RGB_PHASE(uv_rgb_hphase));
388                 I915_WRITE_FW(SKL_PS_WIN_POS(pipe, scaler_id), (crtc_x << 16) | crtc_y);
389                 I915_WRITE_FW(SKL_PS_WIN_SZ(pipe, scaler_id),
390                               ((crtc_w + 1) << 16)|(crtc_h + 1));
391
392                 I915_WRITE_FW(PLANE_POS(pipe, plane_id), 0);
393         } else {
394                 I915_WRITE_FW(PLANE_POS(pipe, plane_id), (crtc_y << 16) | crtc_x);
395         }
396
397         I915_WRITE_FW(PLANE_CTL(pipe, plane_id), plane_ctl);
398         I915_WRITE_FW(PLANE_SURF(pipe, plane_id),
399                       intel_plane_ggtt_offset(plane_state) + surf_addr);
400         POSTING_READ_FW(PLANE_SURF(pipe, plane_id));
401
402         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
403 }
404
405 void
406 skl_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
407 {
408         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
409         enum plane_id plane_id = plane->id;
410         enum pipe pipe = plane->pipe;
411         unsigned long irqflags;
412
413         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
414
415         I915_WRITE_FW(PLANE_CTL(pipe, plane_id), 0);
416
417         I915_WRITE_FW(PLANE_SURF(pipe, plane_id), 0);
418         POSTING_READ_FW(PLANE_SURF(pipe, plane_id));
419
420         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
421 }
422
423 bool
424 skl_plane_get_hw_state(struct intel_plane *plane,
425                        enum pipe *pipe)
426 {
427         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
428         enum intel_display_power_domain power_domain;
429         enum plane_id plane_id = plane->id;
430         bool ret;
431
432         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
433         if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
434                 return false;
435
436         ret = I915_READ(PLANE_CTL(plane->pipe, plane_id)) & PLANE_CTL_ENABLE;
437
438         *pipe = plane->pipe;
439
440         intel_display_power_put(dev_priv, power_domain);
441
442         return ret;
443 }
444
445 static void
446 chv_update_csc(const struct intel_plane_state *plane_state)
447 {
448         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
449         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
450         const struct drm_framebuffer *fb = plane_state->base.fb;
451         enum plane_id plane_id = plane->id;
452         /*
453          * |r|   | c0 c1 c2 |   |cr|
454          * |g| = | c3 c4 c5 | x |y |
455          * |b|   | c6 c7 c8 |   |cb|
456          *
457          * Coefficients are s3.12.
458          *
459          * Cb and Cr apparently come in as signed already, and
460          * we always get full range data in on account of CLRC0/1.
461          */
462         static const s16 csc_matrix[][9] = {
463                 /* BT.601 full range YCbCr -> full range RGB */
464                 [DRM_COLOR_YCBCR_BT601] = {
465                          5743, 4096,     0,
466                         -2925, 4096, -1410,
467                             0, 4096,  7258,
468                 },
469                 /* BT.709 full range YCbCr -> full range RGB */
470                 [DRM_COLOR_YCBCR_BT709] = {
471                          6450, 4096,     0,
472                         -1917, 4096,  -767,
473                             0, 4096,  7601,
474                 },
475         };
476         const s16 *csc = csc_matrix[plane_state->base.color_encoding];
477
478         /* Seems RGB data bypasses the CSC always */
479         if (!fb->format->is_yuv)
480                 return;
481
482         I915_WRITE_FW(SPCSCYGOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
483         I915_WRITE_FW(SPCSCCBOFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
484         I915_WRITE_FW(SPCSCCROFF(plane_id), SPCSC_OOFF(0) | SPCSC_IOFF(0));
485
486         I915_WRITE_FW(SPCSCC01(plane_id), SPCSC_C1(csc[1]) | SPCSC_C0(csc[0]));
487         I915_WRITE_FW(SPCSCC23(plane_id), SPCSC_C1(csc[3]) | SPCSC_C0(csc[2]));
488         I915_WRITE_FW(SPCSCC45(plane_id), SPCSC_C1(csc[5]) | SPCSC_C0(csc[4]));
489         I915_WRITE_FW(SPCSCC67(plane_id), SPCSC_C1(csc[7]) | SPCSC_C0(csc[6]));
490         I915_WRITE_FW(SPCSCC8(plane_id), SPCSC_C0(csc[8]));
491
492         I915_WRITE_FW(SPCSCYGICLAMP(plane_id), SPCSC_IMAX(1023) | SPCSC_IMIN(0));
493         I915_WRITE_FW(SPCSCCBICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
494         I915_WRITE_FW(SPCSCCRICLAMP(plane_id), SPCSC_IMAX(512) | SPCSC_IMIN(-512));
495
496         I915_WRITE_FW(SPCSCYGOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
497         I915_WRITE_FW(SPCSCCBOCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
498         I915_WRITE_FW(SPCSCCROCLAMP(plane_id), SPCSC_OMAX(1023) | SPCSC_OMIN(0));
499 }
500
501 #define SIN_0 0
502 #define COS_0 1
503
504 static void
505 vlv_update_clrc(const struct intel_plane_state *plane_state)
506 {
507         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
508         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
509         const struct drm_framebuffer *fb = plane_state->base.fb;
510         enum pipe pipe = plane->pipe;
511         enum plane_id plane_id = plane->id;
512         int contrast, brightness, sh_scale, sh_sin, sh_cos;
513
514         if (fb->format->is_yuv &&
515             plane_state->base.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) {
516                 /*
517                  * Expand limited range to full range:
518                  * Contrast is applied first and is used to expand Y range.
519                  * Brightness is applied second and is used to remove the
520                  * offset from Y. Saturation/hue is used to expand CbCr range.
521                  */
522                 contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16);
523                 brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16);
524                 sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128);
525                 sh_sin = SIN_0 * sh_scale;
526                 sh_cos = COS_0 * sh_scale;
527         } else {
528                 /* Pass-through everything. */
529                 contrast = 1 << 6;
530                 brightness = 0;
531                 sh_scale = 1 << 7;
532                 sh_sin = SIN_0 * sh_scale;
533                 sh_cos = COS_0 * sh_scale;
534         }
535
536         /* FIXME these register are single buffered :( */
537         I915_WRITE_FW(SPCLRC0(pipe, plane_id),
538                       SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness));
539         I915_WRITE_FW(SPCLRC1(pipe, plane_id),
540                       SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos));
541 }
542
543 static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state,
544                           const struct intel_plane_state *plane_state)
545 {
546         const struct drm_framebuffer *fb = plane_state->base.fb;
547         unsigned int rotation = plane_state->base.rotation;
548         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
549         u32 sprctl;
550
551         sprctl = SP_ENABLE | SP_GAMMA_ENABLE;
552
553         switch (fb->format->format) {
554         case DRM_FORMAT_YUYV:
555                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
556                 break;
557         case DRM_FORMAT_YVYU:
558                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
559                 break;
560         case DRM_FORMAT_UYVY:
561                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
562                 break;
563         case DRM_FORMAT_VYUY:
564                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
565                 break;
566         case DRM_FORMAT_RGB565:
567                 sprctl |= SP_FORMAT_BGR565;
568                 break;
569         case DRM_FORMAT_XRGB8888:
570                 sprctl |= SP_FORMAT_BGRX8888;
571                 break;
572         case DRM_FORMAT_ARGB8888:
573                 sprctl |= SP_FORMAT_BGRA8888;
574                 break;
575         case DRM_FORMAT_XBGR2101010:
576                 sprctl |= SP_FORMAT_RGBX1010102;
577                 break;
578         case DRM_FORMAT_ABGR2101010:
579                 sprctl |= SP_FORMAT_RGBA1010102;
580                 break;
581         case DRM_FORMAT_XBGR8888:
582                 sprctl |= SP_FORMAT_RGBX8888;
583                 break;
584         case DRM_FORMAT_ABGR8888:
585                 sprctl |= SP_FORMAT_RGBA8888;
586                 break;
587         default:
588                 MISSING_CASE(fb->format->format);
589                 return 0;
590         }
591
592         if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
593                 sprctl |= SP_YUV_FORMAT_BT709;
594
595         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
596                 sprctl |= SP_TILED;
597
598         if (rotation & DRM_MODE_ROTATE_180)
599                 sprctl |= SP_ROTATE_180;
600
601         if (rotation & DRM_MODE_REFLECT_X)
602                 sprctl |= SP_MIRROR;
603
604         if (key->flags & I915_SET_COLORKEY_SOURCE)
605                 sprctl |= SP_SOURCE_KEY;
606
607         return sprctl;
608 }
609
610 static void
611 vlv_update_plane(struct intel_plane *plane,
612                  const struct intel_crtc_state *crtc_state,
613                  const struct intel_plane_state *plane_state)
614 {
615         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
616         const struct drm_framebuffer *fb = plane_state->base.fb;
617         enum pipe pipe = plane->pipe;
618         enum plane_id plane_id = plane->id;
619         u32 sprctl = plane_state->ctl;
620         u32 sprsurf_offset = plane_state->color_plane[0].offset;
621         u32 linear_offset;
622         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
623         int crtc_x = plane_state->base.dst.x1;
624         int crtc_y = plane_state->base.dst.y1;
625         uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
626         uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
627         uint32_t x = plane_state->color_plane[0].x;
628         uint32_t y = plane_state->color_plane[0].y;
629         unsigned long irqflags;
630
631         /* Sizes are 0 based */
632         crtc_w--;
633         crtc_h--;
634
635         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
636
637         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
638
639         vlv_update_clrc(plane_state);
640
641         if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
642                 chv_update_csc(plane_state);
643
644         if (key->flags) {
645                 I915_WRITE_FW(SPKEYMINVAL(pipe, plane_id), key->min_value);
646                 I915_WRITE_FW(SPKEYMAXVAL(pipe, plane_id), key->max_value);
647                 I915_WRITE_FW(SPKEYMSK(pipe, plane_id), key->channel_mask);
648         }
649         I915_WRITE_FW(SPSTRIDE(pipe, plane_id),
650                       plane_state->color_plane[0].stride);
651         I915_WRITE_FW(SPPOS(pipe, plane_id), (crtc_y << 16) | crtc_x);
652
653         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
654                 I915_WRITE_FW(SPTILEOFF(pipe, plane_id), (y << 16) | x);
655         else
656                 I915_WRITE_FW(SPLINOFF(pipe, plane_id), linear_offset);
657
658         I915_WRITE_FW(SPCONSTALPHA(pipe, plane_id), 0);
659
660         I915_WRITE_FW(SPSIZE(pipe, plane_id), (crtc_h << 16) | crtc_w);
661         I915_WRITE_FW(SPCNTR(pipe, plane_id), sprctl);
662         I915_WRITE_FW(SPSURF(pipe, plane_id),
663                       intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
664         POSTING_READ_FW(SPSURF(pipe, plane_id));
665
666         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
667 }
668
669 static void
670 vlv_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
671 {
672         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
673         enum pipe pipe = plane->pipe;
674         enum plane_id plane_id = plane->id;
675         unsigned long irqflags;
676
677         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
678
679         I915_WRITE_FW(SPCNTR(pipe, plane_id), 0);
680
681         I915_WRITE_FW(SPSURF(pipe, plane_id), 0);
682         POSTING_READ_FW(SPSURF(pipe, plane_id));
683
684         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
685 }
686
687 static bool
688 vlv_plane_get_hw_state(struct intel_plane *plane,
689                        enum pipe *pipe)
690 {
691         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
692         enum intel_display_power_domain power_domain;
693         enum plane_id plane_id = plane->id;
694         bool ret;
695
696         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
697         if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
698                 return false;
699
700         ret = I915_READ(SPCNTR(plane->pipe, plane_id)) & SP_ENABLE;
701
702         *pipe = plane->pipe;
703
704         intel_display_power_put(dev_priv, power_domain);
705
706         return ret;
707 }
708
709 static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
710                           const struct intel_plane_state *plane_state)
711 {
712         struct drm_i915_private *dev_priv =
713                 to_i915(plane_state->base.plane->dev);
714         const struct drm_framebuffer *fb = plane_state->base.fb;
715         unsigned int rotation = plane_state->base.rotation;
716         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
717         u32 sprctl;
718
719         sprctl = SPRITE_ENABLE | SPRITE_GAMMA_ENABLE;
720
721         if (IS_IVYBRIDGE(dev_priv))
722                 sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
723
724         if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
725                 sprctl |= SPRITE_PIPE_CSC_ENABLE;
726
727         switch (fb->format->format) {
728         case DRM_FORMAT_XBGR8888:
729                 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
730                 break;
731         case DRM_FORMAT_XRGB8888:
732                 sprctl |= SPRITE_FORMAT_RGBX888;
733                 break;
734         case DRM_FORMAT_YUYV:
735                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
736                 break;
737         case DRM_FORMAT_YVYU:
738                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
739                 break;
740         case DRM_FORMAT_UYVY:
741                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
742                 break;
743         case DRM_FORMAT_VYUY:
744                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
745                 break;
746         default:
747                 MISSING_CASE(fb->format->format);
748                 return 0;
749         }
750
751         if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
752                 sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
753
754         if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
755                 sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE;
756
757         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
758                 sprctl |= SPRITE_TILED;
759
760         if (rotation & DRM_MODE_ROTATE_180)
761                 sprctl |= SPRITE_ROTATE_180;
762
763         if (key->flags & I915_SET_COLORKEY_DESTINATION)
764                 sprctl |= SPRITE_DEST_KEY;
765         else if (key->flags & I915_SET_COLORKEY_SOURCE)
766                 sprctl |= SPRITE_SOURCE_KEY;
767
768         return sprctl;
769 }
770
771 static void
772 ivb_update_plane(struct intel_plane *plane,
773                  const struct intel_crtc_state *crtc_state,
774                  const struct intel_plane_state *plane_state)
775 {
776         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
777         const struct drm_framebuffer *fb = plane_state->base.fb;
778         enum pipe pipe = plane->pipe;
779         u32 sprctl = plane_state->ctl, sprscale = 0;
780         u32 sprsurf_offset = plane_state->color_plane[0].offset;
781         u32 linear_offset;
782         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
783         int crtc_x = plane_state->base.dst.x1;
784         int crtc_y = plane_state->base.dst.y1;
785         uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
786         uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
787         uint32_t x = plane_state->color_plane[0].x;
788         uint32_t y = plane_state->color_plane[0].y;
789         uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
790         uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
791         unsigned long irqflags;
792
793         /* Sizes are 0 based */
794         src_w--;
795         src_h--;
796         crtc_w--;
797         crtc_h--;
798
799         if (crtc_w != src_w || crtc_h != src_h)
800                 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
801
802         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
803
804         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
805
806         if (key->flags) {
807                 I915_WRITE_FW(SPRKEYVAL(pipe), key->min_value);
808                 I915_WRITE_FW(SPRKEYMAX(pipe), key->max_value);
809                 I915_WRITE_FW(SPRKEYMSK(pipe), key->channel_mask);
810         }
811
812         I915_WRITE_FW(SPRSTRIDE(pipe), plane_state->color_plane[0].stride);
813         I915_WRITE_FW(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
814
815         /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
816          * register */
817         if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv))
818                 I915_WRITE_FW(SPROFFSET(pipe), (y << 16) | x);
819         else if (fb->modifier == I915_FORMAT_MOD_X_TILED)
820                 I915_WRITE_FW(SPRTILEOFF(pipe), (y << 16) | x);
821         else
822                 I915_WRITE_FW(SPRLINOFF(pipe), linear_offset);
823
824         I915_WRITE_FW(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
825         if (IS_IVYBRIDGE(dev_priv))
826                 I915_WRITE_FW(SPRSCALE(pipe), sprscale);
827         I915_WRITE_FW(SPRCTL(pipe), sprctl);
828         I915_WRITE_FW(SPRSURF(pipe),
829                       intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
830         POSTING_READ_FW(SPRSURF(pipe));
831
832         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
833 }
834
835 static void
836 ivb_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
837 {
838         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
839         enum pipe pipe = plane->pipe;
840         unsigned long irqflags;
841
842         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
843
844         I915_WRITE_FW(SPRCTL(pipe), 0);
845         /* Can't leave the scaler enabled... */
846         if (IS_IVYBRIDGE(dev_priv))
847                 I915_WRITE_FW(SPRSCALE(pipe), 0);
848
849         I915_WRITE_FW(SPRSURF(pipe), 0);
850         POSTING_READ_FW(SPRSURF(pipe));
851
852         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
853 }
854
855 static bool
856 ivb_plane_get_hw_state(struct intel_plane *plane,
857                        enum pipe *pipe)
858 {
859         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
860         enum intel_display_power_domain power_domain;
861         bool ret;
862
863         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
864         if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
865                 return false;
866
867         ret =  I915_READ(SPRCTL(plane->pipe)) & SPRITE_ENABLE;
868
869         *pipe = plane->pipe;
870
871         intel_display_power_put(dev_priv, power_domain);
872
873         return ret;
874 }
875
876 static unsigned int
877 g4x_sprite_max_stride(struct intel_plane *plane,
878                       u32 pixel_format, u64 modifier,
879                       unsigned int rotation)
880 {
881         return 16384;
882 }
883
884 static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state,
885                           const struct intel_plane_state *plane_state)
886 {
887         struct drm_i915_private *dev_priv =
888                 to_i915(plane_state->base.plane->dev);
889         const struct drm_framebuffer *fb = plane_state->base.fb;
890         unsigned int rotation = plane_state->base.rotation;
891         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
892         u32 dvscntr;
893
894         dvscntr = DVS_ENABLE | DVS_GAMMA_ENABLE;
895
896         if (IS_GEN6(dev_priv))
897                 dvscntr |= DVS_TRICKLE_FEED_DISABLE;
898
899         switch (fb->format->format) {
900         case DRM_FORMAT_XBGR8888:
901                 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
902                 break;
903         case DRM_FORMAT_XRGB8888:
904                 dvscntr |= DVS_FORMAT_RGBX888;
905                 break;
906         case DRM_FORMAT_YUYV:
907                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
908                 break;
909         case DRM_FORMAT_YVYU:
910                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
911                 break;
912         case DRM_FORMAT_UYVY:
913                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
914                 break;
915         case DRM_FORMAT_VYUY:
916                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
917                 break;
918         default:
919                 MISSING_CASE(fb->format->format);
920                 return 0;
921         }
922
923         if (plane_state->base.color_encoding == DRM_COLOR_YCBCR_BT709)
924                 dvscntr |= DVS_YUV_FORMAT_BT709;
925
926         if (plane_state->base.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
927                 dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE;
928
929         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
930                 dvscntr |= DVS_TILED;
931
932         if (rotation & DRM_MODE_ROTATE_180)
933                 dvscntr |= DVS_ROTATE_180;
934
935         if (key->flags & I915_SET_COLORKEY_DESTINATION)
936                 dvscntr |= DVS_DEST_KEY;
937         else if (key->flags & I915_SET_COLORKEY_SOURCE)
938                 dvscntr |= DVS_SOURCE_KEY;
939
940         return dvscntr;
941 }
942
943 static void
944 g4x_update_plane(struct intel_plane *plane,
945                  const struct intel_crtc_state *crtc_state,
946                  const struct intel_plane_state *plane_state)
947 {
948         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
949         const struct drm_framebuffer *fb = plane_state->base.fb;
950         enum pipe pipe = plane->pipe;
951         u32 dvscntr = plane_state->ctl, dvsscale = 0;
952         u32 dvssurf_offset = plane_state->color_plane[0].offset;
953         u32 linear_offset;
954         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
955         int crtc_x = plane_state->base.dst.x1;
956         int crtc_y = plane_state->base.dst.y1;
957         uint32_t crtc_w = drm_rect_width(&plane_state->base.dst);
958         uint32_t crtc_h = drm_rect_height(&plane_state->base.dst);
959         uint32_t x = plane_state->color_plane[0].x;
960         uint32_t y = plane_state->color_plane[0].y;
961         uint32_t src_w = drm_rect_width(&plane_state->base.src) >> 16;
962         uint32_t src_h = drm_rect_height(&plane_state->base.src) >> 16;
963         unsigned long irqflags;
964
965         /* Sizes are 0 based */
966         src_w--;
967         src_h--;
968         crtc_w--;
969         crtc_h--;
970
971         if (crtc_w != src_w || crtc_h != src_h)
972                 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
973
974         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
975
976         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
977
978         if (key->flags) {
979                 I915_WRITE_FW(DVSKEYVAL(pipe), key->min_value);
980                 I915_WRITE_FW(DVSKEYMAX(pipe), key->max_value);
981                 I915_WRITE_FW(DVSKEYMSK(pipe), key->channel_mask);
982         }
983
984         I915_WRITE_FW(DVSSTRIDE(pipe), plane_state->color_plane[0].stride);
985         I915_WRITE_FW(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
986
987         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
988                 I915_WRITE_FW(DVSTILEOFF(pipe), (y << 16) | x);
989         else
990                 I915_WRITE_FW(DVSLINOFF(pipe), linear_offset);
991
992         I915_WRITE_FW(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
993         I915_WRITE_FW(DVSSCALE(pipe), dvsscale);
994         I915_WRITE_FW(DVSCNTR(pipe), dvscntr);
995         I915_WRITE_FW(DVSSURF(pipe),
996                       intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
997         POSTING_READ_FW(DVSSURF(pipe));
998
999         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1000 }
1001
1002 static void
1003 g4x_disable_plane(struct intel_plane *plane, struct intel_crtc *crtc)
1004 {
1005         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1006         enum pipe pipe = plane->pipe;
1007         unsigned long irqflags;
1008
1009         spin_lock_irqsave(&dev_priv->uncore.lock, irqflags);
1010
1011         I915_WRITE_FW(DVSCNTR(pipe), 0);
1012         /* Disable the scaler */
1013         I915_WRITE_FW(DVSSCALE(pipe), 0);
1014
1015         I915_WRITE_FW(DVSSURF(pipe), 0);
1016         POSTING_READ_FW(DVSSURF(pipe));
1017
1018         spin_unlock_irqrestore(&dev_priv->uncore.lock, irqflags);
1019 }
1020
1021 static bool
1022 g4x_plane_get_hw_state(struct intel_plane *plane,
1023                        enum pipe *pipe)
1024 {
1025         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1026         enum intel_display_power_domain power_domain;
1027         bool ret;
1028
1029         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
1030         if (!intel_display_power_get_if_enabled(dev_priv, power_domain))
1031                 return false;
1032
1033         ret = I915_READ(DVSCNTR(plane->pipe)) & DVS_ENABLE;
1034
1035         *pipe = plane->pipe;
1036
1037         intel_display_power_put(dev_priv, power_domain);
1038
1039         return ret;
1040 }
1041
1042 static int
1043 g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
1044                          struct intel_plane_state *plane_state)
1045 {
1046         const struct drm_framebuffer *fb = plane_state->base.fb;
1047         const struct drm_rect *src = &plane_state->base.src;
1048         const struct drm_rect *dst = &plane_state->base.dst;
1049         int src_x, src_y, src_w, src_h, crtc_w, crtc_h;
1050         const struct drm_display_mode *adjusted_mode =
1051                 &crtc_state->base.adjusted_mode;
1052         unsigned int cpp = fb->format->cpp[0];
1053         unsigned int width_bytes;
1054         int min_width, min_height;
1055
1056         crtc_w = drm_rect_width(dst);
1057         crtc_h = drm_rect_height(dst);
1058
1059         src_x = src->x1 >> 16;
1060         src_y = src->y1 >> 16;
1061         src_w = drm_rect_width(src) >> 16;
1062         src_h = drm_rect_height(src) >> 16;
1063
1064         if (src_w == crtc_w && src_h == crtc_h)
1065                 return 0;
1066
1067         min_width = 3;
1068
1069         if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
1070                 if (src_h & 1) {
1071                         DRM_DEBUG_KMS("Source height must be even with interlaced modes\n");
1072                         return -EINVAL;
1073                 }
1074                 min_height = 6;
1075         } else {
1076                 min_height = 3;
1077         }
1078
1079         width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
1080
1081         if (src_w < min_width || src_h < min_height ||
1082             src_w > 2048 || src_h > 2048) {
1083                 DRM_DEBUG_KMS("Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
1084                               src_w, src_h, min_width, min_height, 2048, 2048);
1085                 return -EINVAL;
1086         }
1087
1088         if (width_bytes > 4096) {
1089                 DRM_DEBUG_KMS("Fetch width (%d) exceeds hardware max with scaling (%u)\n",
1090                               width_bytes, 4096);
1091                 return -EINVAL;
1092         }
1093
1094         if (width_bytes > 4096 || fb->pitches[0] > 4096) {
1095                 DRM_DEBUG_KMS("Stride (%u) exceeds hardware max with scaling (%u)\n",
1096                               fb->pitches[0], 4096);
1097                 return -EINVAL;
1098         }
1099
1100         return 0;
1101 }
1102
1103 static int
1104 g4x_sprite_check(struct intel_crtc_state *crtc_state,
1105                  struct intel_plane_state *plane_state)
1106 {
1107         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1108         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1109         int max_scale, min_scale;
1110         int ret;
1111
1112         if (INTEL_GEN(dev_priv) < 7) {
1113                 min_scale = 1;
1114                 max_scale = 16 << 16;
1115         } else if (IS_IVYBRIDGE(dev_priv)) {
1116                 min_scale = 1;
1117                 max_scale = 2 << 16;
1118         } else {
1119                 min_scale = DRM_PLANE_HELPER_NO_SCALING;
1120                 max_scale = DRM_PLANE_HELPER_NO_SCALING;
1121         }
1122
1123         ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1124                                                   &crtc_state->base,
1125                                                   min_scale, max_scale,
1126                                                   true, true);
1127         if (ret)
1128                 return ret;
1129
1130         if (!plane_state->base.visible)
1131                 return 0;
1132
1133         ret = intel_plane_check_src_coordinates(plane_state);
1134         if (ret)
1135                 return ret;
1136
1137         ret = g4x_sprite_check_scaling(crtc_state, plane_state);
1138         if (ret)
1139                 return ret;
1140
1141         ret = i9xx_check_plane_surface(plane_state);
1142         if (ret)
1143                 return ret;
1144
1145         if (INTEL_GEN(dev_priv) >= 7)
1146                 plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state);
1147         else
1148                 plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state);
1149
1150         return 0;
1151 }
1152
1153 int chv_plane_check_rotation(const struct intel_plane_state *plane_state)
1154 {
1155         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1156         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1157         unsigned int rotation = plane_state->base.rotation;
1158
1159         /* CHV ignores the mirror bit when the rotate bit is set :( */
1160         if (IS_CHERRYVIEW(dev_priv) &&
1161             rotation & DRM_MODE_ROTATE_180 &&
1162             rotation & DRM_MODE_REFLECT_X) {
1163                 DRM_DEBUG_KMS("Cannot rotate and reflect at the same time\n");
1164                 return -EINVAL;
1165         }
1166
1167         return 0;
1168 }
1169
1170 static int
1171 vlv_sprite_check(struct intel_crtc_state *crtc_state,
1172                  struct intel_plane_state *plane_state)
1173 {
1174         int ret;
1175
1176         ret = chv_plane_check_rotation(plane_state);
1177         if (ret)
1178                 return ret;
1179
1180         ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1181                                                   &crtc_state->base,
1182                                                   DRM_PLANE_HELPER_NO_SCALING,
1183                                                   DRM_PLANE_HELPER_NO_SCALING,
1184                                                   true, true);
1185         if (ret)
1186                 return ret;
1187
1188         if (!plane_state->base.visible)
1189                 return 0;
1190
1191         ret = intel_plane_check_src_coordinates(plane_state);
1192         if (ret)
1193                 return ret;
1194
1195         ret = i9xx_check_plane_surface(plane_state);
1196         if (ret)
1197                 return ret;
1198
1199         plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state);
1200
1201         return 0;
1202 }
1203
1204 static int skl_plane_check_fb(const struct intel_crtc_state *crtc_state,
1205                               const struct intel_plane_state *plane_state)
1206 {
1207         const struct drm_framebuffer *fb = plane_state->base.fb;
1208         unsigned int rotation = plane_state->base.rotation;
1209         struct drm_format_name_buf format_name;
1210
1211         if (!fb)
1212                 return 0;
1213
1214         if (rotation & ~(DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180) &&
1215             is_ccs_modifier(fb->modifier)) {
1216                 DRM_DEBUG_KMS("RC support only with 0/180 degree rotation (%x)\n",
1217                               rotation);
1218                 return -EINVAL;
1219         }
1220
1221         if (rotation & DRM_MODE_REFLECT_X &&
1222             fb->modifier == DRM_FORMAT_MOD_LINEAR) {
1223                 DRM_DEBUG_KMS("horizontal flip is not supported with linear surface formats\n");
1224                 return -EINVAL;
1225         }
1226
1227         if (drm_rotation_90_or_270(rotation)) {
1228                 if (fb->modifier != I915_FORMAT_MOD_Y_TILED &&
1229                     fb->modifier != I915_FORMAT_MOD_Yf_TILED) {
1230                         DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n");
1231                         return -EINVAL;
1232                 }
1233
1234                 /*
1235                  * 90/270 is not allowed with RGB64 16:16:16:16,
1236                  * RGB 16-bit 5:6:5, and Indexed 8-bit.
1237                  * TBD: Add RGB64 case once its added in supported format list.
1238                  */
1239                 switch (fb->format->format) {
1240                 case DRM_FORMAT_C8:
1241                 case DRM_FORMAT_RGB565:
1242                         DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n",
1243                                       drm_get_format_name(fb->format->format,
1244                                                           &format_name));
1245                         return -EINVAL;
1246                 default:
1247                         break;
1248                 }
1249         }
1250
1251         /* Y-tiling is not supported in IF-ID Interlace mode */
1252         if (crtc_state->base.enable &&
1253             crtc_state->base.adjusted_mode.flags & DRM_MODE_FLAG_INTERLACE &&
1254             (fb->modifier == I915_FORMAT_MOD_Y_TILED ||
1255              fb->modifier == I915_FORMAT_MOD_Yf_TILED ||
1256              fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
1257              fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS)) {
1258                 DRM_DEBUG_KMS("Y/Yf tiling not supported in IF-ID mode\n");
1259                 return -EINVAL;
1260         }
1261
1262         return 0;
1263 }
1264
1265 static int skl_plane_check_dst_coordinates(const struct intel_crtc_state *crtc_state,
1266                                            const struct intel_plane_state *plane_state)
1267 {
1268         struct drm_i915_private *dev_priv =
1269                 to_i915(plane_state->base.plane->dev);
1270         int crtc_x = plane_state->base.dst.x1;
1271         int crtc_w = drm_rect_width(&plane_state->base.dst);
1272         int pipe_src_w = crtc_state->pipe_src_w;
1273
1274         /*
1275          * Display WA #1175: cnl,glk
1276          * Planes other than the cursor may cause FIFO underflow and display
1277          * corruption if starting less than 4 pixels from the right edge of
1278          * the screen.
1279          * Besides the above WA fix the similar problem, where planes other
1280          * than the cursor ending less than 4 pixels from the left edge of the
1281          * screen may cause FIFO underflow and display corruption.
1282          */
1283         if ((IS_GEMINILAKE(dev_priv) || IS_CANNONLAKE(dev_priv)) &&
1284             (crtc_x + crtc_w < 4 || crtc_x > pipe_src_w - 4)) {
1285                 DRM_DEBUG_KMS("requested plane X %s position %d invalid (valid range %d-%d)\n",
1286                               crtc_x + crtc_w < 4 ? "end" : "start",
1287                               crtc_x + crtc_w < 4 ? crtc_x + crtc_w : crtc_x,
1288                               4, pipe_src_w - 4);
1289                 return -ERANGE;
1290         }
1291
1292         return 0;
1293 }
1294
1295 int skl_plane_check(struct intel_crtc_state *crtc_state,
1296                     struct intel_plane_state *plane_state)
1297 {
1298         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1299         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1300         int max_scale, min_scale;
1301         int ret;
1302
1303         ret = skl_plane_check_fb(crtc_state, plane_state);
1304         if (ret)
1305                 return ret;
1306
1307         /* use scaler when colorkey is not required */
1308         if (!plane_state->ckey.flags) {
1309                 const struct drm_framebuffer *fb = plane_state->base.fb;
1310
1311                 min_scale = 1;
1312                 max_scale = skl_max_scale(crtc_state,
1313                                           fb ? fb->format->format : 0);
1314         } else {
1315                 min_scale = DRM_PLANE_HELPER_NO_SCALING;
1316                 max_scale = DRM_PLANE_HELPER_NO_SCALING;
1317         }
1318
1319         ret = drm_atomic_helper_check_plane_state(&plane_state->base,
1320                                                   &crtc_state->base,
1321                                                   min_scale, max_scale,
1322                                                   true, true);
1323         if (ret)
1324                 return ret;
1325
1326         if (!plane_state->base.visible)
1327                 return 0;
1328
1329         ret = skl_plane_check_dst_coordinates(crtc_state, plane_state);
1330         if (ret)
1331                 return ret;
1332
1333         ret = intel_plane_check_src_coordinates(plane_state);
1334         if (ret)
1335                 return ret;
1336
1337         ret = skl_check_plane_surface(plane_state);
1338         if (ret)
1339                 return ret;
1340
1341         plane_state->ctl = skl_plane_ctl(crtc_state, plane_state);
1342
1343         if (INTEL_GEN(dev_priv) >= 10 || IS_GEMINILAKE(dev_priv))
1344                 plane_state->color_ctl = glk_plane_color_ctl(crtc_state,
1345                                                              plane_state);
1346
1347         return 0;
1348 }
1349
1350 static bool has_dst_key_in_primary_plane(struct drm_i915_private *dev_priv)
1351 {
1352         return INTEL_GEN(dev_priv) >= 9;
1353 }
1354
1355 static void intel_plane_set_ckey(struct intel_plane_state *plane_state,
1356                                  const struct drm_intel_sprite_colorkey *set)
1357 {
1358         struct intel_plane *plane = to_intel_plane(plane_state->base.plane);
1359         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1360         struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1361
1362         *key = *set;
1363
1364         /*
1365          * We want src key enabled on the
1366          * sprite and not on the primary.
1367          */
1368         if (plane->id == PLANE_PRIMARY &&
1369             set->flags & I915_SET_COLORKEY_SOURCE)
1370                 key->flags = 0;
1371
1372         /*
1373          * On SKL+ we want dst key enabled on
1374          * the primary and not on the sprite.
1375          */
1376         if (INTEL_GEN(dev_priv) >= 9 && plane->id != PLANE_PRIMARY &&
1377             set->flags & I915_SET_COLORKEY_DESTINATION)
1378                 key->flags = 0;
1379 }
1380
1381 int intel_sprite_set_colorkey_ioctl(struct drm_device *dev, void *data,
1382                                     struct drm_file *file_priv)
1383 {
1384         struct drm_i915_private *dev_priv = to_i915(dev);
1385         struct drm_intel_sprite_colorkey *set = data;
1386         struct drm_plane *plane;
1387         struct drm_plane_state *plane_state;
1388         struct drm_atomic_state *state;
1389         struct drm_modeset_acquire_ctx ctx;
1390         int ret = 0;
1391
1392         /* ignore the pointless "none" flag */
1393         set->flags &= ~I915_SET_COLORKEY_NONE;
1394
1395         if (set->flags & ~(I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
1396                 return -EINVAL;
1397
1398         /* Make sure we don't try to enable both src & dest simultaneously */
1399         if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
1400                 return -EINVAL;
1401
1402         if ((IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) &&
1403             set->flags & I915_SET_COLORKEY_DESTINATION)
1404                 return -EINVAL;
1405
1406         plane = drm_plane_find(dev, file_priv, set->plane_id);
1407         if (!plane || plane->type != DRM_PLANE_TYPE_OVERLAY)
1408                 return -ENOENT;
1409
1410         /*
1411          * SKL+ only plane 2 can do destination keying against plane 1.
1412          * Also multiple planes can't do destination keying on the same
1413          * pipe simultaneously.
1414          */
1415         if (INTEL_GEN(dev_priv) >= 9 &&
1416             to_intel_plane(plane)->id >= PLANE_SPRITE1 &&
1417             set->flags & I915_SET_COLORKEY_DESTINATION)
1418                 return -EINVAL;
1419
1420         drm_modeset_acquire_init(&ctx, 0);
1421
1422         state = drm_atomic_state_alloc(plane->dev);
1423         if (!state) {
1424                 ret = -ENOMEM;
1425                 goto out;
1426         }
1427         state->acquire_ctx = &ctx;
1428
1429         while (1) {
1430                 plane_state = drm_atomic_get_plane_state(state, plane);
1431                 ret = PTR_ERR_OR_ZERO(plane_state);
1432                 if (!ret)
1433                         intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
1434
1435                 /*
1436                  * On some platforms we have to configure
1437                  * the dst colorkey on the primary plane.
1438                  */
1439                 if (!ret && has_dst_key_in_primary_plane(dev_priv)) {
1440                         struct intel_crtc *crtc =
1441                                 intel_get_crtc_for_pipe(dev_priv,
1442                                                         to_intel_plane(plane)->pipe);
1443
1444                         plane_state = drm_atomic_get_plane_state(state,
1445                                                                  crtc->base.primary);
1446                         ret = PTR_ERR_OR_ZERO(plane_state);
1447                         if (!ret)
1448                                 intel_plane_set_ckey(to_intel_plane_state(plane_state), set);
1449                 }
1450
1451                 if (!ret)
1452                         ret = drm_atomic_commit(state);
1453
1454                 if (ret != -EDEADLK)
1455                         break;
1456
1457                 drm_atomic_state_clear(state);
1458                 drm_modeset_backoff(&ctx);
1459         }
1460
1461         drm_atomic_state_put(state);
1462 out:
1463         drm_modeset_drop_locks(&ctx);
1464         drm_modeset_acquire_fini(&ctx);
1465         return ret;
1466 }
1467
1468 static const uint32_t g4x_plane_formats[] = {
1469         DRM_FORMAT_XRGB8888,
1470         DRM_FORMAT_YUYV,
1471         DRM_FORMAT_YVYU,
1472         DRM_FORMAT_UYVY,
1473         DRM_FORMAT_VYUY,
1474 };
1475
1476 static const uint64_t i9xx_plane_format_modifiers[] = {
1477         I915_FORMAT_MOD_X_TILED,
1478         DRM_FORMAT_MOD_LINEAR,
1479         DRM_FORMAT_MOD_INVALID
1480 };
1481
1482 static const uint32_t snb_plane_formats[] = {
1483         DRM_FORMAT_XBGR8888,
1484         DRM_FORMAT_XRGB8888,
1485         DRM_FORMAT_YUYV,
1486         DRM_FORMAT_YVYU,
1487         DRM_FORMAT_UYVY,
1488         DRM_FORMAT_VYUY,
1489 };
1490
1491 static const uint32_t vlv_plane_formats[] = {
1492         DRM_FORMAT_RGB565,
1493         DRM_FORMAT_ABGR8888,
1494         DRM_FORMAT_ARGB8888,
1495         DRM_FORMAT_XBGR8888,
1496         DRM_FORMAT_XRGB8888,
1497         DRM_FORMAT_XBGR2101010,
1498         DRM_FORMAT_ABGR2101010,
1499         DRM_FORMAT_YUYV,
1500         DRM_FORMAT_YVYU,
1501         DRM_FORMAT_UYVY,
1502         DRM_FORMAT_VYUY,
1503 };
1504
1505 static uint32_t skl_plane_formats[] = {
1506         DRM_FORMAT_RGB565,
1507         DRM_FORMAT_ABGR8888,
1508         DRM_FORMAT_ARGB8888,
1509         DRM_FORMAT_XBGR8888,
1510         DRM_FORMAT_XRGB8888,
1511         DRM_FORMAT_YUYV,
1512         DRM_FORMAT_YVYU,
1513         DRM_FORMAT_UYVY,
1514         DRM_FORMAT_VYUY,
1515 };
1516
1517 static uint32_t skl_planar_formats[] = {
1518         DRM_FORMAT_RGB565,
1519         DRM_FORMAT_ABGR8888,
1520         DRM_FORMAT_ARGB8888,
1521         DRM_FORMAT_XBGR8888,
1522         DRM_FORMAT_XRGB8888,
1523         DRM_FORMAT_YUYV,
1524         DRM_FORMAT_YVYU,
1525         DRM_FORMAT_UYVY,
1526         DRM_FORMAT_VYUY,
1527         DRM_FORMAT_NV12,
1528 };
1529
1530 static const uint64_t skl_plane_format_modifiers_noccs[] = {
1531         I915_FORMAT_MOD_Yf_TILED,
1532         I915_FORMAT_MOD_Y_TILED,
1533         I915_FORMAT_MOD_X_TILED,
1534         DRM_FORMAT_MOD_LINEAR,
1535         DRM_FORMAT_MOD_INVALID
1536 };
1537
1538 static const uint64_t skl_plane_format_modifiers_ccs[] = {
1539         I915_FORMAT_MOD_Yf_TILED_CCS,
1540         I915_FORMAT_MOD_Y_TILED_CCS,
1541         I915_FORMAT_MOD_Yf_TILED,
1542         I915_FORMAT_MOD_Y_TILED,
1543         I915_FORMAT_MOD_X_TILED,
1544         DRM_FORMAT_MOD_LINEAR,
1545         DRM_FORMAT_MOD_INVALID
1546 };
1547
1548 static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane,
1549                                             u32 format, u64 modifier)
1550 {
1551         switch (modifier) {
1552         case DRM_FORMAT_MOD_LINEAR:
1553         case I915_FORMAT_MOD_X_TILED:
1554                 break;
1555         default:
1556                 return false;
1557         }
1558
1559         switch (format) {
1560         case DRM_FORMAT_XRGB8888:
1561         case DRM_FORMAT_YUYV:
1562         case DRM_FORMAT_YVYU:
1563         case DRM_FORMAT_UYVY:
1564         case DRM_FORMAT_VYUY:
1565                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
1566                     modifier == I915_FORMAT_MOD_X_TILED)
1567                         return true;
1568                 /* fall through */
1569         default:
1570                 return false;
1571         }
1572 }
1573
1574 static bool snb_sprite_format_mod_supported(struct drm_plane *_plane,
1575                                             u32 format, u64 modifier)
1576 {
1577         switch (modifier) {
1578         case DRM_FORMAT_MOD_LINEAR:
1579         case I915_FORMAT_MOD_X_TILED:
1580                 break;
1581         default:
1582                 return false;
1583         }
1584
1585         switch (format) {
1586         case DRM_FORMAT_XRGB8888:
1587         case DRM_FORMAT_XBGR8888:
1588         case DRM_FORMAT_YUYV:
1589         case DRM_FORMAT_YVYU:
1590         case DRM_FORMAT_UYVY:
1591         case DRM_FORMAT_VYUY:
1592                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
1593                     modifier == I915_FORMAT_MOD_X_TILED)
1594                         return true;
1595                 /* fall through */
1596         default:
1597                 return false;
1598         }
1599 }
1600
1601 static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane,
1602                                             u32 format, u64 modifier)
1603 {
1604         switch (modifier) {
1605         case DRM_FORMAT_MOD_LINEAR:
1606         case I915_FORMAT_MOD_X_TILED:
1607                 break;
1608         default:
1609                 return false;
1610         }
1611
1612         switch (format) {
1613         case DRM_FORMAT_RGB565:
1614         case DRM_FORMAT_ABGR8888:
1615         case DRM_FORMAT_ARGB8888:
1616         case DRM_FORMAT_XBGR8888:
1617         case DRM_FORMAT_XRGB8888:
1618         case DRM_FORMAT_XBGR2101010:
1619         case DRM_FORMAT_ABGR2101010:
1620         case DRM_FORMAT_YUYV:
1621         case DRM_FORMAT_YVYU:
1622         case DRM_FORMAT_UYVY:
1623         case DRM_FORMAT_VYUY:
1624                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
1625                     modifier == I915_FORMAT_MOD_X_TILED)
1626                         return true;
1627                 /* fall through */
1628         default:
1629                 return false;
1630         }
1631 }
1632
1633 static bool skl_plane_format_mod_supported(struct drm_plane *_plane,
1634                                            u32 format, u64 modifier)
1635 {
1636         struct intel_plane *plane = to_intel_plane(_plane);
1637
1638         switch (modifier) {
1639         case DRM_FORMAT_MOD_LINEAR:
1640         case I915_FORMAT_MOD_X_TILED:
1641         case I915_FORMAT_MOD_Y_TILED:
1642         case I915_FORMAT_MOD_Yf_TILED:
1643                 break;
1644         case I915_FORMAT_MOD_Y_TILED_CCS:
1645         case I915_FORMAT_MOD_Yf_TILED_CCS:
1646                 if (!plane->has_ccs)
1647                         return false;
1648                 break;
1649         default:
1650                 return false;
1651         }
1652
1653         switch (format) {
1654         case DRM_FORMAT_XRGB8888:
1655         case DRM_FORMAT_XBGR8888:
1656         case DRM_FORMAT_ARGB8888:
1657         case DRM_FORMAT_ABGR8888:
1658                 if (is_ccs_modifier(modifier))
1659                         return true;
1660                 /* fall through */
1661         case DRM_FORMAT_RGB565:
1662         case DRM_FORMAT_XRGB2101010:
1663         case DRM_FORMAT_XBGR2101010:
1664         case DRM_FORMAT_YUYV:
1665         case DRM_FORMAT_YVYU:
1666         case DRM_FORMAT_UYVY:
1667         case DRM_FORMAT_VYUY:
1668         case DRM_FORMAT_NV12:
1669                 if (modifier == I915_FORMAT_MOD_Yf_TILED)
1670                         return true;
1671                 /* fall through */
1672         case DRM_FORMAT_C8:
1673                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
1674                     modifier == I915_FORMAT_MOD_X_TILED ||
1675                     modifier == I915_FORMAT_MOD_Y_TILED)
1676                         return true;
1677                 /* fall through */
1678         default:
1679                 return false;
1680         }
1681 }
1682
1683 static const struct drm_plane_funcs g4x_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 = g4x_sprite_format_mod_supported,
1692 };
1693
1694 static const struct drm_plane_funcs snb_sprite_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 = snb_sprite_format_mod_supported,
1703 };
1704
1705 static const struct drm_plane_funcs vlv_sprite_funcs = {
1706         .update_plane = drm_atomic_helper_update_plane,
1707         .disable_plane = drm_atomic_helper_disable_plane,
1708         .destroy = intel_plane_destroy,
1709         .atomic_get_property = intel_plane_atomic_get_property,
1710         .atomic_set_property = intel_plane_atomic_set_property,
1711         .atomic_duplicate_state = intel_plane_duplicate_state,
1712         .atomic_destroy_state = intel_plane_destroy_state,
1713         .format_mod_supported = vlv_sprite_format_mod_supported,
1714 };
1715
1716 static const struct drm_plane_funcs skl_plane_funcs = {
1717         .update_plane = drm_atomic_helper_update_plane,
1718         .disable_plane = drm_atomic_helper_disable_plane,
1719         .destroy = intel_plane_destroy,
1720         .atomic_get_property = intel_plane_atomic_get_property,
1721         .atomic_set_property = intel_plane_atomic_set_property,
1722         .atomic_duplicate_state = intel_plane_duplicate_state,
1723         .atomic_destroy_state = intel_plane_destroy_state,
1724         .format_mod_supported = skl_plane_format_mod_supported,
1725 };
1726
1727 bool skl_plane_has_ccs(struct drm_i915_private *dev_priv,
1728                        enum pipe pipe, enum plane_id plane_id)
1729 {
1730         if (plane_id == PLANE_CURSOR)
1731                 return false;
1732
1733         if (INTEL_GEN(dev_priv) >= 10)
1734                 return true;
1735
1736         if (IS_GEMINILAKE(dev_priv))
1737                 return pipe != PIPE_C;
1738
1739         return pipe != PIPE_C &&
1740                 (plane_id == PLANE_PRIMARY ||
1741                  plane_id == PLANE_SPRITE0);
1742 }
1743
1744 struct intel_plane *
1745 intel_sprite_plane_create(struct drm_i915_private *dev_priv,
1746                           enum pipe pipe, int plane)
1747 {
1748         struct intel_plane *intel_plane = NULL;
1749         struct intel_plane_state *state = NULL;
1750         const struct drm_plane_funcs *plane_funcs;
1751         unsigned long possible_crtcs;
1752         const uint32_t *plane_formats;
1753         const uint64_t *modifiers;
1754         unsigned int supported_rotations;
1755         int num_plane_formats;
1756         int ret;
1757
1758         intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL);
1759         if (!intel_plane) {
1760                 ret = -ENOMEM;
1761                 goto fail;
1762         }
1763
1764         state = intel_create_plane_state(&intel_plane->base);
1765         if (!state) {
1766                 ret = -ENOMEM;
1767                 goto fail;
1768         }
1769         intel_plane->base.state = &state->base;
1770
1771         if (INTEL_GEN(dev_priv) >= 9) {
1772                 state->scaler_id = -1;
1773
1774                 intel_plane->has_ccs = skl_plane_has_ccs(dev_priv, pipe,
1775                                                          PLANE_SPRITE0 + plane);
1776
1777                 intel_plane->max_stride = skl_plane_max_stride;
1778                 intel_plane->update_plane = skl_update_plane;
1779                 intel_plane->disable_plane = skl_disable_plane;
1780                 intel_plane->get_hw_state = skl_plane_get_hw_state;
1781                 intel_plane->check_plane = skl_plane_check;
1782
1783                 if (skl_plane_has_planar(dev_priv, pipe,
1784                                          PLANE_SPRITE0 + plane)) {
1785                         plane_formats = skl_planar_formats;
1786                         num_plane_formats = ARRAY_SIZE(skl_planar_formats);
1787                 } else {
1788                         plane_formats = skl_plane_formats;
1789                         num_plane_formats = ARRAY_SIZE(skl_plane_formats);
1790                 }
1791
1792                 if (intel_plane->has_ccs)
1793                         modifiers = skl_plane_format_modifiers_ccs;
1794                 else
1795                         modifiers = skl_plane_format_modifiers_noccs;
1796
1797                 plane_funcs = &skl_plane_funcs;
1798         } else if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
1799                 intel_plane->max_stride = i9xx_plane_max_stride;
1800                 intel_plane->update_plane = vlv_update_plane;
1801                 intel_plane->disable_plane = vlv_disable_plane;
1802                 intel_plane->get_hw_state = vlv_plane_get_hw_state;
1803                 intel_plane->check_plane = vlv_sprite_check;
1804
1805                 plane_formats = vlv_plane_formats;
1806                 num_plane_formats = ARRAY_SIZE(vlv_plane_formats);
1807                 modifiers = i9xx_plane_format_modifiers;
1808
1809                 plane_funcs = &vlv_sprite_funcs;
1810         } else if (INTEL_GEN(dev_priv) >= 7) {
1811                 intel_plane->max_stride = g4x_sprite_max_stride;
1812                 intel_plane->update_plane = ivb_update_plane;
1813                 intel_plane->disable_plane = ivb_disable_plane;
1814                 intel_plane->get_hw_state = ivb_plane_get_hw_state;
1815                 intel_plane->check_plane = g4x_sprite_check;
1816
1817                 plane_formats = snb_plane_formats;
1818                 num_plane_formats = ARRAY_SIZE(snb_plane_formats);
1819                 modifiers = i9xx_plane_format_modifiers;
1820
1821                 plane_funcs = &snb_sprite_funcs;
1822         } else {
1823                 intel_plane->max_stride = g4x_sprite_max_stride;
1824                 intel_plane->update_plane = g4x_update_plane;
1825                 intel_plane->disable_plane = g4x_disable_plane;
1826                 intel_plane->get_hw_state = g4x_plane_get_hw_state;
1827                 intel_plane->check_plane = g4x_sprite_check;
1828
1829                 modifiers = i9xx_plane_format_modifiers;
1830                 if (IS_GEN6(dev_priv)) {
1831                         plane_formats = snb_plane_formats;
1832                         num_plane_formats = ARRAY_SIZE(snb_plane_formats);
1833
1834                         plane_funcs = &snb_sprite_funcs;
1835                 } else {
1836                         plane_formats = g4x_plane_formats;
1837                         num_plane_formats = ARRAY_SIZE(g4x_plane_formats);
1838
1839                         plane_funcs = &g4x_sprite_funcs;
1840                 }
1841         }
1842
1843         if (INTEL_GEN(dev_priv) >= 9) {
1844                 supported_rotations =
1845                         DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_90 |
1846                         DRM_MODE_ROTATE_180 | DRM_MODE_ROTATE_270;
1847         } else if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
1848                 supported_rotations =
1849                         DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
1850                         DRM_MODE_REFLECT_X;
1851         } else {
1852                 supported_rotations =
1853                         DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
1854         }
1855
1856         intel_plane->pipe = pipe;
1857         intel_plane->i9xx_plane = plane;
1858         intel_plane->id = PLANE_SPRITE0 + plane;
1859         intel_plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, intel_plane->id);
1860
1861         possible_crtcs = (1 << pipe);
1862
1863         if (INTEL_GEN(dev_priv) >= 9)
1864                 ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
1865                                                possible_crtcs, plane_funcs,
1866                                                plane_formats, num_plane_formats,
1867                                                modifiers,
1868                                                DRM_PLANE_TYPE_OVERLAY,
1869                                                "plane %d%c", plane + 2, pipe_name(pipe));
1870         else
1871                 ret = drm_universal_plane_init(&dev_priv->drm, &intel_plane->base,
1872                                                possible_crtcs, plane_funcs,
1873                                                plane_formats, num_plane_formats,
1874                                                modifiers,
1875                                                DRM_PLANE_TYPE_OVERLAY,
1876                                                "sprite %c", sprite_name(pipe, plane));
1877         if (ret)
1878                 goto fail;
1879
1880         drm_plane_create_rotation_property(&intel_plane->base,
1881                                            DRM_MODE_ROTATE_0,
1882                                            supported_rotations);
1883
1884         drm_plane_create_color_properties(&intel_plane->base,
1885                                           BIT(DRM_COLOR_YCBCR_BT601) |
1886                                           BIT(DRM_COLOR_YCBCR_BT709),
1887                                           BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
1888                                           BIT(DRM_COLOR_YCBCR_FULL_RANGE),
1889                                           DRM_COLOR_YCBCR_BT709,
1890                                           DRM_COLOR_YCBCR_LIMITED_RANGE);
1891
1892         drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs);
1893
1894         return intel_plane;
1895
1896 fail:
1897         kfree(state);
1898         kfree(intel_plane);
1899
1900         return ERR_PTR(ret);
1901 }