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