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