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