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