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