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