]> Git Repo - linux.git/blob - drivers/gpu/drm/i915/display/intel_sprite.c
net: wan: Add framer framework support
[linux.git] / drivers / gpu / drm / i915 / display / 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
33 #include <linux/string_helpers.h>
34
35 #include <drm/drm_atomic_helper.h>
36 #include <drm/drm_blend.h>
37 #include <drm/drm_color_mgmt.h>
38 #include <drm/drm_fourcc.h>
39 #include <drm/drm_rect.h>
40
41 #include "i915_drv.h"
42 #include "i915_reg.h"
43 #include "i9xx_plane.h"
44 #include "intel_atomic_plane.h"
45 #include "intel_de.h"
46 #include "intel_display_types.h"
47 #include "intel_fb.h"
48 #include "intel_frontbuffer.h"
49 #include "intel_sprite.h"
50
51 static void i9xx_plane_linear_gamma(u16 gamma[8])
52 {
53         /* The points are not evenly spaced. */
54         static const u8 in[8] = { 0, 1, 2, 4, 8, 16, 24, 32 };
55         int i;
56
57         for (i = 0; i < 8; i++)
58                 gamma[i] = (in[i] << 8) / 32;
59 }
60
61 static void
62 chv_sprite_update_csc(const struct intel_plane_state *plane_state)
63 {
64         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
65         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
66         const struct drm_framebuffer *fb = plane_state->hw.fb;
67         enum plane_id plane_id = plane->id;
68         /*
69          * |r|   | c0 c1 c2 |   |cr|
70          * |g| = | c3 c4 c5 | x |y |
71          * |b|   | c6 c7 c8 |   |cb|
72          *
73          * Coefficients are s3.12.
74          *
75          * Cb and Cr apparently come in as signed already, and
76          * we always get full range data in on account of CLRC0/1.
77          */
78         static const s16 csc_matrix[][9] = {
79                 /* BT.601 full range YCbCr -> full range RGB */
80                 [DRM_COLOR_YCBCR_BT601] = {
81                          5743, 4096,     0,
82                         -2925, 4096, -1410,
83                             0, 4096,  7258,
84                 },
85                 /* BT.709 full range YCbCr -> full range RGB */
86                 [DRM_COLOR_YCBCR_BT709] = {
87                          6450, 4096,     0,
88                         -1917, 4096,  -767,
89                             0, 4096,  7601,
90                 },
91         };
92         const s16 *csc = csc_matrix[plane_state->hw.color_encoding];
93
94         /* Seems RGB data bypasses the CSC always */
95         if (!fb->format->is_yuv)
96                 return;
97
98         intel_de_write_fw(dev_priv, SPCSCYGOFF(plane_id),
99                           SPCSC_OOFF(0) | SPCSC_IOFF(0));
100         intel_de_write_fw(dev_priv, SPCSCCBOFF(plane_id),
101                           SPCSC_OOFF(0) | SPCSC_IOFF(0));
102         intel_de_write_fw(dev_priv, SPCSCCROFF(plane_id),
103                           SPCSC_OOFF(0) | SPCSC_IOFF(0));
104
105         intel_de_write_fw(dev_priv, SPCSCC01(plane_id),
106                           SPCSC_C1(csc[1]) | SPCSC_C0(csc[0]));
107         intel_de_write_fw(dev_priv, SPCSCC23(plane_id),
108                           SPCSC_C1(csc[3]) | SPCSC_C0(csc[2]));
109         intel_de_write_fw(dev_priv, SPCSCC45(plane_id),
110                           SPCSC_C1(csc[5]) | SPCSC_C0(csc[4]));
111         intel_de_write_fw(dev_priv, SPCSCC67(plane_id),
112                           SPCSC_C1(csc[7]) | SPCSC_C0(csc[6]));
113         intel_de_write_fw(dev_priv, SPCSCC8(plane_id), SPCSC_C0(csc[8]));
114
115         intel_de_write_fw(dev_priv, SPCSCYGICLAMP(plane_id),
116                           SPCSC_IMAX(1023) | SPCSC_IMIN(0));
117         intel_de_write_fw(dev_priv, SPCSCCBICLAMP(plane_id),
118                           SPCSC_IMAX(512) | SPCSC_IMIN(-512));
119         intel_de_write_fw(dev_priv, SPCSCCRICLAMP(plane_id),
120                           SPCSC_IMAX(512) | SPCSC_IMIN(-512));
121
122         intel_de_write_fw(dev_priv, SPCSCYGOCLAMP(plane_id),
123                           SPCSC_OMAX(1023) | SPCSC_OMIN(0));
124         intel_de_write_fw(dev_priv, SPCSCCBOCLAMP(plane_id),
125                           SPCSC_OMAX(1023) | SPCSC_OMIN(0));
126         intel_de_write_fw(dev_priv, SPCSCCROCLAMP(plane_id),
127                           SPCSC_OMAX(1023) | SPCSC_OMIN(0));
128 }
129
130 #define SIN_0 0
131 #define COS_0 1
132
133 static void
134 vlv_sprite_update_clrc(const struct intel_plane_state *plane_state)
135 {
136         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
137         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
138         const struct drm_framebuffer *fb = plane_state->hw.fb;
139         enum pipe pipe = plane->pipe;
140         enum plane_id plane_id = plane->id;
141         int contrast, brightness, sh_scale, sh_sin, sh_cos;
142
143         if (fb->format->is_yuv &&
144             plane_state->hw.color_range == DRM_COLOR_YCBCR_LIMITED_RANGE) {
145                 /*
146                  * Expand limited range to full range:
147                  * Contrast is applied first and is used to expand Y range.
148                  * Brightness is applied second and is used to remove the
149                  * offset from Y. Saturation/hue is used to expand CbCr range.
150                  */
151                 contrast = DIV_ROUND_CLOSEST(255 << 6, 235 - 16);
152                 brightness = -DIV_ROUND_CLOSEST(16 * 255, 235 - 16);
153                 sh_scale = DIV_ROUND_CLOSEST(128 << 7, 240 - 128);
154                 sh_sin = SIN_0 * sh_scale;
155                 sh_cos = COS_0 * sh_scale;
156         } else {
157                 /* Pass-through everything. */
158                 contrast = 1 << 6;
159                 brightness = 0;
160                 sh_scale = 1 << 7;
161                 sh_sin = SIN_0 * sh_scale;
162                 sh_cos = COS_0 * sh_scale;
163         }
164
165         /* FIXME these register are single buffered :( */
166         intel_de_write_fw(dev_priv, SPCLRC0(pipe, plane_id),
167                           SP_CONTRAST(contrast) | SP_BRIGHTNESS(brightness));
168         intel_de_write_fw(dev_priv, SPCLRC1(pipe, plane_id),
169                           SP_SH_SIN(sh_sin) | SP_SH_COS(sh_cos));
170 }
171
172 static void
173 vlv_plane_ratio(const struct intel_crtc_state *crtc_state,
174                 const struct intel_plane_state *plane_state,
175                 unsigned int *num, unsigned int *den)
176 {
177         u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
178         const struct drm_framebuffer *fb = plane_state->hw.fb;
179         unsigned int cpp = fb->format->cpp[0];
180
181         /*
182          * VLV bspec only considers cases where all three planes are
183          * enabled, and cases where the primary and one sprite is enabled.
184          * Let's assume the case with just two sprites enabled also
185          * maps to the latter case.
186          */
187         if (hweight8(active_planes) == 3) {
188                 switch (cpp) {
189                 case 8:
190                         *num = 11;
191                         *den = 8;
192                         break;
193                 case 4:
194                         *num = 18;
195                         *den = 16;
196                         break;
197                 default:
198                         *num = 1;
199                         *den = 1;
200                         break;
201                 }
202         } else if (hweight8(active_planes) == 2) {
203                 switch (cpp) {
204                 case 8:
205                         *num = 10;
206                         *den = 8;
207                         break;
208                 case 4:
209                         *num = 17;
210                         *den = 16;
211                         break;
212                 default:
213                         *num = 1;
214                         *den = 1;
215                         break;
216                 }
217         } else {
218                 switch (cpp) {
219                 case 8:
220                         *num = 10;
221                         *den = 8;
222                         break;
223                 default:
224                         *num = 1;
225                         *den = 1;
226                         break;
227                 }
228         }
229 }
230
231 int vlv_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
232                         const struct intel_plane_state *plane_state)
233 {
234         unsigned int pixel_rate;
235         unsigned int num, den;
236
237         /*
238          * Note that crtc_state->pixel_rate accounts for both
239          * horizontal and vertical panel fitter downscaling factors.
240          * Pre-HSW bspec tells us to only consider the horizontal
241          * downscaling factor here. We ignore that and just consider
242          * both for simplicity.
243          */
244         pixel_rate = crtc_state->pixel_rate;
245
246         vlv_plane_ratio(crtc_state, plane_state, &num, &den);
247
248         return DIV_ROUND_UP(pixel_rate * num, den);
249 }
250
251 static u32 vlv_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
252 {
253         u32 sprctl = 0;
254
255         if (crtc_state->gamma_enable)
256                 sprctl |= SP_PIPE_GAMMA_ENABLE;
257
258         return sprctl;
259 }
260
261 static u32 vlv_sprite_ctl(const struct intel_crtc_state *crtc_state,
262                           const struct intel_plane_state *plane_state)
263 {
264         const struct drm_framebuffer *fb = plane_state->hw.fb;
265         unsigned int rotation = plane_state->hw.rotation;
266         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
267         u32 sprctl;
268
269         sprctl = SP_ENABLE;
270
271         switch (fb->format->format) {
272         case DRM_FORMAT_YUYV:
273                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YUYV;
274                 break;
275         case DRM_FORMAT_YVYU:
276                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_YVYU;
277                 break;
278         case DRM_FORMAT_UYVY:
279                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_UYVY;
280                 break;
281         case DRM_FORMAT_VYUY:
282                 sprctl |= SP_FORMAT_YUV422 | SP_YUV_ORDER_VYUY;
283                 break;
284         case DRM_FORMAT_C8:
285                 sprctl |= SP_FORMAT_8BPP;
286                 break;
287         case DRM_FORMAT_RGB565:
288                 sprctl |= SP_FORMAT_BGR565;
289                 break;
290         case DRM_FORMAT_XRGB8888:
291                 sprctl |= SP_FORMAT_BGRX8888;
292                 break;
293         case DRM_FORMAT_ARGB8888:
294                 sprctl |= SP_FORMAT_BGRA8888;
295                 break;
296         case DRM_FORMAT_XBGR2101010:
297                 sprctl |= SP_FORMAT_RGBX1010102;
298                 break;
299         case DRM_FORMAT_ABGR2101010:
300                 sprctl |= SP_FORMAT_RGBA1010102;
301                 break;
302         case DRM_FORMAT_XRGB2101010:
303                 sprctl |= SP_FORMAT_BGRX1010102;
304                 break;
305         case DRM_FORMAT_ARGB2101010:
306                 sprctl |= SP_FORMAT_BGRA1010102;
307                 break;
308         case DRM_FORMAT_XBGR8888:
309                 sprctl |= SP_FORMAT_RGBX8888;
310                 break;
311         case DRM_FORMAT_ABGR8888:
312                 sprctl |= SP_FORMAT_RGBA8888;
313                 break;
314         default:
315                 MISSING_CASE(fb->format->format);
316                 return 0;
317         }
318
319         if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
320                 sprctl |= SP_YUV_FORMAT_BT709;
321
322         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
323                 sprctl |= SP_TILED;
324
325         if (rotation & DRM_MODE_ROTATE_180)
326                 sprctl |= SP_ROTATE_180;
327
328         if (rotation & DRM_MODE_REFLECT_X)
329                 sprctl |= SP_MIRROR;
330
331         if (key->flags & I915_SET_COLORKEY_SOURCE)
332                 sprctl |= SP_SOURCE_KEY;
333
334         return sprctl;
335 }
336
337 static void vlv_sprite_update_gamma(const struct intel_plane_state *plane_state)
338 {
339         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
340         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
341         const struct drm_framebuffer *fb = plane_state->hw.fb;
342         enum pipe pipe = plane->pipe;
343         enum plane_id plane_id = plane->id;
344         u16 gamma[8];
345         int i;
346
347         /* Seems RGB data bypasses the gamma always */
348         if (!fb->format->is_yuv)
349                 return;
350
351         i9xx_plane_linear_gamma(gamma);
352
353         /* FIXME these register are single buffered :( */
354         /* The two end points are implicit (0.0 and 1.0) */
355         for (i = 1; i < 8 - 1; i++)
356                 intel_de_write_fw(dev_priv, SPGAMC(pipe, plane_id, i - 1),
357                                   gamma[i] << 16 | gamma[i] << 8 | gamma[i]);
358 }
359
360 static void
361 vlv_sprite_update_noarm(struct intel_plane *plane,
362                         const struct intel_crtc_state *crtc_state,
363                         const struct intel_plane_state *plane_state)
364 {
365         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
366         enum pipe pipe = plane->pipe;
367         enum plane_id plane_id = plane->id;
368         int crtc_x = plane_state->uapi.dst.x1;
369         int crtc_y = plane_state->uapi.dst.y1;
370         u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
371         u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
372
373         intel_de_write_fw(dev_priv, SPSTRIDE(pipe, plane_id),
374                           plane_state->view.color_plane[0].mapping_stride);
375         intel_de_write_fw(dev_priv, SPPOS(pipe, plane_id),
376                           SP_POS_Y(crtc_y) | SP_POS_X(crtc_x));
377         intel_de_write_fw(dev_priv, SPSIZE(pipe, plane_id),
378                           SP_HEIGHT(crtc_h - 1) | SP_WIDTH(crtc_w - 1));
379 }
380
381 static void
382 vlv_sprite_update_arm(struct intel_plane *plane,
383                       const struct intel_crtc_state *crtc_state,
384                       const struct intel_plane_state *plane_state)
385 {
386         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
387         enum pipe pipe = plane->pipe;
388         enum plane_id plane_id = plane->id;
389         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
390         u32 sprsurf_offset = plane_state->view.color_plane[0].offset;
391         u32 x = plane_state->view.color_plane[0].x;
392         u32 y = plane_state->view.color_plane[0].y;
393         u32 sprctl, linear_offset;
394
395         sprctl = plane_state->ctl | vlv_sprite_ctl_crtc(crtc_state);
396
397         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
398
399         if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B)
400                 chv_sprite_update_csc(plane_state);
401
402         if (key->flags) {
403                 intel_de_write_fw(dev_priv, SPKEYMINVAL(pipe, plane_id),
404                                   key->min_value);
405                 intel_de_write_fw(dev_priv, SPKEYMSK(pipe, plane_id),
406                                   key->channel_mask);
407                 intel_de_write_fw(dev_priv, SPKEYMAXVAL(pipe, plane_id),
408                                   key->max_value);
409         }
410
411         intel_de_write_fw(dev_priv, SPCONSTALPHA(pipe, plane_id), 0);
412
413         intel_de_write_fw(dev_priv, SPLINOFF(pipe, plane_id), linear_offset);
414         intel_de_write_fw(dev_priv, SPTILEOFF(pipe, plane_id),
415                           SP_OFFSET_Y(y) | SP_OFFSET_X(x));
416
417         /*
418          * The control register self-arms if the plane was previously
419          * disabled. Try to make the plane enable atomic by writing
420          * the control register just before the surface register.
421          */
422         intel_de_write_fw(dev_priv, SPCNTR(pipe, plane_id), sprctl);
423         intel_de_write_fw(dev_priv, SPSURF(pipe, plane_id),
424                           intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
425
426         vlv_sprite_update_clrc(plane_state);
427         vlv_sprite_update_gamma(plane_state);
428 }
429
430 static void
431 vlv_sprite_disable_arm(struct intel_plane *plane,
432                        const struct intel_crtc_state *crtc_state)
433 {
434         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
435         enum pipe pipe = plane->pipe;
436         enum plane_id plane_id = plane->id;
437
438         intel_de_write_fw(dev_priv, SPCNTR(pipe, plane_id), 0);
439         intel_de_write_fw(dev_priv, SPSURF(pipe, plane_id), 0);
440 }
441
442 static bool
443 vlv_sprite_get_hw_state(struct intel_plane *plane,
444                         enum pipe *pipe)
445 {
446         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
447         enum intel_display_power_domain power_domain;
448         enum plane_id plane_id = plane->id;
449         intel_wakeref_t wakeref;
450         bool ret;
451
452         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
453         wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
454         if (!wakeref)
455                 return false;
456
457         ret = intel_de_read(dev_priv, SPCNTR(plane->pipe, plane_id)) & SP_ENABLE;
458
459         *pipe = plane->pipe;
460
461         intel_display_power_put(dev_priv, power_domain, wakeref);
462
463         return ret;
464 }
465
466 static void ivb_plane_ratio(const struct intel_crtc_state *crtc_state,
467                             const struct intel_plane_state *plane_state,
468                             unsigned int *num, unsigned int *den)
469 {
470         u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
471         const struct drm_framebuffer *fb = plane_state->hw.fb;
472         unsigned int cpp = fb->format->cpp[0];
473
474         if (hweight8(active_planes) == 2) {
475                 switch (cpp) {
476                 case 8:
477                         *num = 10;
478                         *den = 8;
479                         break;
480                 case 4:
481                         *num = 17;
482                         *den = 16;
483                         break;
484                 default:
485                         *num = 1;
486                         *den = 1;
487                         break;
488                 }
489         } else {
490                 switch (cpp) {
491                 case 8:
492                         *num = 9;
493                         *den = 8;
494                         break;
495                 default:
496                         *num = 1;
497                         *den = 1;
498                         break;
499                 }
500         }
501 }
502
503 static void ivb_plane_ratio_scaling(const struct intel_crtc_state *crtc_state,
504                                     const struct intel_plane_state *plane_state,
505                                     unsigned int *num, unsigned int *den)
506 {
507         const struct drm_framebuffer *fb = plane_state->hw.fb;
508         unsigned int cpp = fb->format->cpp[0];
509
510         switch (cpp) {
511         case 8:
512                 *num = 12;
513                 *den = 8;
514                 break;
515         case 4:
516                 *num = 19;
517                 *den = 16;
518                 break;
519         case 2:
520                 *num = 33;
521                 *den = 32;
522                 break;
523         default:
524                 *num = 1;
525                 *den = 1;
526                 break;
527         }
528 }
529
530 int ivb_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
531                         const struct intel_plane_state *plane_state)
532 {
533         unsigned int pixel_rate;
534         unsigned int num, den;
535
536         /*
537          * Note that crtc_state->pixel_rate accounts for both
538          * horizontal and vertical panel fitter downscaling factors.
539          * Pre-HSW bspec tells us to only consider the horizontal
540          * downscaling factor here. We ignore that and just consider
541          * both for simplicity.
542          */
543         pixel_rate = crtc_state->pixel_rate;
544
545         ivb_plane_ratio(crtc_state, plane_state, &num, &den);
546
547         return DIV_ROUND_UP(pixel_rate * num, den);
548 }
549
550 static int ivb_sprite_min_cdclk(const struct intel_crtc_state *crtc_state,
551                                 const struct intel_plane_state *plane_state)
552 {
553         unsigned int src_w, dst_w, pixel_rate;
554         unsigned int num, den;
555
556         /*
557          * Note that crtc_state->pixel_rate accounts for both
558          * horizontal and vertical panel fitter downscaling factors.
559          * Pre-HSW bspec tells us to only consider the horizontal
560          * downscaling factor here. We ignore that and just consider
561          * both for simplicity.
562          */
563         pixel_rate = crtc_state->pixel_rate;
564
565         src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
566         dst_w = drm_rect_width(&plane_state->uapi.dst);
567
568         if (src_w != dst_w)
569                 ivb_plane_ratio_scaling(crtc_state, plane_state, &num, &den);
570         else
571                 ivb_plane_ratio(crtc_state, plane_state, &num, &den);
572
573         /* Horizontal downscaling limits the maximum pixel rate */
574         dst_w = min(src_w, dst_w);
575
576         return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, num * src_w),
577                                 den * dst_w);
578 }
579
580 static void hsw_plane_ratio(const struct intel_crtc_state *crtc_state,
581                             const struct intel_plane_state *plane_state,
582                             unsigned int *num, unsigned int *den)
583 {
584         u8 active_planes = crtc_state->active_planes & ~BIT(PLANE_CURSOR);
585         const struct drm_framebuffer *fb = plane_state->hw.fb;
586         unsigned int cpp = fb->format->cpp[0];
587
588         if (hweight8(active_planes) == 2) {
589                 switch (cpp) {
590                 case 8:
591                         *num = 10;
592                         *den = 8;
593                         break;
594                 default:
595                         *num = 1;
596                         *den = 1;
597                         break;
598                 }
599         } else {
600                 switch (cpp) {
601                 case 8:
602                         *num = 9;
603                         *den = 8;
604                         break;
605                 default:
606                         *num = 1;
607                         *den = 1;
608                         break;
609                 }
610         }
611 }
612
613 int hsw_plane_min_cdclk(const struct intel_crtc_state *crtc_state,
614                         const struct intel_plane_state *plane_state)
615 {
616         unsigned int pixel_rate = crtc_state->pixel_rate;
617         unsigned int num, den;
618
619         hsw_plane_ratio(crtc_state, plane_state, &num, &den);
620
621         return DIV_ROUND_UP(pixel_rate * num, den);
622 }
623
624 static u32 ivb_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
625 {
626         u32 sprctl = 0;
627
628         if (crtc_state->gamma_enable)
629                 sprctl |= SPRITE_PIPE_GAMMA_ENABLE;
630
631         if (crtc_state->csc_enable)
632                 sprctl |= SPRITE_PIPE_CSC_ENABLE;
633
634         return sprctl;
635 }
636
637 static bool ivb_need_sprite_gamma(const struct intel_plane_state *plane_state)
638 {
639         struct drm_i915_private *dev_priv =
640                 to_i915(plane_state->uapi.plane->dev);
641         const struct drm_framebuffer *fb = plane_state->hw.fb;
642
643         return fb->format->cpp[0] == 8 &&
644                 (IS_IVYBRIDGE(dev_priv) || IS_HASWELL(dev_priv));
645 }
646
647 static u32 ivb_sprite_ctl(const struct intel_crtc_state *crtc_state,
648                           const struct intel_plane_state *plane_state)
649 {
650         struct drm_i915_private *dev_priv =
651                 to_i915(plane_state->uapi.plane->dev);
652         const struct drm_framebuffer *fb = plane_state->hw.fb;
653         unsigned int rotation = plane_state->hw.rotation;
654         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
655         u32 sprctl;
656
657         sprctl = SPRITE_ENABLE;
658
659         if (IS_IVYBRIDGE(dev_priv))
660                 sprctl |= SPRITE_TRICKLE_FEED_DISABLE;
661
662         switch (fb->format->format) {
663         case DRM_FORMAT_XBGR8888:
664                 sprctl |= SPRITE_FORMAT_RGBX888 | SPRITE_RGB_ORDER_RGBX;
665                 break;
666         case DRM_FORMAT_XRGB8888:
667                 sprctl |= SPRITE_FORMAT_RGBX888;
668                 break;
669         case DRM_FORMAT_XBGR2101010:
670                 sprctl |= SPRITE_FORMAT_RGBX101010 | SPRITE_RGB_ORDER_RGBX;
671                 break;
672         case DRM_FORMAT_XRGB2101010:
673                 sprctl |= SPRITE_FORMAT_RGBX101010;
674                 break;
675         case DRM_FORMAT_XBGR16161616F:
676                 sprctl |= SPRITE_FORMAT_RGBX161616 | SPRITE_RGB_ORDER_RGBX;
677                 break;
678         case DRM_FORMAT_XRGB16161616F:
679                 sprctl |= SPRITE_FORMAT_RGBX161616;
680                 break;
681         case DRM_FORMAT_YUYV:
682                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YUYV;
683                 break;
684         case DRM_FORMAT_YVYU:
685                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_YVYU;
686                 break;
687         case DRM_FORMAT_UYVY:
688                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_UYVY;
689                 break;
690         case DRM_FORMAT_VYUY:
691                 sprctl |= SPRITE_FORMAT_YUV422 | SPRITE_YUV_ORDER_VYUY;
692                 break;
693         default:
694                 MISSING_CASE(fb->format->format);
695                 return 0;
696         }
697
698         if (!ivb_need_sprite_gamma(plane_state))
699                 sprctl |= SPRITE_PLANE_GAMMA_DISABLE;
700
701         if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
702                 sprctl |= SPRITE_YUV_TO_RGB_CSC_FORMAT_BT709;
703
704         if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
705                 sprctl |= SPRITE_YUV_RANGE_CORRECTION_DISABLE;
706
707         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
708                 sprctl |= SPRITE_TILED;
709
710         if (rotation & DRM_MODE_ROTATE_180)
711                 sprctl |= SPRITE_ROTATE_180;
712
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
718         return sprctl;
719 }
720
721 static void ivb_sprite_linear_gamma(const struct intel_plane_state *plane_state,
722                                     u16 gamma[18])
723 {
724         int scale, i;
725
726         /*
727          * WaFP16GammaEnabling:ivb,hsw
728          * "Workaround : When using the 64-bit format, the sprite output
729          *  on each color channel has one quarter amplitude. It can be
730          *  brought up to full amplitude by using sprite internal gamma
731          *  correction, pipe gamma correction, or pipe color space
732          *  conversion to multiply the sprite output by four."
733          */
734         scale = 4;
735
736         for (i = 0; i < 16; i++)
737                 gamma[i] = min((scale * i << 10) / 16, (1 << 10) - 1);
738
739         gamma[i] = min((scale * i << 10) / 16, 1 << 10);
740         i++;
741
742         gamma[i] = 3 << 10;
743         i++;
744 }
745
746 static void ivb_sprite_update_gamma(const struct intel_plane_state *plane_state)
747 {
748         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
749         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
750         enum pipe pipe = plane->pipe;
751         u16 gamma[18];
752         int i;
753
754         if (!ivb_need_sprite_gamma(plane_state))
755                 return;
756
757         ivb_sprite_linear_gamma(plane_state, gamma);
758
759         /* FIXME these register are single buffered :( */
760         for (i = 0; i < 16; i++)
761                 intel_de_write_fw(dev_priv, SPRGAMC(pipe, i),
762                                   gamma[i] << 20 | gamma[i] << 10 | gamma[i]);
763
764         intel_de_write_fw(dev_priv, SPRGAMC16(pipe, 0), gamma[i]);
765         intel_de_write_fw(dev_priv, SPRGAMC16(pipe, 1), gamma[i]);
766         intel_de_write_fw(dev_priv, SPRGAMC16(pipe, 2), gamma[i]);
767         i++;
768
769         intel_de_write_fw(dev_priv, SPRGAMC17(pipe, 0), gamma[i]);
770         intel_de_write_fw(dev_priv, SPRGAMC17(pipe, 1), gamma[i]);
771         intel_de_write_fw(dev_priv, SPRGAMC17(pipe, 2), gamma[i]);
772         i++;
773 }
774
775 static void
776 ivb_sprite_update_noarm(struct intel_plane *plane,
777                         const struct intel_crtc_state *crtc_state,
778                         const struct intel_plane_state *plane_state)
779 {
780         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
781         enum pipe pipe = plane->pipe;
782         int crtc_x = plane_state->uapi.dst.x1;
783         int crtc_y = plane_state->uapi.dst.y1;
784         u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
785         u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
786         u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
787         u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
788         u32 sprscale = 0;
789
790         if (crtc_w != src_w || crtc_h != src_h)
791                 sprscale = SPRITE_SCALE_ENABLE |
792                         SPRITE_SRC_WIDTH(src_w - 1) |
793                         SPRITE_SRC_HEIGHT(src_h - 1);
794
795         intel_de_write_fw(dev_priv, SPRSTRIDE(pipe),
796                           plane_state->view.color_plane[0].mapping_stride);
797         intel_de_write_fw(dev_priv, SPRPOS(pipe),
798                           SPRITE_POS_Y(crtc_y) | SPRITE_POS_X(crtc_x));
799         intel_de_write_fw(dev_priv, SPRSIZE(pipe),
800                           SPRITE_HEIGHT(crtc_h - 1) | SPRITE_WIDTH(crtc_w - 1));
801         if (IS_IVYBRIDGE(dev_priv))
802                 intel_de_write_fw(dev_priv, SPRSCALE(pipe), sprscale);
803 }
804
805 static void
806 ivb_sprite_update_arm(struct intel_plane *plane,
807                       const struct intel_crtc_state *crtc_state,
808                       const struct intel_plane_state *plane_state)
809 {
810         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
811         enum pipe pipe = plane->pipe;
812         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
813         u32 sprsurf_offset = plane_state->view.color_plane[0].offset;
814         u32 x = plane_state->view.color_plane[0].x;
815         u32 y = plane_state->view.color_plane[0].y;
816         u32 sprctl, linear_offset;
817
818         sprctl = plane_state->ctl | ivb_sprite_ctl_crtc(crtc_state);
819
820         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
821
822         if (key->flags) {
823                 intel_de_write_fw(dev_priv, SPRKEYVAL(pipe), key->min_value);
824                 intel_de_write_fw(dev_priv, SPRKEYMSK(pipe),
825                                   key->channel_mask);
826                 intel_de_write_fw(dev_priv, SPRKEYMAX(pipe), key->max_value);
827         }
828
829         /* HSW consolidates SPRTILEOFF and SPRLINOFF into a single SPROFFSET
830          * register */
831         if (IS_HASWELL(dev_priv) || IS_BROADWELL(dev_priv)) {
832                 intel_de_write_fw(dev_priv, SPROFFSET(pipe),
833                                   SPRITE_OFFSET_Y(y) | SPRITE_OFFSET_X(x));
834         } else {
835                 intel_de_write_fw(dev_priv, SPRLINOFF(pipe), linear_offset);
836                 intel_de_write_fw(dev_priv, SPRTILEOFF(pipe),
837                                   SPRITE_OFFSET_Y(y) | SPRITE_OFFSET_X(x));
838         }
839
840         /*
841          * The control register self-arms if the plane was previously
842          * disabled. Try to make the plane enable atomic by writing
843          * the control register just before the surface register.
844          */
845         intel_de_write_fw(dev_priv, SPRCTL(pipe), sprctl);
846         intel_de_write_fw(dev_priv, SPRSURF(pipe),
847                           intel_plane_ggtt_offset(plane_state) + sprsurf_offset);
848
849         ivb_sprite_update_gamma(plane_state);
850 }
851
852 static void
853 ivb_sprite_disable_arm(struct intel_plane *plane,
854                        const struct intel_crtc_state *crtc_state)
855 {
856         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
857         enum pipe pipe = plane->pipe;
858
859         intel_de_write_fw(dev_priv, SPRCTL(pipe), 0);
860         /* Disable the scaler */
861         if (IS_IVYBRIDGE(dev_priv))
862                 intel_de_write_fw(dev_priv, SPRSCALE(pipe), 0);
863         intel_de_write_fw(dev_priv, SPRSURF(pipe), 0);
864 }
865
866 static bool
867 ivb_sprite_get_hw_state(struct intel_plane *plane,
868                         enum pipe *pipe)
869 {
870         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
871         enum intel_display_power_domain power_domain;
872         intel_wakeref_t wakeref;
873         bool ret;
874
875         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
876         wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
877         if (!wakeref)
878                 return false;
879
880         ret =  intel_de_read(dev_priv, SPRCTL(plane->pipe)) & SPRITE_ENABLE;
881
882         *pipe = plane->pipe;
883
884         intel_display_power_put(dev_priv, power_domain, wakeref);
885
886         return ret;
887 }
888
889 static int g4x_sprite_min_cdclk(const struct intel_crtc_state *crtc_state,
890                                 const struct intel_plane_state *plane_state)
891 {
892         const struct drm_framebuffer *fb = plane_state->hw.fb;
893         unsigned int hscale, pixel_rate;
894         unsigned int limit, decimate;
895
896         /*
897          * Note that crtc_state->pixel_rate accounts for both
898          * horizontal and vertical panel fitter downscaling factors.
899          * Pre-HSW bspec tells us to only consider the horizontal
900          * downscaling factor here. We ignore that and just consider
901          * both for simplicity.
902          */
903         pixel_rate = crtc_state->pixel_rate;
904
905         /* Horizontal downscaling limits the maximum pixel rate */
906         hscale = drm_rect_calc_hscale(&plane_state->uapi.src,
907                                       &plane_state->uapi.dst,
908                                       0, INT_MAX);
909         hscale = max(hscale, 0x10000u);
910
911         /* Decimation steps at 2x,4x,8x,16x */
912         decimate = ilog2(hscale >> 16);
913         hscale >>= decimate;
914
915         /* Starting limit is 90% of cdclk */
916         limit = 9;
917
918         /* -10% per decimation step */
919         limit -= decimate;
920
921         /* -10% for RGB */
922         if (!fb->format->is_yuv)
923                 limit--;
924
925         /*
926          * We should also do -10% if sprite scaling is enabled
927          * on the other pipe, but we can't really check for that,
928          * so we ignore it.
929          */
930
931         return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate, 10 * hscale),
932                                 limit << 16);
933 }
934
935 static unsigned int
936 g4x_sprite_max_stride(struct intel_plane *plane,
937                       u32 pixel_format, u64 modifier,
938                       unsigned int rotation)
939 {
940         const struct drm_format_info *info = drm_format_info(pixel_format);
941         int cpp = info->cpp[0];
942
943         /* Limit to 4k pixels to guarantee TILEOFF.x doesn't get too big. */
944         if (modifier == I915_FORMAT_MOD_X_TILED)
945                 return min(4096 * cpp, 16 * 1024);
946         else
947                 return 16 * 1024;
948 }
949
950 static unsigned int
951 hsw_sprite_max_stride(struct intel_plane *plane,
952                       u32 pixel_format, u64 modifier,
953                       unsigned int rotation)
954 {
955         const struct drm_format_info *info = drm_format_info(pixel_format);
956         int cpp = info->cpp[0];
957
958         /* Limit to 8k pixels to guarantee OFFSET.x doesn't get too big. */
959         return min(8192 * cpp, 16 * 1024);
960 }
961
962 static u32 g4x_sprite_ctl_crtc(const struct intel_crtc_state *crtc_state)
963 {
964         u32 dvscntr = 0;
965
966         if (crtc_state->gamma_enable)
967                 dvscntr |= DVS_PIPE_GAMMA_ENABLE;
968
969         if (crtc_state->csc_enable)
970                 dvscntr |= DVS_PIPE_CSC_ENABLE;
971
972         return dvscntr;
973 }
974
975 static u32 g4x_sprite_ctl(const struct intel_crtc_state *crtc_state,
976                           const struct intel_plane_state *plane_state)
977 {
978         struct drm_i915_private *dev_priv =
979                 to_i915(plane_state->uapi.plane->dev);
980         const struct drm_framebuffer *fb = plane_state->hw.fb;
981         unsigned int rotation = plane_state->hw.rotation;
982         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
983         u32 dvscntr;
984
985         dvscntr = DVS_ENABLE;
986
987         if (IS_SANDYBRIDGE(dev_priv))
988                 dvscntr |= DVS_TRICKLE_FEED_DISABLE;
989
990         switch (fb->format->format) {
991         case DRM_FORMAT_XBGR8888:
992                 dvscntr |= DVS_FORMAT_RGBX888 | DVS_RGB_ORDER_XBGR;
993                 break;
994         case DRM_FORMAT_XRGB8888:
995                 dvscntr |= DVS_FORMAT_RGBX888;
996                 break;
997         case DRM_FORMAT_XBGR2101010:
998                 dvscntr |= DVS_FORMAT_RGBX101010 | DVS_RGB_ORDER_XBGR;
999                 break;
1000         case DRM_FORMAT_XRGB2101010:
1001                 dvscntr |= DVS_FORMAT_RGBX101010;
1002                 break;
1003         case DRM_FORMAT_XBGR16161616F:
1004                 dvscntr |= DVS_FORMAT_RGBX161616 | DVS_RGB_ORDER_XBGR;
1005                 break;
1006         case DRM_FORMAT_XRGB16161616F:
1007                 dvscntr |= DVS_FORMAT_RGBX161616;
1008                 break;
1009         case DRM_FORMAT_YUYV:
1010                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YUYV;
1011                 break;
1012         case DRM_FORMAT_YVYU:
1013                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_YVYU;
1014                 break;
1015         case DRM_FORMAT_UYVY:
1016                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_UYVY;
1017                 break;
1018         case DRM_FORMAT_VYUY:
1019                 dvscntr |= DVS_FORMAT_YUV422 | DVS_YUV_ORDER_VYUY;
1020                 break;
1021         default:
1022                 MISSING_CASE(fb->format->format);
1023                 return 0;
1024         }
1025
1026         if (plane_state->hw.color_encoding == DRM_COLOR_YCBCR_BT709)
1027                 dvscntr |= DVS_YUV_FORMAT_BT709;
1028
1029         if (plane_state->hw.color_range == DRM_COLOR_YCBCR_FULL_RANGE)
1030                 dvscntr |= DVS_YUV_RANGE_CORRECTION_DISABLE;
1031
1032         if (fb->modifier == I915_FORMAT_MOD_X_TILED)
1033                 dvscntr |= DVS_TILED;
1034
1035         if (rotation & DRM_MODE_ROTATE_180)
1036                 dvscntr |= DVS_ROTATE_180;
1037
1038         if (key->flags & I915_SET_COLORKEY_DESTINATION)
1039                 dvscntr |= DVS_DEST_KEY;
1040         else if (key->flags & I915_SET_COLORKEY_SOURCE)
1041                 dvscntr |= DVS_SOURCE_KEY;
1042
1043         return dvscntr;
1044 }
1045
1046 static void g4x_sprite_update_gamma(const struct intel_plane_state *plane_state)
1047 {
1048         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1049         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1050         const struct drm_framebuffer *fb = plane_state->hw.fb;
1051         enum pipe pipe = plane->pipe;
1052         u16 gamma[8];
1053         int i;
1054
1055         /* Seems RGB data bypasses the gamma always */
1056         if (!fb->format->is_yuv)
1057                 return;
1058
1059         i9xx_plane_linear_gamma(gamma);
1060
1061         /* FIXME these register are single buffered :( */
1062         /* The two end points are implicit (0.0 and 1.0) */
1063         for (i = 1; i < 8 - 1; i++)
1064                 intel_de_write_fw(dev_priv, DVSGAMC_G4X(pipe, i - 1),
1065                                   gamma[i] << 16 | gamma[i] << 8 | gamma[i]);
1066 }
1067
1068 static void ilk_sprite_linear_gamma(u16 gamma[17])
1069 {
1070         int i;
1071
1072         for (i = 0; i < 17; i++)
1073                 gamma[i] = (i << 10) / 16;
1074 }
1075
1076 static void ilk_sprite_update_gamma(const struct intel_plane_state *plane_state)
1077 {
1078         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1079         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1080         const struct drm_framebuffer *fb = plane_state->hw.fb;
1081         enum pipe pipe = plane->pipe;
1082         u16 gamma[17];
1083         int i;
1084
1085         /* Seems RGB data bypasses the gamma always */
1086         if (!fb->format->is_yuv)
1087                 return;
1088
1089         ilk_sprite_linear_gamma(gamma);
1090
1091         /* FIXME these register are single buffered :( */
1092         for (i = 0; i < 16; i++)
1093                 intel_de_write_fw(dev_priv, DVSGAMC_ILK(pipe, i),
1094                                   gamma[i] << 20 | gamma[i] << 10 | gamma[i]);
1095
1096         intel_de_write_fw(dev_priv, DVSGAMCMAX_ILK(pipe, 0), gamma[i]);
1097         intel_de_write_fw(dev_priv, DVSGAMCMAX_ILK(pipe, 1), gamma[i]);
1098         intel_de_write_fw(dev_priv, DVSGAMCMAX_ILK(pipe, 2), gamma[i]);
1099         i++;
1100 }
1101
1102 static void
1103 g4x_sprite_update_noarm(struct intel_plane *plane,
1104                         const struct intel_crtc_state *crtc_state,
1105                         const struct intel_plane_state *plane_state)
1106 {
1107         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1108         enum pipe pipe = plane->pipe;
1109         int crtc_x = plane_state->uapi.dst.x1;
1110         int crtc_y = plane_state->uapi.dst.y1;
1111         u32 crtc_w = drm_rect_width(&plane_state->uapi.dst);
1112         u32 crtc_h = drm_rect_height(&plane_state->uapi.dst);
1113         u32 src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
1114         u32 src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
1115         u32 dvsscale = 0;
1116
1117         if (crtc_w != src_w || crtc_h != src_h)
1118                 dvsscale = DVS_SCALE_ENABLE |
1119                         DVS_SRC_WIDTH(src_w - 1) |
1120                         DVS_SRC_HEIGHT(src_h - 1);
1121
1122         intel_de_write_fw(dev_priv, DVSSTRIDE(pipe),
1123                           plane_state->view.color_plane[0].mapping_stride);
1124         intel_de_write_fw(dev_priv, DVSPOS(pipe),
1125                           DVS_POS_Y(crtc_y) | DVS_POS_X(crtc_x));
1126         intel_de_write_fw(dev_priv, DVSSIZE(pipe),
1127                           DVS_HEIGHT(crtc_h - 1) | DVS_WIDTH(crtc_w - 1));
1128         intel_de_write_fw(dev_priv, DVSSCALE(pipe), dvsscale);
1129 }
1130
1131 static void
1132 g4x_sprite_update_arm(struct intel_plane *plane,
1133                       const struct intel_crtc_state *crtc_state,
1134                       const struct intel_plane_state *plane_state)
1135 {
1136         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1137         enum pipe pipe = plane->pipe;
1138         const struct drm_intel_sprite_colorkey *key = &plane_state->ckey;
1139         u32 dvssurf_offset = plane_state->view.color_plane[0].offset;
1140         u32 x = plane_state->view.color_plane[0].x;
1141         u32 y = plane_state->view.color_plane[0].y;
1142         u32 dvscntr, linear_offset;
1143
1144         dvscntr = plane_state->ctl | g4x_sprite_ctl_crtc(crtc_state);
1145
1146         linear_offset = intel_fb_xy_to_linear(x, y, plane_state, 0);
1147
1148         if (key->flags) {
1149                 intel_de_write_fw(dev_priv, DVSKEYVAL(pipe), key->min_value);
1150                 intel_de_write_fw(dev_priv, DVSKEYMSK(pipe),
1151                                   key->channel_mask);
1152                 intel_de_write_fw(dev_priv, DVSKEYMAX(pipe), key->max_value);
1153         }
1154
1155         intel_de_write_fw(dev_priv, DVSLINOFF(pipe), linear_offset);
1156         intel_de_write_fw(dev_priv, DVSTILEOFF(pipe),
1157                           DVS_OFFSET_Y(y) | DVS_OFFSET_X(x));
1158
1159         /*
1160          * The control register self-arms if the plane was previously
1161          * disabled. Try to make the plane enable atomic by writing
1162          * the control register just before the surface register.
1163          */
1164         intel_de_write_fw(dev_priv, DVSCNTR(pipe), dvscntr);
1165         intel_de_write_fw(dev_priv, DVSSURF(pipe),
1166                           intel_plane_ggtt_offset(plane_state) + dvssurf_offset);
1167
1168         if (IS_G4X(dev_priv))
1169                 g4x_sprite_update_gamma(plane_state);
1170         else
1171                 ilk_sprite_update_gamma(plane_state);
1172 }
1173
1174 static void
1175 g4x_sprite_disable_arm(struct intel_plane *plane,
1176                        const struct intel_crtc_state *crtc_state)
1177 {
1178         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1179         enum pipe pipe = plane->pipe;
1180
1181         intel_de_write_fw(dev_priv, DVSCNTR(pipe), 0);
1182         /* Disable the scaler */
1183         intel_de_write_fw(dev_priv, DVSSCALE(pipe), 0);
1184         intel_de_write_fw(dev_priv, DVSSURF(pipe), 0);
1185 }
1186
1187 static bool
1188 g4x_sprite_get_hw_state(struct intel_plane *plane,
1189                         enum pipe *pipe)
1190 {
1191         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1192         enum intel_display_power_domain power_domain;
1193         intel_wakeref_t wakeref;
1194         bool ret;
1195
1196         power_domain = POWER_DOMAIN_PIPE(plane->pipe);
1197         wakeref = intel_display_power_get_if_enabled(dev_priv, power_domain);
1198         if (!wakeref)
1199                 return false;
1200
1201         ret = intel_de_read(dev_priv, DVSCNTR(plane->pipe)) & DVS_ENABLE;
1202
1203         *pipe = plane->pipe;
1204
1205         intel_display_power_put(dev_priv, power_domain, wakeref);
1206
1207         return ret;
1208 }
1209
1210 static bool g4x_fb_scalable(const struct drm_framebuffer *fb)
1211 {
1212         if (!fb)
1213                 return false;
1214
1215         switch (fb->format->format) {
1216         case DRM_FORMAT_C8:
1217         case DRM_FORMAT_XRGB16161616F:
1218         case DRM_FORMAT_ARGB16161616F:
1219         case DRM_FORMAT_XBGR16161616F:
1220         case DRM_FORMAT_ABGR16161616F:
1221                 return false;
1222         default:
1223                 return true;
1224         }
1225 }
1226
1227 static int
1228 g4x_sprite_check_scaling(struct intel_crtc_state *crtc_state,
1229                          struct intel_plane_state *plane_state)
1230 {
1231         struct drm_i915_private *i915 = to_i915(plane_state->uapi.plane->dev);
1232         const struct drm_framebuffer *fb = plane_state->hw.fb;
1233         const struct drm_rect *src = &plane_state->uapi.src;
1234         const struct drm_rect *dst = &plane_state->uapi.dst;
1235         int src_x, src_w, src_h, crtc_w, crtc_h;
1236         const struct drm_display_mode *adjusted_mode =
1237                 &crtc_state->hw.adjusted_mode;
1238         unsigned int stride = plane_state->view.color_plane[0].mapping_stride;
1239         unsigned int cpp = fb->format->cpp[0];
1240         unsigned int width_bytes;
1241         int min_width, min_height;
1242
1243         crtc_w = drm_rect_width(dst);
1244         crtc_h = drm_rect_height(dst);
1245
1246         src_x = src->x1 >> 16;
1247         src_w = drm_rect_width(src) >> 16;
1248         src_h = drm_rect_height(src) >> 16;
1249
1250         if (src_w == crtc_w && src_h == crtc_h)
1251                 return 0;
1252
1253         min_width = 3;
1254
1255         if (adjusted_mode->flags & DRM_MODE_FLAG_INTERLACE) {
1256                 if (src_h & 1) {
1257                         drm_dbg_kms(&i915->drm, "Source height must be even with interlaced modes\n");
1258                         return -EINVAL;
1259                 }
1260                 min_height = 6;
1261         } else {
1262                 min_height = 3;
1263         }
1264
1265         width_bytes = ((src_x * cpp) & 63) + src_w * cpp;
1266
1267         if (src_w < min_width || src_h < min_height ||
1268             src_w > 2048 || src_h > 2048) {
1269                 drm_dbg_kms(&i915->drm, "Source dimensions (%dx%d) exceed hardware limits (%dx%d - %dx%d)\n",
1270                             src_w, src_h, min_width, min_height, 2048, 2048);
1271                 return -EINVAL;
1272         }
1273
1274         if (width_bytes > 4096) {
1275                 drm_dbg_kms(&i915->drm, "Fetch width (%d) exceeds hardware max with scaling (%u)\n",
1276                             width_bytes, 4096);
1277                 return -EINVAL;
1278         }
1279
1280         if (stride > 4096) {
1281                 drm_dbg_kms(&i915->drm, "Stride (%u) exceeds hardware max with scaling (%u)\n",
1282                             stride, 4096);
1283                 return -EINVAL;
1284         }
1285
1286         return 0;
1287 }
1288
1289 static int
1290 g4x_sprite_check(struct intel_crtc_state *crtc_state,
1291                  struct intel_plane_state *plane_state)
1292 {
1293         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1294         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1295         int min_scale = DRM_PLANE_NO_SCALING;
1296         int max_scale = DRM_PLANE_NO_SCALING;
1297         int ret;
1298
1299         if (g4x_fb_scalable(plane_state->hw.fb)) {
1300                 if (DISPLAY_VER(dev_priv) < 7) {
1301                         min_scale = 1;
1302                         max_scale = 16 << 16;
1303                 } else if (IS_IVYBRIDGE(dev_priv)) {
1304                         min_scale = 1;
1305                         max_scale = 2 << 16;
1306                 }
1307         }
1308
1309         ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
1310                                                 min_scale, max_scale, true);
1311         if (ret)
1312                 return ret;
1313
1314         ret = i9xx_check_plane_surface(plane_state);
1315         if (ret)
1316                 return ret;
1317
1318         if (!plane_state->uapi.visible)
1319                 return 0;
1320
1321         ret = intel_plane_check_src_coordinates(plane_state);
1322         if (ret)
1323                 return ret;
1324
1325         ret = g4x_sprite_check_scaling(crtc_state, plane_state);
1326         if (ret)
1327                 return ret;
1328
1329         if (DISPLAY_VER(dev_priv) >= 7)
1330                 plane_state->ctl = ivb_sprite_ctl(crtc_state, plane_state);
1331         else
1332                 plane_state->ctl = g4x_sprite_ctl(crtc_state, plane_state);
1333
1334         return 0;
1335 }
1336
1337 int chv_plane_check_rotation(const struct intel_plane_state *plane_state)
1338 {
1339         struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1340         struct drm_i915_private *dev_priv = to_i915(plane->base.dev);
1341         unsigned int rotation = plane_state->hw.rotation;
1342
1343         /* CHV ignores the mirror bit when the rotate bit is set :( */
1344         if (IS_CHERRYVIEW(dev_priv) &&
1345             rotation & DRM_MODE_ROTATE_180 &&
1346             rotation & DRM_MODE_REFLECT_X) {
1347                 drm_dbg_kms(&dev_priv->drm,
1348                             "Cannot rotate and reflect at the same time\n");
1349                 return -EINVAL;
1350         }
1351
1352         return 0;
1353 }
1354
1355 static int
1356 vlv_sprite_check(struct intel_crtc_state *crtc_state,
1357                  struct intel_plane_state *plane_state)
1358 {
1359         int ret;
1360
1361         ret = chv_plane_check_rotation(plane_state);
1362         if (ret)
1363                 return ret;
1364
1365         ret = intel_atomic_plane_check_clipping(plane_state, crtc_state,
1366                                                 DRM_PLANE_NO_SCALING,
1367                                                 DRM_PLANE_NO_SCALING,
1368                                                 true);
1369         if (ret)
1370                 return ret;
1371
1372         ret = i9xx_check_plane_surface(plane_state);
1373         if (ret)
1374                 return ret;
1375
1376         if (!plane_state->uapi.visible)
1377                 return 0;
1378
1379         ret = intel_plane_check_src_coordinates(plane_state);
1380         if (ret)
1381                 return ret;
1382
1383         plane_state->ctl = vlv_sprite_ctl(crtc_state, plane_state);
1384
1385         return 0;
1386 }
1387
1388 static const u32 g4x_sprite_formats[] = {
1389         DRM_FORMAT_XRGB8888,
1390         DRM_FORMAT_YUYV,
1391         DRM_FORMAT_YVYU,
1392         DRM_FORMAT_UYVY,
1393         DRM_FORMAT_VYUY,
1394 };
1395
1396 static const u32 snb_sprite_formats[] = {
1397         DRM_FORMAT_XRGB8888,
1398         DRM_FORMAT_XBGR8888,
1399         DRM_FORMAT_XRGB2101010,
1400         DRM_FORMAT_XBGR2101010,
1401         DRM_FORMAT_XRGB16161616F,
1402         DRM_FORMAT_XBGR16161616F,
1403         DRM_FORMAT_YUYV,
1404         DRM_FORMAT_YVYU,
1405         DRM_FORMAT_UYVY,
1406         DRM_FORMAT_VYUY,
1407 };
1408
1409 static const u32 vlv_sprite_formats[] = {
1410         DRM_FORMAT_C8,
1411         DRM_FORMAT_RGB565,
1412         DRM_FORMAT_XRGB8888,
1413         DRM_FORMAT_XBGR8888,
1414         DRM_FORMAT_ARGB8888,
1415         DRM_FORMAT_ABGR8888,
1416         DRM_FORMAT_XBGR2101010,
1417         DRM_FORMAT_ABGR2101010,
1418         DRM_FORMAT_YUYV,
1419         DRM_FORMAT_YVYU,
1420         DRM_FORMAT_UYVY,
1421         DRM_FORMAT_VYUY,
1422 };
1423
1424 static const u32 chv_pipe_b_sprite_formats[] = {
1425         DRM_FORMAT_C8,
1426         DRM_FORMAT_RGB565,
1427         DRM_FORMAT_XRGB8888,
1428         DRM_FORMAT_XBGR8888,
1429         DRM_FORMAT_ARGB8888,
1430         DRM_FORMAT_ABGR8888,
1431         DRM_FORMAT_XRGB2101010,
1432         DRM_FORMAT_XBGR2101010,
1433         DRM_FORMAT_ARGB2101010,
1434         DRM_FORMAT_ABGR2101010,
1435         DRM_FORMAT_YUYV,
1436         DRM_FORMAT_YVYU,
1437         DRM_FORMAT_UYVY,
1438         DRM_FORMAT_VYUY,
1439 };
1440
1441 static bool g4x_sprite_format_mod_supported(struct drm_plane *_plane,
1442                                             u32 format, u64 modifier)
1443 {
1444         if (!intel_fb_plane_supports_modifier(to_intel_plane(_plane), modifier))
1445                 return false;
1446
1447         switch (format) {
1448         case DRM_FORMAT_XRGB8888:
1449         case DRM_FORMAT_YUYV:
1450         case DRM_FORMAT_YVYU:
1451         case DRM_FORMAT_UYVY:
1452         case DRM_FORMAT_VYUY:
1453                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
1454                     modifier == I915_FORMAT_MOD_X_TILED)
1455                         return true;
1456                 fallthrough;
1457         default:
1458                 return false;
1459         }
1460 }
1461
1462 static bool snb_sprite_format_mod_supported(struct drm_plane *_plane,
1463                                             u32 format, u64 modifier)
1464 {
1465         if (!intel_fb_plane_supports_modifier(to_intel_plane(_plane), modifier))
1466                 return false;
1467
1468         switch (format) {
1469         case DRM_FORMAT_XRGB8888:
1470         case DRM_FORMAT_XBGR8888:
1471         case DRM_FORMAT_XRGB2101010:
1472         case DRM_FORMAT_XBGR2101010:
1473         case DRM_FORMAT_XRGB16161616F:
1474         case DRM_FORMAT_XBGR16161616F:
1475         case DRM_FORMAT_YUYV:
1476         case DRM_FORMAT_YVYU:
1477         case DRM_FORMAT_UYVY:
1478         case DRM_FORMAT_VYUY:
1479                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
1480                     modifier == I915_FORMAT_MOD_X_TILED)
1481                         return true;
1482                 fallthrough;
1483         default:
1484                 return false;
1485         }
1486 }
1487
1488 static bool vlv_sprite_format_mod_supported(struct drm_plane *_plane,
1489                                             u32 format, u64 modifier)
1490 {
1491         if (!intel_fb_plane_supports_modifier(to_intel_plane(_plane), modifier))
1492                 return false;
1493
1494         switch (format) {
1495         case DRM_FORMAT_C8:
1496         case DRM_FORMAT_RGB565:
1497         case DRM_FORMAT_ABGR8888:
1498         case DRM_FORMAT_ARGB8888:
1499         case DRM_FORMAT_XBGR8888:
1500         case DRM_FORMAT_XRGB8888:
1501         case DRM_FORMAT_XBGR2101010:
1502         case DRM_FORMAT_ABGR2101010:
1503         case DRM_FORMAT_XRGB2101010:
1504         case DRM_FORMAT_ARGB2101010:
1505         case DRM_FORMAT_YUYV:
1506         case DRM_FORMAT_YVYU:
1507         case DRM_FORMAT_UYVY:
1508         case DRM_FORMAT_VYUY:
1509                 if (modifier == DRM_FORMAT_MOD_LINEAR ||
1510                     modifier == I915_FORMAT_MOD_X_TILED)
1511                         return true;
1512                 fallthrough;
1513         default:
1514                 return false;
1515         }
1516 }
1517
1518 static const struct drm_plane_funcs g4x_sprite_funcs = {
1519         .update_plane = drm_atomic_helper_update_plane,
1520         .disable_plane = drm_atomic_helper_disable_plane,
1521         .destroy = intel_plane_destroy,
1522         .atomic_duplicate_state = intel_plane_duplicate_state,
1523         .atomic_destroy_state = intel_plane_destroy_state,
1524         .format_mod_supported = g4x_sprite_format_mod_supported,
1525 };
1526
1527 static const struct drm_plane_funcs snb_sprite_funcs = {
1528         .update_plane = drm_atomic_helper_update_plane,
1529         .disable_plane = drm_atomic_helper_disable_plane,
1530         .destroy = intel_plane_destroy,
1531         .atomic_duplicate_state = intel_plane_duplicate_state,
1532         .atomic_destroy_state = intel_plane_destroy_state,
1533         .format_mod_supported = snb_sprite_format_mod_supported,
1534 };
1535
1536 static const struct drm_plane_funcs vlv_sprite_funcs = {
1537         .update_plane = drm_atomic_helper_update_plane,
1538         .disable_plane = drm_atomic_helper_disable_plane,
1539         .destroy = intel_plane_destroy,
1540         .atomic_duplicate_state = intel_plane_duplicate_state,
1541         .atomic_destroy_state = intel_plane_destroy_state,
1542         .format_mod_supported = vlv_sprite_format_mod_supported,
1543 };
1544
1545 struct intel_plane *
1546 intel_sprite_plane_create(struct drm_i915_private *dev_priv,
1547                           enum pipe pipe, int sprite)
1548 {
1549         struct intel_plane *plane;
1550         const struct drm_plane_funcs *plane_funcs;
1551         unsigned int supported_rotations;
1552         const u64 *modifiers;
1553         const u32 *formats;
1554         int num_formats;
1555         int ret, zpos;
1556
1557         plane = intel_plane_alloc();
1558         if (IS_ERR(plane))
1559                 return plane;
1560
1561         if (IS_VALLEYVIEW(dev_priv) || IS_CHERRYVIEW(dev_priv)) {
1562                 plane->update_noarm = vlv_sprite_update_noarm;
1563                 plane->update_arm = vlv_sprite_update_arm;
1564                 plane->disable_arm = vlv_sprite_disable_arm;
1565                 plane->get_hw_state = vlv_sprite_get_hw_state;
1566                 plane->check_plane = vlv_sprite_check;
1567                 plane->max_stride = i965_plane_max_stride;
1568                 plane->min_cdclk = vlv_plane_min_cdclk;
1569
1570                 if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
1571                         formats = chv_pipe_b_sprite_formats;
1572                         num_formats = ARRAY_SIZE(chv_pipe_b_sprite_formats);
1573                 } else {
1574                         formats = vlv_sprite_formats;
1575                         num_formats = ARRAY_SIZE(vlv_sprite_formats);
1576                 }
1577
1578                 plane_funcs = &vlv_sprite_funcs;
1579         } else if (DISPLAY_VER(dev_priv) >= 7) {
1580                 plane->update_noarm = ivb_sprite_update_noarm;
1581                 plane->update_arm = ivb_sprite_update_arm;
1582                 plane->disable_arm = ivb_sprite_disable_arm;
1583                 plane->get_hw_state = ivb_sprite_get_hw_state;
1584                 plane->check_plane = g4x_sprite_check;
1585
1586                 if (IS_BROADWELL(dev_priv) || IS_HASWELL(dev_priv)) {
1587                         plane->max_stride = hsw_sprite_max_stride;
1588                         plane->min_cdclk = hsw_plane_min_cdclk;
1589                 } else {
1590                         plane->max_stride = g4x_sprite_max_stride;
1591                         plane->min_cdclk = ivb_sprite_min_cdclk;
1592                 }
1593
1594                 formats = snb_sprite_formats;
1595                 num_formats = ARRAY_SIZE(snb_sprite_formats);
1596
1597                 plane_funcs = &snb_sprite_funcs;
1598         } else {
1599                 plane->update_noarm = g4x_sprite_update_noarm;
1600                 plane->update_arm = g4x_sprite_update_arm;
1601                 plane->disable_arm = g4x_sprite_disable_arm;
1602                 plane->get_hw_state = g4x_sprite_get_hw_state;
1603                 plane->check_plane = g4x_sprite_check;
1604                 plane->max_stride = g4x_sprite_max_stride;
1605                 plane->min_cdclk = g4x_sprite_min_cdclk;
1606
1607                 if (IS_SANDYBRIDGE(dev_priv)) {
1608                         formats = snb_sprite_formats;
1609                         num_formats = ARRAY_SIZE(snb_sprite_formats);
1610
1611                         plane_funcs = &snb_sprite_funcs;
1612                 } else {
1613                         formats = g4x_sprite_formats;
1614                         num_formats = ARRAY_SIZE(g4x_sprite_formats);
1615
1616                         plane_funcs = &g4x_sprite_funcs;
1617                 }
1618         }
1619
1620         if (IS_CHERRYVIEW(dev_priv) && pipe == PIPE_B) {
1621                 supported_rotations =
1622                         DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180 |
1623                         DRM_MODE_REFLECT_X;
1624         } else {
1625                 supported_rotations =
1626                         DRM_MODE_ROTATE_0 | DRM_MODE_ROTATE_180;
1627         }
1628
1629         plane->pipe = pipe;
1630         plane->id = PLANE_SPRITE0 + sprite;
1631         plane->frontbuffer_bit = INTEL_FRONTBUFFER(pipe, plane->id);
1632
1633         modifiers = intel_fb_plane_get_modifiers(dev_priv, INTEL_PLANE_CAP_TILING_X);
1634
1635         ret = drm_universal_plane_init(&dev_priv->drm, &plane->base,
1636                                        0, plane_funcs,
1637                                        formats, num_formats, modifiers,
1638                                        DRM_PLANE_TYPE_OVERLAY,
1639                                        "sprite %c", sprite_name(pipe, sprite));
1640         kfree(modifiers);
1641
1642         if (ret)
1643                 goto fail;
1644
1645         drm_plane_create_rotation_property(&plane->base,
1646                                            DRM_MODE_ROTATE_0,
1647                                            supported_rotations);
1648
1649         drm_plane_create_color_properties(&plane->base,
1650                                           BIT(DRM_COLOR_YCBCR_BT601) |
1651                                           BIT(DRM_COLOR_YCBCR_BT709),
1652                                           BIT(DRM_COLOR_YCBCR_LIMITED_RANGE) |
1653                                           BIT(DRM_COLOR_YCBCR_FULL_RANGE),
1654                                           DRM_COLOR_YCBCR_BT709,
1655                                           DRM_COLOR_YCBCR_LIMITED_RANGE);
1656
1657         zpos = sprite + 1;
1658         drm_plane_create_zpos_immutable_property(&plane->base, zpos);
1659
1660         intel_plane_helper_add(plane);
1661
1662         return plane;
1663
1664 fail:
1665         intel_plane_free(plane);
1666
1667         return ERR_PTR(ret);
1668 }
This page took 0.132799 seconds and 4 git commands to generate.