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