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