750b634d45eced1387e7a9a8b950bb7f5fe881ed
[linux-2.6-block.git] / drivers / gpu / drm / i915 / intel_sprite.c
1 /*
2  * Copyright © 2011 Intel Corporation
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice (including the next
12  * paragraph) shall be included in all copies or substantial portions of the
13  * Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21  * SOFTWARE.
22  *
23  * Authors:
24  *   Jesse Barnes <jbarnes@virtuousgeek.org>
25  *
26  * New plane/sprite handling.
27  *
28  * The older chips had a separate interface for programming plane related
29  * registers; newer ones are much simpler and we can use the new DRM plane
30  * support.
31  */
32 #include <drm/drmP.h>
33 #include <drm/drm_crtc.h>
34 #include <drm/drm_fourcc.h>
35 #include <drm/drm_rect.h>
36 #include "intel_drv.h"
37 #include <drm/i915_drm.h>
38 #include "i915_drv.h"
39
40 static int usecs_to_scanlines(const struct drm_display_mode *mode, int usecs)
41 {
42         /* paranoia */
43         if (!mode->crtc_htotal)
44                 return 1;
45
46         return DIV_ROUND_UP(usecs * mode->crtc_clock, 1000 * mode->crtc_htotal);
47 }
48
49 static bool intel_pipe_update_start(struct intel_crtc *crtc, uint32_t *start_vbl_count)
50 {
51         struct drm_device *dev = crtc->base.dev;
52         const struct drm_display_mode *mode = &crtc->config.adjusted_mode;
53         enum pipe pipe = crtc->pipe;
54         long timeout = msecs_to_jiffies_timeout(1);
55         int scanline, min, max, vblank_start;
56         wait_queue_head_t *wq = drm_crtc_vblank_waitqueue(&crtc->base);
57         DEFINE_WAIT(wait);
58
59         WARN_ON(!drm_modeset_is_locked(&crtc->base.mutex));
60
61         vblank_start = mode->crtc_vblank_start;
62         if (mode->flags & DRM_MODE_FLAG_INTERLACE)
63                 vblank_start = DIV_ROUND_UP(vblank_start, 2);
64
65         /* FIXME needs to be calibrated sensibly */
66         min = vblank_start - usecs_to_scanlines(mode, 100);
67         max = vblank_start - 1;
68
69         if (min <= 0 || max <= 0)
70                 return false;
71
72         if (WARN_ON(drm_vblank_get(dev, pipe)))
73                 return false;
74
75         local_irq_disable();
76
77         trace_i915_pipe_update_start(crtc, min, max);
78
79         for (;;) {
80                 /*
81                  * prepare_to_wait() has a memory barrier, which guarantees
82                  * other CPUs can see the task state update by the time we
83                  * read the scanline.
84                  */
85                 prepare_to_wait(wq, &wait, TASK_UNINTERRUPTIBLE);
86
87                 scanline = intel_get_crtc_scanline(crtc);
88                 if (scanline < min || scanline > max)
89                         break;
90
91                 if (timeout <= 0) {
92                         DRM_ERROR("Potential atomic update failure on pipe %c\n",
93                                   pipe_name(crtc->pipe));
94                         break;
95                 }
96
97                 local_irq_enable();
98
99                 timeout = schedule_timeout(timeout);
100
101                 local_irq_disable();
102         }
103
104         finish_wait(wq, &wait);
105
106         drm_vblank_put(dev, pipe);
107
108         *start_vbl_count = dev->driver->get_vblank_counter(dev, pipe);
109
110         trace_i915_pipe_update_vblank_evaded(crtc, min, max, *start_vbl_count);
111
112         return true;
113 }
114
115 static void intel_pipe_update_end(struct intel_crtc *crtc, u32 start_vbl_count)
116 {
117         struct drm_device *dev = crtc->base.dev;
118         enum pipe pipe = crtc->pipe;
119         u32 end_vbl_count = dev->driver->get_vblank_counter(dev, pipe);
120
121         trace_i915_pipe_update_end(crtc, end_vbl_count);
122
123         local_irq_enable();
124
125         if (start_vbl_count != end_vbl_count)
126                 DRM_ERROR("Atomic update failure on pipe %c (start=%u end=%u)\n",
127                           pipe_name(pipe), start_vbl_count, end_vbl_count);
128 }
129
130 static void intel_update_primary_plane(struct intel_crtc *crtc)
131 {
132         struct drm_i915_private *dev_priv = crtc->base.dev->dev_private;
133         int reg = DSPCNTR(crtc->plane);
134
135         if (crtc->primary_enabled)
136                 I915_WRITE(reg, I915_READ(reg) | DISPLAY_PLANE_ENABLE);
137         else
138                 I915_WRITE(reg, I915_READ(reg) & ~DISPLAY_PLANE_ENABLE);
139 }
140
141 static void
142 skl_update_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc,
143                  struct drm_framebuffer *fb,
144                  struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
145                  unsigned int crtc_w, unsigned int crtc_h,
146                  uint32_t x, uint32_t y,
147                  uint32_t src_w, uint32_t src_h)
148 {
149         struct drm_device *dev = drm_plane->dev;
150         struct drm_i915_private *dev_priv = dev->dev_private;
151         struct intel_plane *intel_plane = to_intel_plane(drm_plane);
152         const int pipe = intel_plane->pipe;
153         const int plane = intel_plane->plane + 1;
154         u32 plane_ctl, stride;
155         int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
156
157         plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
158
159         /* Mask out pixel format bits in case we change it */
160         plane_ctl &= ~PLANE_CTL_FORMAT_MASK;
161         plane_ctl &= ~PLANE_CTL_ORDER_RGBX;
162         plane_ctl &= ~PLANE_CTL_YUV422_ORDER_MASK;
163         plane_ctl &= ~PLANE_CTL_TILED_MASK;
164         plane_ctl &= ~PLANE_CTL_ALPHA_MASK;
165
166         /* Trickle feed has to be enabled */
167         plane_ctl &= ~PLANE_CTL_TRICKLE_FEED_DISABLE;
168
169         switch (fb->pixel_format) {
170         case DRM_FORMAT_RGB565:
171                 plane_ctl |= PLANE_CTL_FORMAT_RGB_565;
172                 break;
173         case DRM_FORMAT_XBGR8888:
174                 plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 | PLANE_CTL_ORDER_RGBX;
175                 break;
176         case DRM_FORMAT_XRGB8888:
177                 plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888;
178                 break;
179         /*
180          * XXX: For ARBG/ABGR formats we default to expecting scanout buffers
181          * to be already pre-multiplied. We need to add a knob (or a different
182          * DRM_FORMAT) for user-space to configure that.
183          */
184         case DRM_FORMAT_ABGR8888:
185                 plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
186                              PLANE_CTL_ORDER_RGBX |
187                              PLANE_CTL_ALPHA_SW_PREMULTIPLY;
188                 break;
189         case DRM_FORMAT_ARGB8888:
190                 plane_ctl |= PLANE_CTL_FORMAT_XRGB_8888 |
191                              PLANE_CTL_ALPHA_SW_PREMULTIPLY;
192                 break;
193         case DRM_FORMAT_YUYV:
194                 plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YUYV;
195                 break;
196         case DRM_FORMAT_YVYU:
197                 plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_YVYU;
198                 break;
199         case DRM_FORMAT_UYVY:
200                 plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_UYVY;
201                 break;
202         case DRM_FORMAT_VYUY:
203                 plane_ctl |= PLANE_CTL_FORMAT_YUV422 | PLANE_CTL_YUV422_VYUY;
204                 break;
205         default:
206                 BUG();
207         }
208
209         switch (obj->tiling_mode) {
210         case I915_TILING_NONE:
211                 stride = fb->pitches[0] >> 6;
212                 break;
213         case I915_TILING_X:
214                 plane_ctl |= PLANE_CTL_TILED_X;
215                 stride = fb->pitches[0] >> 9;
216                 break;
217         default:
218                 BUG();
219         }
220
221         plane_ctl |= PLANE_CTL_ENABLE;
222         plane_ctl |= PLANE_CTL_PIPE_CSC_ENABLE;
223
224         intel_update_sprite_watermarks(drm_plane, crtc, src_w, src_h,
225                                        pixel_size, true,
226                                        src_w != crtc_w || src_h != crtc_h);
227
228         /* Sizes are 0 based */
229         src_w--;
230         src_h--;
231         crtc_w--;
232         crtc_h--;
233
234         I915_WRITE(PLANE_OFFSET(pipe, plane), (y << 16) | x);
235         I915_WRITE(PLANE_STRIDE(pipe, plane), stride);
236         I915_WRITE(PLANE_POS(pipe, plane), (crtc_y << 16) | crtc_x);
237         I915_WRITE(PLANE_SIZE(pipe, plane), (crtc_h << 16) | crtc_w);
238         I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
239         I915_WRITE(PLANE_SURF(pipe, plane), i915_gem_obj_ggtt_offset(obj));
240         POSTING_READ(PLANE_SURF(pipe, plane));
241 }
242
243 static void
244 skl_disable_plane(struct drm_plane *drm_plane, struct drm_crtc *crtc)
245 {
246         struct drm_device *dev = drm_plane->dev;
247         struct drm_i915_private *dev_priv = dev->dev_private;
248         struct intel_plane *intel_plane = to_intel_plane(drm_plane);
249         const int pipe = intel_plane->pipe;
250         const int plane = intel_plane->plane + 1;
251
252         I915_WRITE(PLANE_CTL(pipe, plane),
253                    I915_READ(PLANE_CTL(pipe, plane)) & ~PLANE_CTL_ENABLE);
254
255         /* Activate double buffered register update */
256         I915_WRITE(PLANE_CTL(pipe, plane), 0);
257         POSTING_READ(PLANE_CTL(pipe, plane));
258
259         intel_update_sprite_watermarks(drm_plane, crtc, 0, 0, 0, false, false);
260 }
261
262 static int
263 skl_update_colorkey(struct drm_plane *drm_plane,
264                     struct drm_intel_sprite_colorkey *key)
265 {
266         struct drm_device *dev = drm_plane->dev;
267         struct drm_i915_private *dev_priv = dev->dev_private;
268         struct intel_plane *intel_plane = to_intel_plane(drm_plane);
269         const int pipe = intel_plane->pipe;
270         const int plane = intel_plane->plane;
271         u32 plane_ctl;
272
273         I915_WRITE(PLANE_KEYVAL(pipe, plane), key->min_value);
274         I915_WRITE(PLANE_KEYMAX(pipe, plane), key->max_value);
275         I915_WRITE(PLANE_KEYMSK(pipe, plane), key->channel_mask);
276
277         plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
278         plane_ctl &= ~PLANE_CTL_KEY_ENABLE_MASK;
279         if (key->flags & I915_SET_COLORKEY_DESTINATION)
280                 plane_ctl |= PLANE_CTL_KEY_ENABLE_DESTINATION;
281         else if (key->flags & I915_SET_COLORKEY_SOURCE)
282                 plane_ctl |= PLANE_CTL_KEY_ENABLE_SOURCE;
283         I915_WRITE(PLANE_CTL(pipe, plane), plane_ctl);
284
285         POSTING_READ(PLANE_CTL(pipe, plane));
286
287         return 0;
288 }
289
290 static void
291 skl_get_colorkey(struct drm_plane *drm_plane,
292                  struct drm_intel_sprite_colorkey *key)
293 {
294         struct drm_device *dev = drm_plane->dev;
295         struct drm_i915_private *dev_priv = dev->dev_private;
296         struct intel_plane *intel_plane = to_intel_plane(drm_plane);
297         const int pipe = intel_plane->pipe;
298         const int plane = intel_plane->plane;
299         u32 plane_ctl;
300
301         key->min_value = I915_READ(PLANE_KEYVAL(pipe, plane));
302         key->max_value = I915_READ(PLANE_KEYMAX(pipe, plane));
303         key->channel_mask = I915_READ(PLANE_KEYMSK(pipe, plane));
304
305         plane_ctl = I915_READ(PLANE_CTL(pipe, plane));
306
307         switch (plane_ctl & PLANE_CTL_KEY_ENABLE_MASK) {
308         case PLANE_CTL_KEY_ENABLE_DESTINATION:
309                 key->flags = I915_SET_COLORKEY_DESTINATION;
310                 break;
311         case PLANE_CTL_KEY_ENABLE_SOURCE:
312                 key->flags = I915_SET_COLORKEY_SOURCE;
313                 break;
314         default:
315                 key->flags = I915_SET_COLORKEY_NONE;
316         }
317 }
318
319 static void
320 vlv_update_plane(struct drm_plane *dplane, struct drm_crtc *crtc,
321                  struct drm_framebuffer *fb,
322                  struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
323                  unsigned int crtc_w, unsigned int crtc_h,
324                  uint32_t x, uint32_t y,
325                  uint32_t src_w, uint32_t src_h)
326 {
327         struct drm_device *dev = dplane->dev;
328         struct drm_i915_private *dev_priv = dev->dev_private;
329         struct intel_plane *intel_plane = to_intel_plane(dplane);
330         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
331         int pipe = intel_plane->pipe;
332         int plane = intel_plane->plane;
333         u32 sprctl;
334         unsigned long sprsurf_offset, linear_offset;
335         int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
336         u32 start_vbl_count;
337         bool atomic_update;
338
339         sprctl = I915_READ(SPCNTR(pipe, plane));
340
341         /* Mask out pixel format bits in case we change it */
342         sprctl &= ~SP_PIXFORMAT_MASK;
343         sprctl &= ~SP_YUV_BYTE_ORDER_MASK;
344         sprctl &= ~SP_TILED;
345         sprctl &= ~SP_ROTATE_180;
346
347         switch (fb->pixel_format) {
348         case DRM_FORMAT_YUYV:
349                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
350                 break;
351         case DRM_FORMAT_YVYU:
352                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
353                 break;
354         case DRM_FORMAT_UYVY:
355                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
356                 break;
357         case DRM_FORMAT_VYUY:
358                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
359                 break;
360         case DRM_FORMAT_RGB565:
361                 sprctl |= SP_FORMAT_BGR565;
362                 break;
363         case DRM_FORMAT_XRGB8888:
364                 sprctl |= SP_FORMAT_BGRX8888;
365                 break;
366         case DRM_FORMAT_ARGB8888:
367                 sprctl |= SP_FORMAT_BGRA8888;
368                 break;
369         case DRM_FORMAT_XBGR2101010:
370                 sprctl |= SP_FORMAT_RGBX1010102;
371                 break;
372         case DRM_FORMAT_ABGR2101010:
373                 sprctl |= SP_FORMAT_RGBA1010102;
374                 break;
375         case DRM_FORMAT_XBGR8888:
376                 sprctl |= SP_FORMAT_RGBX8888;
377                 break;
378         case DRM_FORMAT_ABGR8888:
379                 sprctl |= SP_FORMAT_RGBA8888;
380                 break;
381         default:
382                 /*
383                  * If we get here one of the upper layers failed to filter
384                  * out the unsupported plane formats
385                  */
386                 BUG();
387                 break;
388         }
389
390         /*
391          * Enable gamma to match primary/cursor plane behaviour.
392          * FIXME should be user controllable via propertiesa.
393          */
394         sprctl |= SP_GAMMA_ENABLE;
395
396         if (obj->tiling_mode != I915_TILING_NONE)
397                 sprctl |= SP_TILED;
398
399         sprctl |= SP_ENABLE;
400
401         intel_update_sprite_watermarks(dplane, crtc, src_w, src_h,
402                                        pixel_size, true,
403                                        src_w != crtc_w || src_h != crtc_h);
404
405         /* Sizes are 0 based */
406         src_w--;
407         src_h--;
408         crtc_w--;
409         crtc_h--;
410
411         linear_offset = y * fb->pitches[0] + x * pixel_size;
412         sprsurf_offset = intel_gen4_compute_page_offset(&x, &y,
413                                                         obj->tiling_mode,
414                                                         pixel_size,
415                                                         fb->pitches[0]);
416         linear_offset -= sprsurf_offset;
417
418         if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
419                 sprctl |= SP_ROTATE_180;
420
421                 x += src_w;
422                 y += src_h;
423                 linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
424         }
425
426         atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
427
428         intel_update_primary_plane(intel_crtc);
429
430         I915_WRITE(SPSTRIDE(pipe, plane), fb->pitches[0]);
431         I915_WRITE(SPPOS(pipe, plane), (crtc_y << 16) | crtc_x);
432
433         if (obj->tiling_mode != I915_TILING_NONE)
434                 I915_WRITE(SPTILEOFF(pipe, plane), (y << 16) | x);
435         else
436                 I915_WRITE(SPLINOFF(pipe, plane), linear_offset);
437
438         I915_WRITE(SPSIZE(pipe, plane), (crtc_h << 16) | crtc_w);
439         I915_WRITE(SPCNTR(pipe, plane), sprctl);
440         I915_WRITE(SPSURF(pipe, plane), i915_gem_obj_ggtt_offset(obj) +
441                    sprsurf_offset);
442
443         intel_flush_primary_plane(dev_priv, intel_crtc->plane);
444
445         if (atomic_update)
446                 intel_pipe_update_end(intel_crtc, start_vbl_count);
447 }
448
449 static void
450 vlv_disable_plane(struct drm_plane *dplane, struct drm_crtc *crtc)
451 {
452         struct drm_device *dev = dplane->dev;
453         struct drm_i915_private *dev_priv = dev->dev_private;
454         struct intel_plane *intel_plane = to_intel_plane(dplane);
455         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
456         int pipe = intel_plane->pipe;
457         int plane = intel_plane->plane;
458         u32 start_vbl_count;
459         bool atomic_update;
460
461         atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
462
463         intel_update_primary_plane(intel_crtc);
464
465         I915_WRITE(SPCNTR(pipe, plane), I915_READ(SPCNTR(pipe, plane)) &
466                    ~SP_ENABLE);
467         /* Activate double buffered register update */
468         I915_WRITE(SPSURF(pipe, plane), 0);
469
470         intel_flush_primary_plane(dev_priv, intel_crtc->plane);
471
472         if (atomic_update)
473                 intel_pipe_update_end(intel_crtc, start_vbl_count);
474
475         intel_update_sprite_watermarks(dplane, crtc, 0, 0, 0, false, false);
476 }
477
478 static int
479 vlv_update_colorkey(struct drm_plane *dplane,
480                     struct drm_intel_sprite_colorkey *key)
481 {
482         struct drm_device *dev = dplane->dev;
483         struct drm_i915_private *dev_priv = dev->dev_private;
484         struct intel_plane *intel_plane = to_intel_plane(dplane);
485         int pipe = intel_plane->pipe;
486         int plane = intel_plane->plane;
487         u32 sprctl;
488
489         if (key->flags & I915_SET_COLORKEY_DESTINATION)
490                 return -EINVAL;
491
492         I915_WRITE(SPKEYMINVAL(pipe, plane), key->min_value);
493         I915_WRITE(SPKEYMAXVAL(pipe, plane), key->max_value);
494         I915_WRITE(SPKEYMSK(pipe, plane), key->channel_mask);
495
496         sprctl = I915_READ(SPCNTR(pipe, plane));
497         sprctl &= ~SP_SOURCE_KEY;
498         if (key->flags & I915_SET_COLORKEY_SOURCE)
499                 sprctl |= SP_SOURCE_KEY;
500         I915_WRITE(SPCNTR(pipe, plane), sprctl);
501
502         POSTING_READ(SPKEYMSK(pipe, plane));
503
504         return 0;
505 }
506
507 static void
508 vlv_get_colorkey(struct drm_plane *dplane,
509                  struct drm_intel_sprite_colorkey *key)
510 {
511         struct drm_device *dev = dplane->dev;
512         struct drm_i915_private *dev_priv = dev->dev_private;
513         struct intel_plane *intel_plane = to_intel_plane(dplane);
514         int pipe = intel_plane->pipe;
515         int plane = intel_plane->plane;
516         u32 sprctl;
517
518         key->min_value = I915_READ(SPKEYMINVAL(pipe, plane));
519         key->max_value = I915_READ(SPKEYMAXVAL(pipe, plane));
520         key->channel_mask = I915_READ(SPKEYMSK(pipe, plane));
521
522         sprctl = I915_READ(SPCNTR(pipe, plane));
523         if (sprctl & SP_SOURCE_KEY)
524                 key->flags = I915_SET_COLORKEY_SOURCE;
525         else
526                 key->flags = I915_SET_COLORKEY_NONE;
527 }
528
529 static void
530 ivb_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
531                  struct drm_framebuffer *fb,
532                  struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
533                  unsigned int crtc_w, unsigned int crtc_h,
534                  uint32_t x, uint32_t y,
535                  uint32_t src_w, uint32_t src_h)
536 {
537         struct drm_device *dev = plane->dev;
538         struct drm_i915_private *dev_priv = dev->dev_private;
539         struct intel_plane *intel_plane = to_intel_plane(plane);
540         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
541         int pipe = intel_plane->pipe;
542         u32 sprctl, sprscale = 0;
543         unsigned long sprsurf_offset, linear_offset;
544         int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
545         u32 start_vbl_count;
546         bool atomic_update;
547
548         sprctl = I915_READ(SPRCTL(pipe));
549
550         /* Mask out pixel format bits in case we change it */
551         sprctl &= ~SPRITE_PIXFORMAT_MASK;
552         sprctl &= ~SPRITE_RGB_ORDER_RGBX;
553         sprctl &= ~SPRITE_YUV_BYTE_ORDER_MASK;
554         sprctl &= ~SPRITE_TILED;
555         sprctl &= ~SPRITE_ROTATE_180;
556
557         switch (fb->pixel_format) {
558         case DRM_FORMAT_XBGR8888:
559                 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
560                 break;
561         case DRM_FORMAT_XRGB8888:
562                 sprctl |= SPRITE_FORMAT_RGBX888;
563                 break;
564         case DRM_FORMAT_YUYV:
565                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
566                 break;
567         case DRM_FORMAT_YVYU:
568                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
569                 break;
570         case DRM_FORMAT_UYVY:
571                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
572                 break;
573         case DRM_FORMAT_VYUY:
574                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
575                 break;
576         default:
577                 BUG();
578         }
579
580         /*
581          * Enable gamma to match primary/cursor plane behaviour.
582          * FIXME should be user controllable via propertiesa.
583          */
584         sprctl |= SPRITE_GAMMA_ENABLE;
585
586         if (obj->tiling_mode != I915_TILING_NONE)
587                 sprctl |= SPRITE_TILED;
588
589         if (IS_HASWELL(dev) || IS_BROADWELL(dev))
590                 sprctl &= ~SPRITE_TRICKLE_FEED_DISABLE;
591         else
592                 sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
593
594         sprctl |= SPRITE_ENABLE;
595
596         if (IS_HASWELL(dev) || IS_BROADWELL(dev))
597                 sprctl |= SPRITE_PIPE_CSC_ENABLE;
598
599         intel_update_sprite_watermarks(plane, crtc, src_w, src_h, pixel_size,
600                                        true,
601                                        src_w != crtc_w || src_h != crtc_h);
602
603         /* Sizes are 0 based */
604         src_w--;
605         src_h--;
606         crtc_w--;
607         crtc_h--;
608
609         if (crtc_w != src_w || crtc_h != src_h)
610                 sprscale = SPRITE_SCALE_ENABLE | (src_w << 16) | src_h;
611
612         linear_offset = y * fb->pitches[0] + x * pixel_size;
613         sprsurf_offset =
614                 intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
615                                                pixel_size, fb->pitches[0]);
616         linear_offset -= sprsurf_offset;
617
618         if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
619                 sprctl |= SPRITE_ROTATE_180;
620
621                 /* HSW and BDW does this automagically in hardware */
622                 if (!IS_HASWELL(dev) && !IS_BROADWELL(dev)) {
623                         x += src_w;
624                         y += src_h;
625                         linear_offset += src_h * fb->pitches[0] +
626                                 src_w * pixel_size;
627                 }
628         }
629
630         atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
631
632         intel_update_primary_plane(intel_crtc);
633
634         I915_WRITE(SPRSTRIDE(pipe), fb->pitches[0]);
635         I915_WRITE(SPRPOS(pipe), (crtc_y << 16) | crtc_x);
636
637         /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
638          * register */
639         if (IS_HASWELL(dev) || IS_BROADWELL(dev))
640                 I915_WRITE(SPROFFSET(pipe), (y << 16) | x);
641         else if (obj->tiling_mode != I915_TILING_NONE)
642                 I915_WRITE(SPRTILEOFF(pipe), (y << 16) | x);
643         else
644                 I915_WRITE(SPRLINOFF(pipe), linear_offset);
645
646         I915_WRITE(SPRSIZE(pipe), (crtc_h << 16) | crtc_w);
647         if (intel_plane->can_scale)
648                 I915_WRITE(SPRSCALE(pipe), sprscale);
649         I915_WRITE(SPRCTL(pipe), sprctl);
650         I915_WRITE(SPRSURF(pipe),
651                    i915_gem_obj_ggtt_offset(obj) + sprsurf_offset);
652
653         intel_flush_primary_plane(dev_priv, intel_crtc->plane);
654
655         if (atomic_update)
656                 intel_pipe_update_end(intel_crtc, start_vbl_count);
657 }
658
659 static void
660 ivb_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
661 {
662         struct drm_device *dev = plane->dev;
663         struct drm_i915_private *dev_priv = dev->dev_private;
664         struct intel_plane *intel_plane = to_intel_plane(plane);
665         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
666         int pipe = intel_plane->pipe;
667         u32 start_vbl_count;
668         bool atomic_update;
669
670         atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
671
672         intel_update_primary_plane(intel_crtc);
673
674         I915_WRITE(SPRCTL(pipe), I915_READ(SPRCTL(pipe)) & ~SPRITE_ENABLE);
675         /* Can't leave the scaler enabled... */
676         if (intel_plane->can_scale)
677                 I915_WRITE(SPRSCALE(pipe), 0);
678         /* Activate double buffered register update */
679         I915_WRITE(SPRSURF(pipe), 0);
680
681         intel_flush_primary_plane(dev_priv, intel_crtc->plane);
682
683         if (atomic_update)
684                 intel_pipe_update_end(intel_crtc, start_vbl_count);
685
686         /*
687          * Avoid underruns when disabling the sprite.
688          * FIXME remove once watermark updates are done properly.
689          */
690         intel_wait_for_vblank(dev, pipe);
691
692         intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false);
693 }
694
695 static int
696 ivb_update_colorkey(struct drm_plane *plane,
697                     struct drm_intel_sprite_colorkey *key)
698 {
699         struct drm_device *dev = plane->dev;
700         struct drm_i915_private *dev_priv = dev->dev_private;
701         struct intel_plane *intel_plane;
702         u32 sprctl;
703         int ret = 0;
704
705         intel_plane = to_intel_plane(plane);
706
707         I915_WRITE(SPRKEYVAL(intel_plane->pipe), key->min_value);
708         I915_WRITE(SPRKEYMAX(intel_plane->pipe), key->max_value);
709         I915_WRITE(SPRKEYMSK(intel_plane->pipe), key->channel_mask);
710
711         sprctl = I915_READ(SPRCTL(intel_plane->pipe));
712         sprctl &= ~(SPRITE_SOURCE_KEY | SPRITE_DEST_KEY);
713         if (key->flags & I915_SET_COLORKEY_DESTINATION)
714                 sprctl |= SPRITE_DEST_KEY;
715         else if (key->flags & I915_SET_COLORKEY_SOURCE)
716                 sprctl |= SPRITE_SOURCE_KEY;
717         I915_WRITE(SPRCTL(intel_plane->pipe), sprctl);
718
719         POSTING_READ(SPRKEYMSK(intel_plane->pipe));
720
721         return ret;
722 }
723
724 static void
725 ivb_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key)
726 {
727         struct drm_device *dev = plane->dev;
728         struct drm_i915_private *dev_priv = dev->dev_private;
729         struct intel_plane *intel_plane;
730         u32 sprctl;
731
732         intel_plane = to_intel_plane(plane);
733
734         key->min_value = I915_READ(SPRKEYVAL(intel_plane->pipe));
735         key->max_value = I915_READ(SPRKEYMAX(intel_plane->pipe));
736         key->channel_mask = I915_READ(SPRKEYMSK(intel_plane->pipe));
737         key->flags = 0;
738
739         sprctl = I915_READ(SPRCTL(intel_plane->pipe));
740
741         if (sprctl & SPRITE_DEST_KEY)
742                 key->flags = I915_SET_COLORKEY_DESTINATION;
743         else if (sprctl & SPRITE_SOURCE_KEY)
744                 key->flags = I915_SET_COLORKEY_SOURCE;
745         else
746                 key->flags = I915_SET_COLORKEY_NONE;
747 }
748
749 static void
750 ilk_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
751                  struct drm_framebuffer *fb,
752                  struct drm_i915_gem_object *obj, int crtc_x, int crtc_y,
753                  unsigned int crtc_w, unsigned int crtc_h,
754                  uint32_t x, uint32_t y,
755                  uint32_t src_w, uint32_t src_h)
756 {
757         struct drm_device *dev = plane->dev;
758         struct drm_i915_private *dev_priv = dev->dev_private;
759         struct intel_plane *intel_plane = to_intel_plane(plane);
760         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
761         int pipe = intel_plane->pipe;
762         unsigned long dvssurf_offset, linear_offset;
763         u32 dvscntr, dvsscale;
764         int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
765         u32 start_vbl_count;
766         bool atomic_update;
767
768         dvscntr = I915_READ(DVSCNTR(pipe));
769
770         /* Mask out pixel format bits in case we change it */
771         dvscntr &= ~DVS_PIXFORMAT_MASK;
772         dvscntr &= ~DVS_RGB_ORDER_XBGR;
773         dvscntr &= ~DVS_YUV_BYTE_ORDER_MASK;
774         dvscntr &= ~DVS_TILED;
775         dvscntr &= ~DVS_ROTATE_180;
776
777         switch (fb->pixel_format) {
778         case DRM_FORMAT_XBGR8888:
779                 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
780                 break;
781         case DRM_FORMAT_XRGB8888:
782                 dvscntr |= DVS_FORMAT_RGBX888;
783                 break;
784         case DRM_FORMAT_YUYV:
785                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
786                 break;
787         case DRM_FORMAT_YVYU:
788                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
789                 break;
790         case DRM_FORMAT_UYVY:
791                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
792                 break;
793         case DRM_FORMAT_VYUY:
794                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
795                 break;
796         default:
797                 BUG();
798         }
799
800         /*
801          * Enable gamma to match primary/cursor plane behaviour.
802          * FIXME should be user controllable via propertiesa.
803          */
804         dvscntr |= DVS_GAMMA_ENABLE;
805
806         if (obj->tiling_mode != I915_TILING_NONE)
807                 dvscntr |= DVS_TILED;
808
809         if (IS_GEN6(dev))
810                 dvscntr |= DVS_TRICKLE_FEED_DISABLE; /* must disable */
811         dvscntr |= DVS_ENABLE;
812
813         intel_update_sprite_watermarks(plane, crtc, src_w, src_h,
814                                        pixel_size, true,
815                                        src_w != crtc_w || src_h != crtc_h);
816
817         /* Sizes are 0 based */
818         src_w--;
819         src_h--;
820         crtc_w--;
821         crtc_h--;
822
823         dvsscale = 0;
824         if (crtc_w != src_w || crtc_h != src_h)
825                 dvsscale = DVS_SCALE_ENABLE | (src_w << 16) | src_h;
826
827         linear_offset = y * fb->pitches[0] + x * pixel_size;
828         dvssurf_offset =
829                 intel_gen4_compute_page_offset(&x, &y, obj->tiling_mode,
830                                                pixel_size, fb->pitches[0]);
831         linear_offset -= dvssurf_offset;
832
833         if (intel_plane->rotation == BIT(DRM_ROTATE_180)) {
834                 dvscntr |= DVS_ROTATE_180;
835
836                 x += src_w;
837                 y += src_h;
838                 linear_offset += src_h * fb->pitches[0] + src_w * pixel_size;
839         }
840
841         atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
842
843         intel_update_primary_plane(intel_crtc);
844
845         I915_WRITE(DVSSTRIDE(pipe), fb->pitches[0]);
846         I915_WRITE(DVSPOS(pipe), (crtc_y << 16) | crtc_x);
847
848         if (obj->tiling_mode != I915_TILING_NONE)
849                 I915_WRITE(DVSTILEOFF(pipe), (y << 16) | x);
850         else
851                 I915_WRITE(DVSLINOFF(pipe), linear_offset);
852
853         I915_WRITE(DVSSIZE(pipe), (crtc_h << 16) | crtc_w);
854         I915_WRITE(DVSSCALE(pipe), dvsscale);
855         I915_WRITE(DVSCNTR(pipe), dvscntr);
856         I915_WRITE(DVSSURF(pipe),
857                    i915_gem_obj_ggtt_offset(obj) + dvssurf_offset);
858
859         intel_flush_primary_plane(dev_priv, intel_crtc->plane);
860
861         if (atomic_update)
862                 intel_pipe_update_end(intel_crtc, start_vbl_count);
863 }
864
865 static void
866 ilk_disable_plane(struct drm_plane *plane, struct drm_crtc *crtc)
867 {
868         struct drm_device *dev = plane->dev;
869         struct drm_i915_private *dev_priv = dev->dev_private;
870         struct intel_plane *intel_plane = to_intel_plane(plane);
871         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
872         int pipe = intel_plane->pipe;
873         u32 start_vbl_count;
874         bool atomic_update;
875
876         atomic_update = intel_pipe_update_start(intel_crtc, &start_vbl_count);
877
878         intel_update_primary_plane(intel_crtc);
879
880         I915_WRITE(DVSCNTR(pipe), I915_READ(DVSCNTR(pipe)) & ~DVS_ENABLE);
881         /* Disable the scaler */
882         I915_WRITE(DVSSCALE(pipe), 0);
883         /* Flush double buffered register updates */
884         I915_WRITE(DVSSURF(pipe), 0);
885
886         intel_flush_primary_plane(dev_priv, intel_crtc->plane);
887
888         if (atomic_update)
889                 intel_pipe_update_end(intel_crtc, start_vbl_count);
890
891         /*
892          * Avoid underruns when disabling the sprite.
893          * FIXME remove once watermark updates are done properly.
894          */
895         intel_wait_for_vblank(dev, pipe);
896
897         intel_update_sprite_watermarks(plane, crtc, 0, 0, 0, false, false);
898 }
899
900 static void
901 intel_post_enable_primary(struct drm_crtc *crtc)
902 {
903         struct drm_device *dev = crtc->dev;
904         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
905
906         /*
907          * BDW signals flip done immediately if the plane
908          * is disabled, even if the plane enable is already
909          * armed to occur at the next vblank :(
910          */
911         if (IS_BROADWELL(dev))
912                 intel_wait_for_vblank(dev, intel_crtc->pipe);
913
914         /*
915          * FIXME IPS should be fine as long as one plane is
916          * enabled, but in practice it seems to have problems
917          * when going from primary only to sprite only and vice
918          * versa.
919          */
920         hsw_enable_ips(intel_crtc);
921
922         mutex_lock(&dev->struct_mutex);
923         intel_update_fbc(dev);
924         mutex_unlock(&dev->struct_mutex);
925 }
926
927 static void
928 intel_pre_disable_primary(struct drm_crtc *crtc)
929 {
930         struct drm_device *dev = crtc->dev;
931         struct drm_i915_private *dev_priv = dev->dev_private;
932         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
933
934         mutex_lock(&dev->struct_mutex);
935         if (dev_priv->fbc.plane == intel_crtc->plane)
936                 intel_disable_fbc(dev);
937         mutex_unlock(&dev->struct_mutex);
938
939         /*
940          * FIXME IPS should be fine as long as one plane is
941          * enabled, but in practice it seems to have problems
942          * when going from primary only to sprite only and vice
943          * versa.
944          */
945         hsw_disable_ips(intel_crtc);
946 }
947
948 static int
949 ilk_update_colorkey(struct drm_plane *plane,
950                     struct drm_intel_sprite_colorkey *key)
951 {
952         struct drm_device *dev = plane->dev;
953         struct drm_i915_private *dev_priv = dev->dev_private;
954         struct intel_plane *intel_plane;
955         u32 dvscntr;
956         int ret = 0;
957
958         intel_plane = to_intel_plane(plane);
959
960         I915_WRITE(DVSKEYVAL(intel_plane->pipe), key->min_value);
961         I915_WRITE(DVSKEYMAX(intel_plane->pipe), key->max_value);
962         I915_WRITE(DVSKEYMSK(intel_plane->pipe), key->channel_mask);
963
964         dvscntr = I915_READ(DVSCNTR(intel_plane->pipe));
965         dvscntr &= ~(DVS_SOURCE_KEY | DVS_DEST_KEY);
966         if (key->flags & I915_SET_COLORKEY_DESTINATION)
967                 dvscntr |= DVS_DEST_KEY;
968         else if (key->flags & I915_SET_COLORKEY_SOURCE)
969                 dvscntr |= DVS_SOURCE_KEY;
970         I915_WRITE(DVSCNTR(intel_plane->pipe), dvscntr);
971
972         POSTING_READ(DVSKEYMSK(intel_plane->pipe));
973
974         return ret;
975 }
976
977 static void
978 ilk_get_colorkey(struct drm_plane *plane, struct drm_intel_sprite_colorkey *key)
979 {
980         struct drm_device *dev = plane->dev;
981         struct drm_i915_private *dev_priv = dev->dev_private;
982         struct intel_plane *intel_plane;
983         u32 dvscntr;
984
985         intel_plane = to_intel_plane(plane);
986
987         key->min_value = I915_READ(DVSKEYVAL(intel_plane->pipe));
988         key->max_value = I915_READ(DVSKEYMAX(intel_plane->pipe));
989         key->channel_mask = I915_READ(DVSKEYMSK(intel_plane->pipe));
990         key->flags = 0;
991
992         dvscntr = I915_READ(DVSCNTR(intel_plane->pipe));
993
994         if (dvscntr & DVS_DEST_KEY)
995                 key->flags = I915_SET_COLORKEY_DESTINATION;
996         else if (dvscntr & DVS_SOURCE_KEY)
997                 key->flags = I915_SET_COLORKEY_SOURCE;
998         else
999                 key->flags = I915_SET_COLORKEY_NONE;
1000 }
1001
1002 static bool
1003 format_is_yuv(uint32_t format)
1004 {
1005         switch (format) {
1006         case DRM_FORMAT_YUYV:
1007         case DRM_FORMAT_UYVY:
1008         case DRM_FORMAT_VYUY:
1009         case DRM_FORMAT_YVYU:
1010                 return true;
1011         default:
1012                 return false;
1013         }
1014 }
1015
1016 static bool colorkey_enabled(struct intel_plane *intel_plane)
1017 {
1018         struct drm_intel_sprite_colorkey key;
1019
1020         intel_plane->get_colorkey(&intel_plane->base, &key);
1021
1022         return key.flags != I915_SET_COLORKEY_NONE;
1023 }
1024
1025 static int
1026 intel_check_sprite_plane(struct drm_plane *plane,
1027                          struct intel_plane_state *state)
1028 {
1029         struct intel_crtc *intel_crtc = to_intel_crtc(state->crtc);
1030         struct intel_plane *intel_plane = to_intel_plane(plane);
1031         struct drm_framebuffer *fb = state->fb;
1032         struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
1033         struct drm_i915_gem_object *obj = intel_fb->obj;
1034         int crtc_x, crtc_y;
1035         unsigned int crtc_w, crtc_h;
1036         uint32_t src_x, src_y, src_w, src_h;
1037         struct drm_rect *src = &state->src;
1038         struct drm_rect *dst = &state->dst;
1039         struct drm_rect *orig_src = &state->orig_src;
1040         const struct drm_rect *clip = &state->clip;
1041         int hscale, vscale;
1042         int max_scale, min_scale;
1043         int pixel_size = drm_format_plane_cpp(fb->pixel_format, 0);
1044
1045         /* Don't modify another pipe's plane */
1046         if (intel_plane->pipe != intel_crtc->pipe) {
1047                 DRM_DEBUG_KMS("Wrong plane <-> crtc mapping\n");
1048                 return -EINVAL;
1049         }
1050
1051         /* FIXME check all gen limits */
1052         if (fb->width < 3 || fb->height < 3 || fb->pitches[0] > 16384) {
1053                 DRM_DEBUG_KMS("Unsuitable framebuffer for plane\n");
1054                 return -EINVAL;
1055         }
1056
1057         /* Sprite planes can be linear or x-tiled surfaces */
1058         switch (obj->tiling_mode) {
1059                 case I915_TILING_NONE:
1060                 case I915_TILING_X:
1061                         break;
1062                 default:
1063                         DRM_DEBUG_KMS("Unsupported tiling mode\n");
1064                         return -EINVAL;
1065         }
1066
1067         /*
1068          * FIXME the following code does a bunch of fuzzy adjustments to the
1069          * coordinates and sizes. We probably need some way to decide whether
1070          * more strict checking should be done instead.
1071          */
1072         max_scale = intel_plane->max_downscale << 16;
1073         min_scale = intel_plane->can_scale ? 1 : (1 << 16);
1074
1075         drm_rect_rotate(src, fb->width << 16, fb->height << 16,
1076                         intel_plane->rotation);
1077
1078         hscale = drm_rect_calc_hscale_relaxed(src, dst, min_scale, max_scale);
1079         BUG_ON(hscale < 0);
1080
1081         vscale = drm_rect_calc_vscale_relaxed(src, dst, min_scale, max_scale);
1082         BUG_ON(vscale < 0);
1083
1084         state->visible =  drm_rect_clip_scaled(src, dst, clip, hscale, vscale);
1085
1086         crtc_x = dst->x1;
1087         crtc_y = dst->y1;
1088         crtc_w = drm_rect_width(dst);
1089         crtc_h = drm_rect_height(dst);
1090
1091         if (state->visible) {
1092                 /* check again in case clipping clamped the results */
1093                 hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
1094                 if (hscale < 0) {
1095                         DRM_DEBUG_KMS("Horizontal scaling factor out of limits\n");
1096                         drm_rect_debug_print(src, true);
1097                         drm_rect_debug_print(dst, false);
1098
1099                         return hscale;
1100                 }
1101
1102                 vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
1103                 if (vscale < 0) {
1104                         DRM_DEBUG_KMS("Vertical scaling factor out of limits\n");
1105                         drm_rect_debug_print(src, true);
1106                         drm_rect_debug_print(dst, false);
1107
1108                         return vscale;
1109                 }
1110
1111                 /* Make the source viewport size an exact multiple of the scaling factors. */
1112                 drm_rect_adjust_size(src,
1113                                      drm_rect_width(dst) * hscale - drm_rect_width(src),
1114                                      drm_rect_height(dst) * vscale - drm_rect_height(src));
1115
1116                 drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16,
1117                                     intel_plane->rotation);
1118
1119                 /* sanity check to make sure the src viewport wasn't enlarged */
1120                 WARN_ON(src->x1 < (int) orig_src->x1 ||
1121                         src->y1 < (int) orig_src->y1 ||
1122                         src->x2 > (int) orig_src->x2 ||
1123                         src->y2 > (int) orig_src->y2);
1124
1125                 /*
1126                  * Hardware doesn't handle subpixel coordinates.
1127                  * Adjust to (macro)pixel boundary, but be careful not to
1128                  * increase the source viewport size, because that could
1129                  * push the downscaling factor out of bounds.
1130                  */
1131                 src_x = src->x1 >> 16;
1132                 src_w = drm_rect_width(src) >> 16;
1133                 src_y = src->y1 >> 16;
1134                 src_h = drm_rect_height(src) >> 16;
1135
1136                 if (format_is_yuv(fb->pixel_format)) {
1137                         src_x &= ~1;
1138                         src_w &= ~1;
1139
1140                         /*
1141                          * Must keep src and dst the
1142                          * same if we can't scale.
1143                          */
1144                         if (!intel_plane->can_scale)
1145                                 crtc_w &= ~1;
1146
1147                         if (crtc_w == 0)
1148                                 state->visible = false;
1149                 }
1150         }
1151
1152         /* Check size restrictions when scaling */
1153         if (state->visible && (src_w != crtc_w || src_h != crtc_h)) {
1154                 unsigned int width_bytes;
1155
1156                 WARN_ON(!intel_plane->can_scale);
1157
1158                 /* FIXME interlacing min height is 6 */
1159
1160                 if (crtc_w < 3 || crtc_h < 3)
1161                         state->visible = false;
1162
1163                 if (src_w < 3 || src_h < 3)
1164                         state->visible = false;
1165
1166                 width_bytes = ((src_x * pixel_size) & 63) +
1167                                         src_w * pixel_size;
1168
1169                 if (src_w > 2048 || src_h > 2048 ||
1170                     width_bytes > 4096 || fb->pitches[0] > 4096) {
1171                         DRM_DEBUG_KMS("Source dimensions exceed hardware limits\n");
1172                         return -EINVAL;
1173                 }
1174         }
1175
1176         if (state->visible) {
1177                 src->x1 = src_x;
1178                 src->x2 = src_x + src_w;
1179                 src->y1 = src_y;
1180                 src->y2 = src_y + src_h;
1181         }
1182
1183         dst->x1 = crtc_x;
1184         dst->x2 = crtc_x + crtc_w;
1185         dst->y1 = crtc_y;
1186         dst->y2 = crtc_y + crtc_h;
1187
1188         return 0;
1189 }
1190
1191 static int
1192 intel_commit_sprite_plane(struct drm_plane *plane,
1193                           struct intel_plane_state *state)
1194 {
1195         struct drm_device *dev = plane->dev;
1196         struct drm_crtc *crtc = state->crtc;
1197         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1198         struct intel_plane *intel_plane = to_intel_plane(plane);
1199         enum pipe pipe = intel_crtc->pipe;
1200         struct drm_framebuffer *fb = state->fb;
1201         struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
1202         struct drm_i915_gem_object *obj = intel_fb->obj;
1203         struct drm_i915_gem_object *old_obj = intel_plane->obj;
1204         int crtc_x, crtc_y;
1205         unsigned int crtc_w, crtc_h;
1206         uint32_t src_x, src_y, src_w, src_h;
1207         struct drm_rect *dst = &state->dst;
1208         const struct drm_rect *clip = &state->clip;
1209         bool primary_enabled;
1210         int ret;
1211
1212         /*
1213          * If the sprite is completely covering the primary plane,
1214          * we can disable the primary and save power.
1215          */
1216         primary_enabled = !drm_rect_equals(dst, clip) || colorkey_enabled(intel_plane);
1217         WARN_ON(!primary_enabled && !state->visible && intel_crtc->active);
1218
1219
1220         if (old_obj != obj) {
1221                 mutex_lock(&dev->struct_mutex);
1222
1223                 /* Note that this will apply the VT-d workaround for scanouts,
1224                  * which is more restrictive than required for sprites. (The
1225                  * primary plane requires 256KiB alignment with 64 PTE padding,
1226                  * the sprite planes only require 128KiB alignment and 32 PTE
1227                  * padding.
1228                  */
1229                 ret = intel_pin_and_fence_fb_obj(dev, obj, NULL);
1230                 if (ret == 0)
1231                         i915_gem_track_fb(old_obj, obj,
1232                                           INTEL_FRONTBUFFER_SPRITE(pipe));
1233                 mutex_unlock(&dev->struct_mutex);
1234                 if (ret)
1235                         return ret;
1236         }
1237
1238         intel_plane->crtc_x = state->orig_dst.x1;
1239         intel_plane->crtc_y = state->orig_dst.y1;
1240         intel_plane->crtc_w = drm_rect_width(&state->orig_dst);
1241         intel_plane->crtc_h = drm_rect_height(&state->orig_dst);
1242         intel_plane->src_x = state->orig_src.x1;
1243         intel_plane->src_y = state->orig_src.y1;
1244         intel_plane->src_w = drm_rect_width(&state->orig_src);
1245         intel_plane->src_h = drm_rect_height(&state->orig_src);
1246         intel_plane->obj = obj;
1247
1248         if (intel_crtc->active) {
1249                 bool primary_was_enabled = intel_crtc->primary_enabled;
1250
1251                 intel_crtc->primary_enabled = primary_enabled;
1252
1253                 if (primary_was_enabled != primary_enabled)
1254                         intel_crtc_wait_for_pending_flips(crtc);
1255
1256                 if (primary_was_enabled && !primary_enabled)
1257                         intel_pre_disable_primary(crtc);
1258
1259                 if (state->visible) {
1260                         crtc_x = state->dst.x1;
1261                         crtc_y = state->dst.y1;
1262                         crtc_w = drm_rect_width(&state->dst);
1263                         crtc_h = drm_rect_height(&state->dst);
1264                         src_x = state->src.x1;
1265                         src_y = state->src.y1;
1266                         src_w = drm_rect_width(&state->src);
1267                         src_h = drm_rect_height(&state->src);
1268                         intel_plane->update_plane(plane, crtc, fb, obj,
1269                                                   crtc_x, crtc_y, crtc_w, crtc_h,
1270                                                   src_x, src_y, src_w, src_h);
1271                 } else {
1272                         intel_plane->disable_plane(plane, crtc);
1273                 }
1274
1275
1276                 intel_frontbuffer_flip(dev, INTEL_FRONTBUFFER_SPRITE(pipe));
1277
1278                 if (!primary_was_enabled && primary_enabled)
1279                         intel_post_enable_primary(crtc);
1280         }
1281
1282         /* Unpin old obj after new one is active to avoid ugliness */
1283         if (old_obj && old_obj != obj) {
1284
1285                 /*
1286                  * It's fairly common to simply update the position of
1287                  * an existing object.  In that case, we don't need to
1288                  * wait for vblank to avoid ugliness, we only need to
1289                  * do the pin & ref bookkeeping.
1290                  */
1291                 if (intel_crtc->active)
1292                         intel_wait_for_vblank(dev, intel_crtc->pipe);
1293
1294                 mutex_lock(&dev->struct_mutex);
1295                 intel_unpin_fb_obj(old_obj);
1296                 mutex_unlock(&dev->struct_mutex);
1297         }
1298
1299         return 0;
1300 }
1301
1302 static int
1303 intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
1304                    struct drm_framebuffer *fb, int crtc_x, int crtc_y,
1305                    unsigned int crtc_w, unsigned int crtc_h,
1306                    uint32_t src_x, uint32_t src_y,
1307                    uint32_t src_w, uint32_t src_h)
1308 {
1309         struct intel_plane_state state;
1310         struct intel_crtc *intel_crtc = to_intel_crtc(crtc);
1311         int ret;
1312
1313         state.crtc = crtc;
1314         state.fb = fb;
1315
1316         /* sample coordinates in 16.16 fixed point */
1317         state.src.x1 = src_x;
1318         state.src.x2 = src_x + src_w;
1319         state.src.y1 = src_y;
1320         state.src.y2 = src_y + src_h;
1321
1322         /* integer pixels */
1323         state.dst.x1 = crtc_x;
1324         state.dst.x2 = crtc_x + crtc_w;
1325         state.dst.y1 = crtc_y;
1326         state.dst.y2 = crtc_y + crtc_h;
1327
1328         state.clip.x1 = 0;
1329         state.clip.y1 = 0;
1330         state.clip.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0;
1331         state.clip.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0;
1332         state.orig_src = state.src;
1333         state.orig_dst = state.dst;
1334
1335         ret = intel_check_sprite_plane(plane, &state);
1336         if (ret)
1337                 return ret;
1338
1339         return intel_commit_sprite_plane(plane, &state);
1340 }
1341
1342 static int
1343 intel_disable_plane(struct drm_plane *plane)
1344 {
1345         struct drm_device *dev = plane->dev;
1346         struct intel_plane *intel_plane = to_intel_plane(plane);
1347         struct intel_crtc *intel_crtc;
1348         enum pipe pipe;
1349
1350         if (!plane->fb)
1351                 return 0;
1352
1353         if (WARN_ON(!plane->crtc))
1354                 return -EINVAL;
1355
1356         intel_crtc = to_intel_crtc(plane->crtc);
1357         pipe = intel_crtc->pipe;
1358
1359         if (intel_crtc->active) {
1360                 bool primary_was_enabled = intel_crtc->primary_enabled;
1361
1362                 intel_crtc->primary_enabled = true;
1363
1364                 intel_plane->disable_plane(plane, plane->crtc);
1365
1366                 if (!primary_was_enabled && intel_crtc->primary_enabled)
1367                         intel_post_enable_primary(plane->crtc);
1368         }
1369
1370         if (intel_plane->obj) {
1371                 if (intel_crtc->active)
1372                         intel_wait_for_vblank(dev, intel_plane->pipe);
1373
1374                 mutex_lock(&dev->struct_mutex);
1375                 intel_unpin_fb_obj(intel_plane->obj);
1376                 i915_gem_track_fb(intel_plane->obj, NULL,
1377                                   INTEL_FRONTBUFFER_SPRITE(pipe));
1378                 mutex_unlock(&dev->struct_mutex);
1379
1380                 intel_plane->obj = NULL;
1381         }
1382
1383         return 0;
1384 }
1385
1386 static void intel_destroy_plane(struct drm_plane *plane)
1387 {
1388         struct intel_plane *intel_plane = to_intel_plane(plane);
1389         intel_disable_plane(plane);
1390         drm_plane_cleanup(plane);
1391         kfree(intel_plane);
1392 }
1393
1394 int intel_sprite_set_colorkey(struct drm_device *dev, void *data,
1395                               struct drm_file *file_priv)
1396 {
1397         struct drm_intel_sprite_colorkey *set = data;
1398         struct drm_plane *plane;
1399         struct intel_plane *intel_plane;
1400         int ret = 0;
1401
1402         if (!drm_core_check_feature(dev, DRIVER_MODESET))
1403                 return -ENODEV;
1404
1405         /* Make sure we don't try to enable both src & dest simultaneously */
1406         if ((set->flags & (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE)) == (I915_SET_COLORKEY_DESTINATION | I915_SET_COLORKEY_SOURCE))
1407                 return -EINVAL;
1408
1409         drm_modeset_lock_all(dev);
1410
1411         plane = drm_plane_find(dev, set->plane_id);
1412         if (!plane) {
1413                 ret = -ENOENT;
1414                 goto out_unlock;
1415         }
1416
1417         intel_plane = to_intel_plane(plane);
1418         ret = intel_plane->update_colorkey(plane, set);
1419
1420 out_unlock:
1421         drm_modeset_unlock_all(dev);
1422         return ret;
1423 }
1424
1425 int intel_sprite_get_colorkey(struct drm_device *dev, void *data,
1426                               struct drm_file *file_priv)
1427 {
1428         struct drm_intel_sprite_colorkey *get = data;
1429         struct drm_plane *plane;
1430         struct intel_plane *intel_plane;
1431         int ret = 0;
1432
1433         if (!drm_core_check_feature(dev, DRIVER_MODESET))
1434                 return -ENODEV;
1435
1436         drm_modeset_lock_all(dev);
1437
1438         plane = drm_plane_find(dev, get->plane_id);
1439         if (!plane) {
1440                 ret = -ENOENT;
1441                 goto out_unlock;
1442         }
1443
1444         intel_plane = to_intel_plane(plane);
1445         intel_plane->get_colorkey(plane, get);
1446
1447 out_unlock:
1448         drm_modeset_unlock_all(dev);
1449         return ret;
1450 }
1451
1452 int intel_plane_set_property(struct drm_plane *plane,
1453                              struct drm_property *prop,
1454                              uint64_t val)
1455 {
1456         struct drm_device *dev = plane->dev;
1457         struct intel_plane *intel_plane = to_intel_plane(plane);
1458         uint64_t old_val;
1459         int ret = -ENOENT;
1460
1461         if (prop == dev->mode_config.rotation_property) {
1462                 /* exactly one rotation angle please */
1463                 if (hweight32(val & 0xf) != 1)
1464                         return -EINVAL;
1465
1466                 if (intel_plane->rotation == val)
1467                         return 0;
1468
1469                 old_val = intel_plane->rotation;
1470                 intel_plane->rotation = val;
1471                 ret = intel_plane_restore(plane);
1472                 if (ret)
1473                         intel_plane->rotation = old_val;
1474         }
1475
1476         return ret;
1477 }
1478
1479 int intel_plane_restore(struct drm_plane *plane)
1480 {
1481         struct intel_plane *intel_plane = to_intel_plane(plane);
1482
1483         if (!plane->crtc || !plane->fb)
1484                 return 0;
1485
1486         return plane->funcs->update_plane(plane, plane->crtc, plane->fb,
1487                                   intel_plane->crtc_x, intel_plane->crtc_y,
1488                                   intel_plane->crtc_w, intel_plane->crtc_h,
1489                                   intel_plane->src_x, intel_plane->src_y,
1490                                   intel_plane->src_w, intel_plane->src_h);
1491 }
1492
1493 void intel_plane_disable(struct drm_plane *plane)
1494 {
1495         if (!plane->crtc || !plane->fb)
1496                 return;
1497
1498         intel_disable_plane(plane);
1499 }
1500
1501 static const struct drm_plane_funcs intel_plane_funcs = {
1502         .update_plane = intel_update_plane,
1503         .disable_plane = intel_disable_plane,
1504         .destroy = intel_destroy_plane,
1505         .set_property = intel_plane_set_property,
1506 };
1507
1508 static uint32_t ilk_plane_formats[] = {
1509         DRM_FORMAT_XRGB8888,
1510         DRM_FORMAT_YUYV,
1511         DRM_FORMAT_YVYU,
1512         DRM_FORMAT_UYVY,
1513         DRM_FORMAT_VYUY,
1514 };
1515
1516 static uint32_t snb_plane_formats[] = {
1517         DRM_FORMAT_XBGR8888,
1518         DRM_FORMAT_XRGB8888,
1519         DRM_FORMAT_YUYV,
1520         DRM_FORMAT_YVYU,
1521         DRM_FORMAT_UYVY,
1522         DRM_FORMAT_VYUY,
1523 };
1524
1525 static uint32_t vlv_plane_formats[] = {
1526         DRM_FORMAT_RGB565,
1527         DRM_FORMAT_ABGR8888,
1528         DRM_FORMAT_ARGB8888,
1529         DRM_FORMAT_XBGR8888,
1530         DRM_FORMAT_XRGB8888,
1531         DRM_FORMAT_XBGR2101010,
1532         DRM_FORMAT_ABGR2101010,
1533         DRM_FORMAT_YUYV,
1534         DRM_FORMAT_YVYU,
1535         DRM_FORMAT_UYVY,
1536         DRM_FORMAT_VYUY,
1537 };
1538
1539 static uint32_t skl_plane_formats[] = {
1540         DRM_FORMAT_RGB565,
1541         DRM_FORMAT_ABGR8888,
1542         DRM_FORMAT_ARGB8888,
1543         DRM_FORMAT_XBGR8888,
1544         DRM_FORMAT_XRGB8888,
1545         DRM_FORMAT_YUYV,
1546         DRM_FORMAT_YVYU,
1547         DRM_FORMAT_UYVY,
1548         DRM_FORMAT_VYUY,
1549 };
1550
1551 int
1552 intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane)
1553 {
1554         struct intel_plane *intel_plane;
1555         unsigned long possible_crtcs;
1556         const uint32_t *plane_formats;
1557         int num_plane_formats;
1558         int ret;
1559
1560         if (INTEL_INFO(dev)->gen < 5)
1561                 return -ENODEV;
1562
1563         intel_plane = kzalloc(sizeof(*intel_plane), GFP_KERNEL);
1564         if (!intel_plane)
1565                 return -ENOMEM;
1566
1567         switch (INTEL_INFO(dev)->gen) {
1568         case 5:
1569         case 6:
1570                 intel_plane->can_scale = true;
1571                 intel_plane->max_downscale = 16;
1572                 intel_plane->update_plane = ilk_update_plane;
1573                 intel_plane->disable_plane = ilk_disable_plane;
1574                 intel_plane->update_colorkey = ilk_update_colorkey;
1575                 intel_plane->get_colorkey = ilk_get_colorkey;
1576
1577                 if (IS_GEN6(dev)) {
1578                         plane_formats = snb_plane_formats;
1579                         num_plane_formats = ARRAY_SIZE(snb_plane_formats);
1580                 } else {
1581                         plane_formats = ilk_plane_formats;
1582                         num_plane_formats = ARRAY_SIZE(ilk_plane_formats);
1583                 }
1584                 break;
1585
1586         case 7:
1587         case 8:
1588                 if (IS_IVYBRIDGE(dev)) {
1589                         intel_plane->can_scale = true;
1590                         intel_plane->max_downscale = 2;
1591                 } else {
1592                         intel_plane->can_scale = false;
1593                         intel_plane->max_downscale = 1;
1594                 }
1595
1596                 if (IS_VALLEYVIEW(dev)) {
1597                         intel_plane->update_plane = vlv_update_plane;
1598                         intel_plane->disable_plane = vlv_disable_plane;
1599                         intel_plane->update_colorkey = vlv_update_colorkey;
1600                         intel_plane->get_colorkey = vlv_get_colorkey;
1601
1602                         plane_formats = vlv_plane_formats;
1603                         num_plane_formats = ARRAY_SIZE(vlv_plane_formats);
1604                 } else {
1605                         intel_plane->update_plane = ivb_update_plane;
1606                         intel_plane->disable_plane = ivb_disable_plane;
1607                         intel_plane->update_colorkey = ivb_update_colorkey;
1608                         intel_plane->get_colorkey = ivb_get_colorkey;
1609
1610                         plane_formats = snb_plane_formats;
1611                         num_plane_formats = ARRAY_SIZE(snb_plane_formats);
1612                 }
1613                 break;
1614         case 9:
1615                 /*
1616                  * FIXME: Skylake planes can be scaled (with some restrictions),
1617                  * but this is for another time.
1618                  */
1619                 intel_plane->can_scale = false;
1620                 intel_plane->max_downscale = 1;
1621                 intel_plane->update_plane = skl_update_plane;
1622                 intel_plane->disable_plane = skl_disable_plane;
1623                 intel_plane->update_colorkey = skl_update_colorkey;
1624                 intel_plane->get_colorkey = skl_get_colorkey;
1625
1626                 plane_formats = skl_plane_formats;
1627                 num_plane_formats = ARRAY_SIZE(skl_plane_formats);
1628                 break;
1629         default:
1630                 kfree(intel_plane);
1631                 return -ENODEV;
1632         }
1633
1634         intel_plane->pipe = pipe;
1635         intel_plane->plane = plane;
1636         intel_plane->rotation = BIT(DRM_ROTATE_0);
1637         possible_crtcs = (1 << pipe);
1638         ret = drm_universal_plane_init(dev, &intel_plane->base, possible_crtcs,
1639                                        &intel_plane_funcs,
1640                                        plane_formats, num_plane_formats,
1641                                        DRM_PLANE_TYPE_OVERLAY);
1642         if (ret) {
1643                 kfree(intel_plane);
1644                 goto out;
1645         }
1646
1647         if (!dev->mode_config.rotation_property)
1648                 dev->mode_config.rotation_property =
1649                         drm_mode_create_rotation_property(dev,
1650                                                           BIT(DRM_ROTATE_0) |
1651                                                           BIT(DRM_ROTATE_180));
1652
1653         if (dev->mode_config.rotation_property)
1654                 drm_object_attach_property(&intel_plane->base.base,
1655                                            dev->mode_config.rotation_property,
1656                                            intel_plane->rotation);
1657
1658  out:
1659         return ret;
1660 }