1 /*
2 * Copyright © 2014 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
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 /**
25 * DOC: atomic plane helpers
26 *
27 * The functions here are used by the atomic plane helper functions to
28 * implement legacy plane updates (i.e., drm_plane->update_plane() and
29 * drm_plane->disable_plane()). This allows plane updates to use the
30 * atomic state infrastructure and perform plane updates as separate
31 * prepare/check/commit/cleanup steps.
32 */
33
34 #include <linux/dma-fence-chain.h>
35 #include <linux/dma-resv.h>
36 #include <linux/iosys-map.h>
37
38 #include <drm/drm_atomic_helper.h>
39 #include <drm/drm_blend.h>
40 #include <drm/drm_cache.h>
41 #include <drm/drm_damage_helper.h>
42 #include <drm/drm_fourcc.h>
43 #include <drm/drm_gem.h>
44 #include <drm/drm_gem_atomic_helper.h>
45 #include <drm/drm_panic.h>
46 #include <drm/drm_print.h>
47
48 #include "i9xx_plane_regs.h"
49 #include "intel_cdclk.h"
50 #include "intel_cursor.h"
51 #include "intel_colorop.h"
52 #include "intel_display_rps.h"
53 #include "intel_display_trace.h"
54 #include "intel_display_types.h"
55 #include "intel_fb.h"
56 #include "intel_fb_pin.h"
57 #include "intel_fbdev.h"
58 #include "intel_parent.h"
59 #include "intel_plane.h"
60 #include "intel_psr.h"
61 #include "skl_scaler.h"
62 #include "skl_universal_plane.h"
63 #include "skl_watermark.h"
64
intel_plane_state_reset(struct intel_plane_state * plane_state,struct intel_plane * plane)65 static void intel_plane_state_reset(struct intel_plane_state *plane_state,
66 struct intel_plane *plane)
67 {
68 memset(plane_state, 0, sizeof(*plane_state));
69
70 __drm_atomic_helper_plane_state_reset(&plane_state->uapi, &plane->base);
71
72 plane_state->scaler_id = -1;
73 }
74
intel_plane_alloc(void)75 struct intel_plane *intel_plane_alloc(void)
76 {
77 struct intel_plane_state *plane_state;
78 struct intel_plane *plane;
79
80 plane = kzalloc_obj(*plane);
81 if (!plane)
82 return ERR_PTR(-ENOMEM);
83
84 plane_state = kzalloc_obj(*plane_state);
85 if (!plane_state) {
86 kfree(plane);
87 return ERR_PTR(-ENOMEM);
88 }
89
90 intel_plane_state_reset(plane_state, plane);
91
92 plane->base.state = &plane_state->uapi;
93
94 return plane;
95 }
96
intel_plane_free(struct intel_plane * plane)97 void intel_plane_free(struct intel_plane *plane)
98 {
99 intel_plane_destroy_state(&plane->base, plane->base.state);
100 kfree(plane);
101 }
102
103 /**
104 * intel_plane_destroy - destroy a plane
105 * @plane: plane to destroy
106 *
107 * Common destruction function for all types of planes (primary, cursor,
108 * sprite).
109 */
intel_plane_destroy(struct drm_plane * plane)110 void intel_plane_destroy(struct drm_plane *plane)
111 {
112 drm_plane_cleanup(plane);
113 kfree(to_intel_plane(plane));
114 }
115
116 /**
117 * intel_plane_duplicate_state - duplicate plane state
118 * @plane: drm plane
119 *
120 * Allocates and returns a copy of the plane state (both common and
121 * Intel-specific) for the specified plane.
122 *
123 * Returns: The newly allocated plane state, or NULL on failure.
124 */
125 struct drm_plane_state *
intel_plane_duplicate_state(struct drm_plane * plane)126 intel_plane_duplicate_state(struct drm_plane *plane)
127 {
128 struct intel_plane_state *intel_state;
129
130 intel_state = to_intel_plane_state(plane->state);
131 intel_state = kmemdup(intel_state, sizeof(*intel_state), GFP_KERNEL);
132
133 if (!intel_state)
134 return NULL;
135
136 __drm_atomic_helper_plane_duplicate_state(plane, &intel_state->uapi);
137
138 intel_state->ggtt_vma = NULL;
139 intel_state->dpt_vma = NULL;
140 intel_state->flags = 0;
141 intel_state->damage = DRM_RECT_INIT(0, 0, 0, 0);
142
143 /* add reference to fb */
144 if (intel_state->hw.fb)
145 drm_framebuffer_get(intel_state->hw.fb);
146
147 if (intel_state->hw.degamma_lut)
148 drm_property_blob_get(intel_state->hw.degamma_lut);
149 if (intel_state->hw.gamma_lut)
150 drm_property_blob_get(intel_state->hw.gamma_lut);
151 if (intel_state->hw.ctm)
152 drm_property_blob_get(intel_state->hw.ctm);
153 if (intel_state->hw.lut_3d)
154 drm_property_blob_get(intel_state->hw.lut_3d);
155
156 return &intel_state->uapi;
157 }
158
159 /**
160 * intel_plane_destroy_state - destroy plane state
161 * @plane: drm plane
162 * @state: state object to destroy
163 *
164 * Destroys the plane state (both common and Intel-specific) for the
165 * specified plane.
166 */
167 void
intel_plane_destroy_state(struct drm_plane * plane,struct drm_plane_state * state)168 intel_plane_destroy_state(struct drm_plane *plane,
169 struct drm_plane_state *state)
170 {
171 struct intel_plane_state *plane_state = to_intel_plane_state(state);
172
173 drm_WARN_ON(plane->dev, plane_state->ggtt_vma);
174 drm_WARN_ON(plane->dev, plane_state->dpt_vma);
175
176 __drm_atomic_helper_plane_destroy_state(&plane_state->uapi);
177 if (plane_state->hw.fb)
178 drm_framebuffer_put(plane_state->hw.fb);
179
180 if (plane_state->hw.degamma_lut)
181 drm_property_blob_put(plane_state->hw.degamma_lut);
182 if (plane_state->hw.gamma_lut)
183 drm_property_blob_put(plane_state->hw.gamma_lut);
184 if (plane_state->hw.ctm)
185 drm_property_blob_put(plane_state->hw.ctm);
186 if (plane_state->hw.lut_3d)
187 drm_property_blob_put(plane_state->hw.lut_3d);
188
189 kfree(plane_state);
190 }
191
intel_plane_needs_physical(struct intel_plane * plane)192 bool intel_plane_needs_physical(struct intel_plane *plane)
193 {
194 struct intel_display *display = to_intel_display(plane);
195
196 return plane->id == PLANE_CURSOR &&
197 DISPLAY_INFO(display)->cursor_needs_physical;
198 }
199
intel_plane_can_async_flip(struct intel_plane * plane,const struct drm_format_info * info,u64 modifier)200 bool intel_plane_can_async_flip(struct intel_plane *plane,
201 const struct drm_format_info *info,
202 u64 modifier)
203 {
204 if (intel_format_info_is_yuv_semiplanar(info, modifier) ||
205 info->format == DRM_FORMAT_C8)
206 return false;
207
208 return plane->can_async_flip && plane->can_async_flip(modifier);
209 }
210
intel_plane_format_mod_supported_async(struct drm_plane * _plane,u32 format,u64 modifier)211 bool intel_plane_format_mod_supported_async(struct drm_plane *_plane,
212 u32 format, u64 modifier)
213 {
214 struct intel_plane *plane = to_intel_plane(_plane);
215 const struct drm_format_info *info;
216
217 if (!plane->base.funcs->format_mod_supported(&plane->base, format, modifier))
218 return false;
219
220 info = drm_get_format_info(plane->base.dev, format, modifier);
221
222 return intel_plane_can_async_flip(plane, info, modifier);
223 }
224
intel_adjusted_rate(const struct drm_rect * src,const struct drm_rect * dst,unsigned int rate)225 unsigned int intel_adjusted_rate(const struct drm_rect *src,
226 const struct drm_rect *dst,
227 unsigned int rate)
228 {
229 unsigned int src_w, src_h, dst_w, dst_h;
230
231 src_w = drm_rect_width(src) >> 16;
232 src_h = drm_rect_height(src) >> 16;
233 dst_w = drm_rect_width(dst);
234 dst_h = drm_rect_height(dst);
235
236 /* Downscaling limits the maximum pixel rate */
237 dst_w = min(src_w, dst_w);
238 dst_h = min(src_h, dst_h);
239
240 return DIV_ROUND_UP_ULL(mul_u32_u32(rate, src_w * src_h),
241 dst_w * dst_h);
242 }
243
intel_plane_pixel_rate(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)244 unsigned int intel_plane_pixel_rate(const struct intel_crtc_state *crtc_state,
245 const struct intel_plane_state *plane_state)
246 {
247 /*
248 * Note we don't check for plane visibility here as
249 * we want to use this when calculating the cursor
250 * watermarks even if the cursor is fully offscreen.
251 * That depends on the src/dst rectangles being
252 * correctly populated whenever the watermark code
253 * considers the cursor to be visible, whether or not
254 * it is actually visible.
255 *
256 * See: intel_wm_plane_visible() and intel_check_cursor()
257 */
258
259 return intel_adjusted_rate(&plane_state->uapi.src,
260 &plane_state->uapi.dst,
261 crtc_state->pixel_rate);
262 }
263
intel_plane_data_rate(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state,int color_plane)264 unsigned int intel_plane_data_rate(const struct intel_crtc_state *crtc_state,
265 const struct intel_plane_state *plane_state,
266 int color_plane)
267 {
268 const struct drm_framebuffer *fb = plane_state->hw.fb;
269
270 if (!plane_state->uapi.visible)
271 return 0;
272
273 return intel_plane_pixel_rate(crtc_state, plane_state) *
274 fb->format->cpp[color_plane];
275 }
276
277 static unsigned int
intel_plane_relative_data_rate(const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state,int color_plane)278 intel_plane_relative_data_rate(const struct intel_crtc_state *crtc_state,
279 const struct intel_plane_state *plane_state,
280 int color_plane)
281 {
282 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
283 const struct drm_framebuffer *fb = plane_state->hw.fb;
284 unsigned int rel_data_rate;
285 int width, height;
286
287 if (plane->id == PLANE_CURSOR)
288 return 0;
289
290 if (!plane_state->uapi.visible)
291 return 0;
292
293 /*
294 * Src coordinates are already rotated by 270 degrees for
295 * the 90/270 degree plane rotation cases (to match the
296 * GTT mapping), hence no need to account for rotation here.
297 */
298 width = drm_rect_width(&plane_state->uapi.src) >> 16;
299 height = drm_rect_height(&plane_state->uapi.src) >> 16;
300
301 /* UV plane does 1/2 pixel sub-sampling */
302 if (color_plane == 1) {
303 width /= 2;
304 height /= 2;
305 }
306
307 rel_data_rate =
308 skl_plane_relative_data_rate(crtc_state, plane, width, height,
309 fb->format->cpp[color_plane]);
310 if (!rel_data_rate)
311 return 0;
312
313 return intel_adjusted_rate(&plane_state->uapi.src,
314 &plane_state->uapi.dst,
315 rel_data_rate);
316 }
317
intel_plane_calc_min_cdclk(struct intel_atomic_state * state,struct intel_plane * plane)318 static void intel_plane_calc_min_cdclk(struct intel_atomic_state *state,
319 struct intel_plane *plane)
320 {
321 const struct intel_plane_state *plane_state =
322 intel_atomic_get_new_plane_state(state, plane);
323 struct intel_crtc *crtc = to_intel_crtc(plane_state->hw.crtc);
324 struct intel_crtc_state *new_crtc_state;
325
326 if (!plane_state->uapi.visible || !plane->min_cdclk)
327 return;
328
329 new_crtc_state = intel_atomic_get_new_crtc_state(state, crtc);
330
331 new_crtc_state->plane_min_cdclk[plane->id] =
332 plane->min_cdclk(new_crtc_state, plane_state);
333 }
334
intel_plane_clear_hw_state(struct intel_plane_state * plane_state)335 static void intel_plane_clear_hw_state(struct intel_plane_state *plane_state)
336 {
337 if (plane_state->hw.fb)
338 drm_framebuffer_put(plane_state->hw.fb);
339 if (plane_state->hw.degamma_lut)
340 drm_property_blob_put(plane_state->hw.degamma_lut);
341 if (plane_state->hw.gamma_lut)
342 drm_property_blob_put(plane_state->hw.gamma_lut);
343 if (plane_state->hw.ctm)
344 drm_property_blob_put(plane_state->hw.ctm);
345 if (plane_state->hw.lut_3d)
346 drm_property_blob_put(plane_state->hw.lut_3d);
347
348 memset(&plane_state->hw, 0, sizeof(plane_state->hw));
349 }
350
351 static void
intel_plane_copy_uapi_plane_damage(struct intel_plane_state * new_plane_state,const struct intel_plane_state * old_uapi_plane_state,const struct intel_plane_state * new_uapi_plane_state)352 intel_plane_copy_uapi_plane_damage(struct intel_plane_state *new_plane_state,
353 const struct intel_plane_state *old_uapi_plane_state,
354 const struct intel_plane_state *new_uapi_plane_state)
355 {
356 struct intel_display *display = to_intel_display(new_plane_state);
357 struct drm_rect *damage = &new_plane_state->damage;
358
359 /* damage property tracking enabled from display version 12 onwards */
360 if (DISPLAY_VER(display) < 12)
361 return;
362
363 if (!drm_atomic_helper_damage_merged(&old_uapi_plane_state->uapi,
364 &new_uapi_plane_state->uapi,
365 damage))
366 /* Incase helper fails, mark whole plane region as damage */
367 *damage = drm_plane_state_src(&new_uapi_plane_state->uapi);
368 }
369
370 static bool
intel_plane_colorop_replace_blob(struct intel_plane_state * plane_state,struct intel_colorop * intel_colorop,struct drm_property_blob * blob)371 intel_plane_colorop_replace_blob(struct intel_plane_state *plane_state,
372 struct intel_colorop *intel_colorop,
373 struct drm_property_blob *blob)
374 {
375 if (intel_colorop->id == INTEL_PLANE_CB_CSC)
376 return drm_property_replace_blob(&plane_state->hw.ctm, blob);
377 else if (intel_colorop->id == INTEL_PLANE_CB_PRE_CSC_LUT)
378 return drm_property_replace_blob(&plane_state->hw.degamma_lut, blob);
379 else if (intel_colorop->id == INTEL_PLANE_CB_POST_CSC_LUT)
380 return drm_property_replace_blob(&plane_state->hw.gamma_lut, blob);
381 else if (intel_colorop->id == INTEL_PLANE_CB_3DLUT)
382 return drm_property_replace_blob(&plane_state->hw.lut_3d, blob);
383
384 return false;
385 }
386
387 static void
intel_plane_color_copy_uapi_to_hw_state(struct intel_plane_state * plane_state,const struct intel_plane_state * from_plane_state,struct intel_crtc * crtc)388 intel_plane_color_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
389 const struct intel_plane_state *from_plane_state,
390 struct intel_crtc *crtc)
391 {
392 struct drm_colorop *iter_colorop, *colorop;
393 struct drm_colorop_state *new_colorop_state;
394 struct drm_atomic_state *state = plane_state->uapi.state;
395 struct intel_colorop *intel_colorop;
396 struct drm_property_blob *blob;
397 struct intel_atomic_state *intel_atomic_state = to_intel_atomic_state(state);
398 struct intel_crtc_state *new_crtc_state = intel_atomic_state ?
399 intel_atomic_get_new_crtc_state(intel_atomic_state, crtc) : NULL;
400 bool changed = false;
401 int i = 0;
402
403 iter_colorop = from_plane_state->uapi.color_pipeline;
404
405 while (iter_colorop) {
406 for_each_new_colorop_in_state(state, colorop, new_colorop_state, i) {
407 if (new_colorop_state->colorop == iter_colorop) {
408 blob = new_colorop_state->bypass ? NULL : new_colorop_state->data;
409 intel_colorop = to_intel_colorop(colorop);
410 changed |= intel_plane_colorop_replace_blob(plane_state,
411 intel_colorop,
412 blob);
413 }
414 }
415 iter_colorop = iter_colorop->next;
416 }
417
418 if (new_crtc_state && changed)
419 new_crtc_state->plane_color_changed = true;
420 }
421
intel_plane_copy_uapi_to_hw_state(struct intel_plane_state * plane_state,const struct intel_plane_state * from_plane_state,struct intel_crtc * crtc)422 void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state *plane_state,
423 const struct intel_plane_state *from_plane_state,
424 struct intel_crtc *crtc)
425 {
426 intel_plane_clear_hw_state(plane_state);
427
428 /*
429 * For the joiner secondary uapi.crtc will point at
430 * the primary crtc. So we explicitly assign the right
431 * secondary crtc to hw.crtc. uapi.crtc!=NULL simply
432 * indicates the plane is logically enabled on the uapi level.
433 */
434 plane_state->hw.crtc = from_plane_state->uapi.crtc ? &crtc->base : NULL;
435
436 plane_state->hw.fb = from_plane_state->uapi.fb;
437 if (plane_state->hw.fb)
438 drm_framebuffer_get(plane_state->hw.fb);
439
440 plane_state->hw.alpha = from_plane_state->uapi.alpha;
441 plane_state->hw.pixel_blend_mode =
442 from_plane_state->uapi.pixel_blend_mode;
443 plane_state->hw.rotation = from_plane_state->uapi.rotation;
444 plane_state->hw.color_encoding = from_plane_state->uapi.color_encoding;
445 plane_state->hw.color_range = from_plane_state->uapi.color_range;
446 plane_state->hw.scaling_filter = from_plane_state->uapi.scaling_filter;
447
448 plane_state->uapi.src = drm_plane_state_src(&from_plane_state->uapi);
449 plane_state->uapi.dst = drm_plane_state_dest(&from_plane_state->uapi);
450
451 intel_plane_color_copy_uapi_to_hw_state(plane_state, from_plane_state, crtc);
452 }
453
intel_plane_copy_hw_state(struct intel_plane_state * plane_state,const struct intel_plane_state * from_plane_state)454 void intel_plane_copy_hw_state(struct intel_plane_state *plane_state,
455 const struct intel_plane_state *from_plane_state)
456 {
457 intel_plane_clear_hw_state(plane_state);
458
459 memcpy(&plane_state->hw, &from_plane_state->hw,
460 sizeof(plane_state->hw));
461
462 if (plane_state->hw.fb)
463 drm_framebuffer_get(plane_state->hw.fb);
464 }
465
unlink_nv12_plane(struct intel_crtc_state * crtc_state,struct intel_plane_state * plane_state)466 static void unlink_nv12_plane(struct intel_crtc_state *crtc_state,
467 struct intel_plane_state *plane_state)
468 {
469 struct intel_display *display = to_intel_display(plane_state);
470 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
471
472 if (!plane_state->planar_linked_plane)
473 return;
474
475 plane_state->planar_linked_plane = NULL;
476
477 if (!plane_state->is_y_plane)
478 return;
479
480 drm_WARN_ON(display->drm, plane_state->uapi.visible);
481
482 plane_state->is_y_plane = false;
483
484 crtc_state->enabled_planes &= ~BIT(plane->id);
485 crtc_state->active_planes &= ~BIT(plane->id);
486 crtc_state->update_planes |= BIT(plane->id);
487 crtc_state->data_rate[plane->id] = 0;
488 crtc_state->rel_data_rate[plane->id] = 0;
489 }
490
intel_plane_set_invisible(struct intel_crtc_state * crtc_state,struct intel_plane_state * plane_state)491 void intel_plane_set_invisible(struct intel_crtc_state *crtc_state,
492 struct intel_plane_state *plane_state)
493 {
494 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
495
496 unlink_nv12_plane(crtc_state, plane_state);
497
498 crtc_state->active_planes &= ~BIT(plane->id);
499 crtc_state->scaled_planes &= ~BIT(plane->id);
500 crtc_state->nv12_planes &= ~BIT(plane->id);
501 crtc_state->c8_planes &= ~BIT(plane->id);
502 crtc_state->async_flip_planes &= ~BIT(plane->id);
503 crtc_state->data_rate[plane->id] = 0;
504 crtc_state->data_rate_y[plane->id] = 0;
505 crtc_state->rel_data_rate[plane->id] = 0;
506 crtc_state->rel_data_rate_y[plane->id] = 0;
507 crtc_state->plane_min_cdclk[plane->id] = 0;
508
509 plane_state->uapi.visible = false;
510 }
511
intel_plane_is_scaled(const struct intel_plane_state * plane_state)512 static bool intel_plane_is_scaled(const struct intel_plane_state *plane_state)
513 {
514 int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
515 int src_h = drm_rect_height(&plane_state->uapi.src) >> 16;
516 int dst_w = drm_rect_width(&plane_state->uapi.dst);
517 int dst_h = drm_rect_height(&plane_state->uapi.dst);
518
519 return src_w != dst_w || src_h != dst_h;
520 }
521
intel_plane_do_async_flip(struct intel_plane * plane,const struct intel_crtc_state * old_crtc_state,const struct intel_crtc_state * new_crtc_state)522 static bool intel_plane_do_async_flip(struct intel_plane *plane,
523 const struct intel_crtc_state *old_crtc_state,
524 const struct intel_crtc_state *new_crtc_state)
525 {
526 struct intel_display *display = to_intel_display(plane);
527
528 if (!plane->async_flip)
529 return false;
530
531 if (!new_crtc_state->uapi.async_flip)
532 return false;
533
534 /*
535 * In platforms after DISPLAY13, we might need to override
536 * first async flip in order to change watermark levels
537 * as part of optimization.
538 *
539 * And let's do this for all skl+ so that we can eg. change the
540 * modifier as well.
541 *
542 * TODO: For older platforms there is less reason to do this as
543 * only X-tile is supported with async flips, though we could
544 * extend this so other scanout parameters (stride/etc) could
545 * be changed as well...
546 */
547 return DISPLAY_VER(display) < 9 || old_crtc_state->uapi.async_flip;
548 }
549
i9xx_must_disable_cxsr(const struct intel_crtc_state * new_crtc_state,const struct intel_plane_state * old_plane_state,const struct intel_plane_state * new_plane_state)550 static bool i9xx_must_disable_cxsr(const struct intel_crtc_state *new_crtc_state,
551 const struct intel_plane_state *old_plane_state,
552 const struct intel_plane_state *new_plane_state)
553 {
554 struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane);
555 bool old_visible = old_plane_state->uapi.visible;
556 bool new_visible = new_plane_state->uapi.visible;
557 u32 old_ctl = old_plane_state->ctl;
558 u32 new_ctl = new_plane_state->ctl;
559 bool modeset, turn_on, turn_off;
560
561 if (plane->id == PLANE_CURSOR)
562 return false;
563
564 modeset = intel_crtc_needs_modeset(new_crtc_state);
565 turn_off = old_visible && (!new_visible || modeset);
566 turn_on = new_visible && (!old_visible || modeset);
567
568 /* Must disable CxSR around plane enable/disable */
569 if (turn_on || turn_off)
570 return true;
571
572 if (!old_visible || !new_visible)
573 return false;
574
575 /*
576 * Most plane control register updates are blocked while in CxSR.
577 *
578 * Tiling mode is one exception where the primary plane can
579 * apparently handle it, whereas the sprites can not (the
580 * sprite issue being only relevant on VLV/CHV where CxSR
581 * is actually possible with a sprite enabled).
582 */
583 if (plane->id == PLANE_PRIMARY) {
584 old_ctl &= ~DISP_TILED;
585 new_ctl &= ~DISP_TILED;
586 }
587
588 return old_ctl != new_ctl;
589 }
590
ilk_must_disable_cxsr(const struct intel_crtc_state * new_crtc_state,const struct intel_plane_state * old_plane_state,const struct intel_plane_state * new_plane_state)591 static bool ilk_must_disable_cxsr(const struct intel_crtc_state *new_crtc_state,
592 const struct intel_plane_state *old_plane_state,
593 const struct intel_plane_state *new_plane_state)
594 {
595 struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane);
596 bool old_visible = old_plane_state->uapi.visible;
597 bool new_visible = new_plane_state->uapi.visible;
598 bool modeset, turn_on;
599
600 if (plane->id == PLANE_CURSOR)
601 return false;
602
603 modeset = intel_crtc_needs_modeset(new_crtc_state);
604 turn_on = new_visible && (!old_visible || modeset);
605
606 /*
607 * ILK/SNB DVSACNTR/Sprite Enable
608 * IVB SPR_CTL/Sprite Enable
609 * "When in Self Refresh Big FIFO mode, a write to enable the
610 * plane will be internally buffered and delayed while Big FIFO
611 * mode is exiting."
612 *
613 * Which means that enabling the sprite can take an extra frame
614 * when we start in big FIFO mode (LP1+). Thus we need to drop
615 * down to LP0 and wait for vblank in order to make sure the
616 * sprite gets enabled on the next vblank after the register write.
617 * Doing otherwise would risk enabling the sprite one frame after
618 * we've already signalled flip completion. We can resume LP1+
619 * once the sprite has been enabled.
620 *
621 * With experimental results seems this is needed also for primary
622 * plane, not only sprite plane.
623 */
624 if (turn_on)
625 return true;
626
627 /*
628 * WaCxSRDisabledForSpriteScaling:ivb
629 * IVB SPR_SCALE/Scaling Enable
630 * "Low Power watermarks must be disabled for at least one
631 * frame before enabling sprite scaling, and kept disabled
632 * until sprite scaling is disabled."
633 *
634 * ILK/SNB DVSASCALE/Scaling Enable
635 * "When in Self Refresh Big FIFO mode, scaling enable will be
636 * masked off while Big FIFO mode is exiting."
637 *
638 * Despite the w/a only being listed for IVB we assume that
639 * the ILK/SNB note has similar ramifications, hence we apply
640 * the w/a on all three platforms.
641 */
642 return !intel_plane_is_scaled(old_plane_state) &&
643 intel_plane_is_scaled(new_plane_state);
644 }
645
intel_plane_atomic_calc_changes(const struct intel_crtc_state * old_crtc_state,struct intel_crtc_state * new_crtc_state,const struct intel_plane_state * old_plane_state,struct intel_plane_state * new_plane_state)646 static int intel_plane_atomic_calc_changes(const struct intel_crtc_state *old_crtc_state,
647 struct intel_crtc_state *new_crtc_state,
648 const struct intel_plane_state *old_plane_state,
649 struct intel_plane_state *new_plane_state)
650 {
651 struct intel_display *display = to_intel_display(new_crtc_state);
652 struct intel_crtc *crtc = to_intel_crtc(new_crtc_state->uapi.crtc);
653 struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane);
654 bool mode_changed = intel_crtc_needs_modeset(new_crtc_state);
655 bool was_crtc_enabled = old_crtc_state->hw.active;
656 bool is_crtc_enabled = new_crtc_state->hw.active;
657 bool turn_off, turn_on, visible, was_visible;
658 int ret;
659
660 if (DISPLAY_VER(display) >= 9 && plane->id != PLANE_CURSOR) {
661 ret = skl_update_scaler_plane(new_crtc_state, new_plane_state);
662 if (ret)
663 return ret;
664 }
665
666 was_visible = old_plane_state->uapi.visible;
667 visible = new_plane_state->uapi.visible;
668
669 if (!was_crtc_enabled && drm_WARN_ON(display->drm, was_visible))
670 was_visible = false;
671
672 /*
673 * Visibility is calculated as if the crtc was on, but
674 * after scaler setup everything depends on it being off
675 * when the crtc isn't active.
676 *
677 * FIXME this is wrong for watermarks. Watermarks should also
678 * be computed as if the pipe would be active. Perhaps move
679 * per-plane wm computation to the .check_plane() hook, and
680 * only combine the results from all planes in the current place?
681 */
682 if (!is_crtc_enabled) {
683 intel_plane_set_invisible(new_crtc_state, new_plane_state);
684 visible = false;
685 }
686
687 if (!was_visible && !visible)
688 return 0;
689
690 turn_off = was_visible && (!visible || mode_changed);
691 turn_on = visible && (!was_visible || mode_changed);
692
693 drm_dbg_atomic(display->drm,
694 "[CRTC:%d:%s] with [PLANE:%d:%s] visible %i -> %i, off %i, on %i, ms %i\n",
695 crtc->base.base.id, crtc->base.name,
696 plane->base.base.id, plane->base.name,
697 was_visible, visible,
698 turn_off, turn_on, mode_changed);
699
700 if (visible || was_visible)
701 new_crtc_state->fb_bits |= plane->frontbuffer_bit;
702
703 if (HAS_GMCH(display) &&
704 i9xx_must_disable_cxsr(new_crtc_state, old_plane_state, new_plane_state))
705 new_crtc_state->disable_cxsr = true;
706
707 if ((display->platform.ironlake || display->platform.sandybridge || display->platform.ivybridge) &&
708 ilk_must_disable_cxsr(new_crtc_state, old_plane_state, new_plane_state))
709 new_crtc_state->disable_cxsr = true;
710
711 if (intel_plane_do_async_flip(plane, old_crtc_state, new_crtc_state))
712 new_crtc_state->do_async_flip = true;
713
714 if (new_crtc_state->uapi.async_flip) {
715 /*
716 * On platforms with double buffered async flip bit we
717 * set the bit already one frame early during the sync
718 * flip (see {i9xx,skl}_plane_update_arm()). The
719 * hardware will therefore be ready to perform a real
720 * async flip during the next commit, without having
721 * to wait yet another frame for the bit to latch.
722 *
723 * async_flip_planes bitmask is also used by selective
724 * fetch calculation to choose full frame update.
725 */
726 new_crtc_state->async_flip_planes |= BIT(plane->id);
727 }
728
729 return 0;
730 }
731
intel_plane_atomic_check_with_state(const struct intel_crtc_state * old_crtc_state,struct intel_crtc_state * new_crtc_state,const struct intel_plane_state * old_plane_state,struct intel_plane_state * new_plane_state)732 int intel_plane_atomic_check_with_state(const struct intel_crtc_state *old_crtc_state,
733 struct intel_crtc_state *new_crtc_state,
734 const struct intel_plane_state *old_plane_state,
735 struct intel_plane_state *new_plane_state)
736 {
737 struct intel_plane *plane = to_intel_plane(new_plane_state->uapi.plane);
738 const struct drm_framebuffer *fb = new_plane_state->hw.fb;
739 int ret;
740
741 intel_plane_set_invisible(new_crtc_state, new_plane_state);
742 new_crtc_state->enabled_planes &= ~BIT(plane->id);
743
744 if (!new_plane_state->hw.crtc && !old_plane_state->hw.crtc)
745 return 0;
746
747 ret = plane->check_plane(new_crtc_state, new_plane_state);
748 if (ret)
749 return ret;
750
751 if (fb)
752 new_crtc_state->enabled_planes |= BIT(plane->id);
753
754 /* FIXME pre-g4x don't work like this */
755 if (new_plane_state->uapi.visible)
756 new_crtc_state->active_planes |= BIT(plane->id);
757
758 if (new_plane_state->uapi.visible &&
759 intel_plane_is_scaled(new_plane_state))
760 new_crtc_state->scaled_planes |= BIT(plane->id);
761
762 if (new_plane_state->uapi.visible &&
763 intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier))
764 new_crtc_state->nv12_planes |= BIT(plane->id);
765
766 if (new_plane_state->uapi.visible &&
767 fb->format->format == DRM_FORMAT_C8)
768 new_crtc_state->c8_planes |= BIT(plane->id);
769
770 if (new_plane_state->uapi.visible || old_plane_state->uapi.visible)
771 new_crtc_state->update_planes |= BIT(plane->id);
772
773 if (new_plane_state->uapi.visible &&
774 intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) {
775 new_crtc_state->data_rate_y[plane->id] =
776 intel_plane_data_rate(new_crtc_state, new_plane_state, 0);
777 new_crtc_state->data_rate[plane->id] =
778 intel_plane_data_rate(new_crtc_state, new_plane_state, 1);
779
780 new_crtc_state->rel_data_rate_y[plane->id] =
781 intel_plane_relative_data_rate(new_crtc_state,
782 new_plane_state, 0);
783 new_crtc_state->rel_data_rate[plane->id] =
784 intel_plane_relative_data_rate(new_crtc_state,
785 new_plane_state, 1);
786 } else if (new_plane_state->uapi.visible) {
787 new_crtc_state->data_rate[plane->id] =
788 intel_plane_data_rate(new_crtc_state, new_plane_state, 0);
789
790 new_crtc_state->rel_data_rate[plane->id] =
791 intel_plane_relative_data_rate(new_crtc_state,
792 new_plane_state, 0);
793 }
794
795 return intel_plane_atomic_calc_changes(old_crtc_state, new_crtc_state,
796 old_plane_state, new_plane_state);
797 }
798
799 struct intel_plane *
intel_crtc_get_plane(struct intel_crtc * crtc,enum plane_id plane_id)800 intel_crtc_get_plane(struct intel_crtc *crtc, enum plane_id plane_id)
801 {
802 struct intel_display *display = to_intel_display(crtc);
803 struct intel_plane *plane;
804
805 for_each_intel_plane_on_crtc(display->drm, crtc, plane) {
806 if (plane->id == plane_id)
807 return plane;
808 }
809
810 return NULL;
811 }
812
plane_atomic_check(struct intel_atomic_state * state,struct intel_plane * plane)813 static int plane_atomic_check(struct intel_atomic_state *state,
814 struct intel_plane *plane)
815 {
816 struct intel_display *display = to_intel_display(state);
817 struct intel_plane_state *new_plane_state =
818 intel_atomic_get_new_plane_state(state, plane);
819 const struct intel_plane_state *old_plane_state =
820 intel_atomic_get_old_plane_state(state, plane);
821 const struct intel_plane_state *new_primary_crtc_plane_state;
822 const struct intel_plane_state *old_primary_crtc_plane_state;
823 struct intel_crtc *crtc = intel_crtc_for_pipe(display, plane->pipe);
824 const struct intel_crtc_state *old_crtc_state =
825 intel_atomic_get_old_crtc_state(state, crtc);
826 struct intel_crtc_state *new_crtc_state =
827 intel_atomic_get_new_crtc_state(state, crtc);
828
829 if (new_crtc_state && intel_crtc_is_joiner_secondary(new_crtc_state)) {
830 struct intel_crtc *primary_crtc =
831 intel_primary_crtc(new_crtc_state);
832 struct intel_plane *primary_crtc_plane =
833 intel_crtc_get_plane(primary_crtc, plane->id);
834
835 new_primary_crtc_plane_state =
836 intel_atomic_get_new_plane_state(state, primary_crtc_plane);
837 old_primary_crtc_plane_state =
838 intel_atomic_get_old_plane_state(state, primary_crtc_plane);
839 } else {
840 new_primary_crtc_plane_state = new_plane_state;
841 old_primary_crtc_plane_state = old_plane_state;
842 }
843
844 intel_plane_copy_uapi_plane_damage(new_plane_state,
845 old_primary_crtc_plane_state,
846 new_primary_crtc_plane_state);
847
848 intel_plane_copy_uapi_to_hw_state(new_plane_state,
849 new_primary_crtc_plane_state,
850 crtc);
851
852 new_plane_state->uapi.visible = false;
853 if (!new_crtc_state)
854 return 0;
855
856 return intel_plane_atomic_check_with_state(old_crtc_state,
857 new_crtc_state,
858 old_plane_state,
859 new_plane_state);
860 }
861
862 static struct intel_plane *
skl_next_plane_to_commit(struct intel_atomic_state * state,struct intel_crtc * crtc,struct skl_ddb_entry ddb[I915_MAX_PLANES],struct skl_ddb_entry ddb_y[I915_MAX_PLANES],unsigned int * update_mask)863 skl_next_plane_to_commit(struct intel_atomic_state *state,
864 struct intel_crtc *crtc,
865 struct skl_ddb_entry ddb[I915_MAX_PLANES],
866 struct skl_ddb_entry ddb_y[I915_MAX_PLANES],
867 unsigned int *update_mask)
868 {
869 struct intel_crtc_state *crtc_state =
870 intel_atomic_get_new_crtc_state(state, crtc);
871 struct intel_plane_state __maybe_unused *plane_state;
872 struct intel_plane *plane;
873 int i;
874
875 if (*update_mask == 0)
876 return NULL;
877
878 for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
879 enum plane_id plane_id = plane->id;
880
881 if (crtc->pipe != plane->pipe ||
882 !(*update_mask & BIT(plane_id)))
883 continue;
884
885 if (skl_ddb_allocation_overlaps(&crtc_state->wm.skl.plane_ddb[plane_id],
886 ddb, I915_MAX_PLANES, plane_id) ||
887 skl_ddb_allocation_overlaps(&crtc_state->wm.skl.plane_ddb_y[plane_id],
888 ddb_y, I915_MAX_PLANES, plane_id))
889 continue;
890
891 *update_mask &= ~BIT(plane_id);
892 ddb[plane_id] = crtc_state->wm.skl.plane_ddb[plane_id];
893 ddb_y[plane_id] = crtc_state->wm.skl.plane_ddb_y[plane_id];
894
895 return plane;
896 }
897
898 /* should never happen */
899 drm_WARN_ON(state->base.dev, 1);
900
901 return NULL;
902 }
903
intel_plane_update_noarm(struct intel_dsb * dsb,struct intel_plane * plane,const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)904 void intel_plane_update_noarm(struct intel_dsb *dsb,
905 struct intel_plane *plane,
906 const struct intel_crtc_state *crtc_state,
907 const struct intel_plane_state *plane_state)
908 {
909 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
910
911 trace_intel_plane_update_noarm(plane_state, crtc);
912
913 if (plane->fbc)
914 intel_fbc_dirty_rect_update_noarm(dsb, plane);
915
916 if (plane->update_noarm)
917 plane->update_noarm(dsb, plane, crtc_state, plane_state);
918 }
919
intel_plane_async_flip(struct intel_dsb * dsb,struct intel_plane * plane,const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state,bool async_flip)920 void intel_plane_async_flip(struct intel_dsb *dsb,
921 struct intel_plane *plane,
922 const struct intel_crtc_state *crtc_state,
923 const struct intel_plane_state *plane_state,
924 bool async_flip)
925 {
926 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
927
928 trace_intel_plane_async_flip(plane, crtc, async_flip);
929 plane->async_flip(dsb, plane, crtc_state, plane_state, async_flip);
930 }
931
intel_plane_update_arm(struct intel_dsb * dsb,struct intel_plane * plane,const struct intel_crtc_state * crtc_state,const struct intel_plane_state * plane_state)932 void intel_plane_update_arm(struct intel_dsb *dsb,
933 struct intel_plane *plane,
934 const struct intel_crtc_state *crtc_state,
935 const struct intel_plane_state *plane_state)
936 {
937 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
938
939 if (crtc_state->do_async_flip && plane->async_flip) {
940 intel_plane_async_flip(dsb, plane, crtc_state, plane_state, true);
941 return;
942 }
943
944 trace_intel_plane_update_arm(plane_state, crtc);
945 plane->update_arm(dsb, plane, crtc_state, plane_state);
946 }
947
intel_plane_disable_arm(struct intel_dsb * dsb,struct intel_plane * plane,const struct intel_crtc_state * crtc_state)948 void intel_plane_disable_arm(struct intel_dsb *dsb,
949 struct intel_plane *plane,
950 const struct intel_crtc_state *crtc_state)
951 {
952 struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc);
953
954 trace_intel_plane_disable_arm(plane, crtc);
955 plane->disable_arm(dsb, plane, crtc_state);
956 }
957
intel_crtc_planes_update_noarm(struct intel_dsb * dsb,struct intel_atomic_state * state,struct intel_crtc * crtc)958 void intel_crtc_planes_update_noarm(struct intel_dsb *dsb,
959 struct intel_atomic_state *state,
960 struct intel_crtc *crtc)
961 {
962 struct intel_crtc_state *new_crtc_state =
963 intel_atomic_get_new_crtc_state(state, crtc);
964 u32 update_mask = new_crtc_state->update_planes;
965 struct intel_plane_state *new_plane_state;
966 struct intel_plane *plane;
967 int i;
968
969 if (new_crtc_state->do_async_flip)
970 return;
971
972 /*
973 * Since we only write non-arming registers here,
974 * the order does not matter even for skl+.
975 */
976 for_each_new_intel_plane_in_state(state, plane, new_plane_state, i) {
977 if (crtc->pipe != plane->pipe ||
978 !(update_mask & BIT(plane->id)))
979 continue;
980
981 /* TODO: for mailbox updates this should be skipped */
982 if (new_plane_state->uapi.visible ||
983 new_plane_state->is_y_plane)
984 intel_plane_update_noarm(dsb, plane,
985 new_crtc_state, new_plane_state);
986 }
987 }
988
skl_crtc_planes_update_arm(struct intel_dsb * dsb,struct intel_atomic_state * state,struct intel_crtc * crtc)989 static void skl_crtc_planes_update_arm(struct intel_dsb *dsb,
990 struct intel_atomic_state *state,
991 struct intel_crtc *crtc)
992 {
993 struct intel_crtc_state *old_crtc_state =
994 intel_atomic_get_old_crtc_state(state, crtc);
995 struct intel_crtc_state *new_crtc_state =
996 intel_atomic_get_new_crtc_state(state, crtc);
997 struct skl_ddb_entry ddb[I915_MAX_PLANES];
998 struct skl_ddb_entry ddb_y[I915_MAX_PLANES];
999 u32 update_mask = new_crtc_state->update_planes;
1000 struct intel_plane *plane;
1001
1002 memcpy(ddb, old_crtc_state->wm.skl.plane_ddb,
1003 sizeof(old_crtc_state->wm.skl.plane_ddb));
1004 memcpy(ddb_y, old_crtc_state->wm.skl.plane_ddb_y,
1005 sizeof(old_crtc_state->wm.skl.plane_ddb_y));
1006
1007 while ((plane = skl_next_plane_to_commit(state, crtc, ddb, ddb_y, &update_mask))) {
1008 struct intel_plane_state *new_plane_state =
1009 intel_atomic_get_new_plane_state(state, plane);
1010
1011 /*
1012 * TODO: for mailbox updates intel_plane_update_noarm()
1013 * would have to be called here as well.
1014 */
1015 if (new_plane_state->uapi.visible ||
1016 new_plane_state->is_y_plane)
1017 intel_plane_update_arm(dsb, plane, new_crtc_state, new_plane_state);
1018 else
1019 intel_plane_disable_arm(dsb, plane, new_crtc_state);
1020 }
1021 }
1022
i9xx_crtc_planes_update_arm(struct intel_dsb * dsb,struct intel_atomic_state * state,struct intel_crtc * crtc)1023 static void i9xx_crtc_planes_update_arm(struct intel_dsb *dsb,
1024 struct intel_atomic_state *state,
1025 struct intel_crtc *crtc)
1026 {
1027 struct intel_crtc_state *new_crtc_state =
1028 intel_atomic_get_new_crtc_state(state, crtc);
1029 u32 update_mask = new_crtc_state->update_planes;
1030 struct intel_plane_state *new_plane_state;
1031 struct intel_plane *plane;
1032 int i;
1033
1034 for_each_new_intel_plane_in_state(state, plane, new_plane_state, i) {
1035 if (crtc->pipe != plane->pipe ||
1036 !(update_mask & BIT(plane->id)))
1037 continue;
1038
1039 /*
1040 * TODO: for mailbox updates intel_plane_update_noarm()
1041 * would have to be called here as well.
1042 */
1043 if (new_plane_state->uapi.visible)
1044 intel_plane_update_arm(dsb, plane, new_crtc_state, new_plane_state);
1045 else
1046 intel_plane_disable_arm(dsb, plane, new_crtc_state);
1047 }
1048 }
1049
intel_crtc_planes_update_arm(struct intel_dsb * dsb,struct intel_atomic_state * state,struct intel_crtc * crtc)1050 void intel_crtc_planes_update_arm(struct intel_dsb *dsb,
1051 struct intel_atomic_state *state,
1052 struct intel_crtc *crtc)
1053 {
1054 struct intel_display *display = to_intel_display(state);
1055
1056 if (DISPLAY_VER(display) >= 9)
1057 skl_crtc_planes_update_arm(dsb, state, crtc);
1058 else
1059 i9xx_crtc_planes_update_arm(dsb, state, crtc);
1060 }
1061
intel_plane_check_clipping(struct intel_plane_state * plane_state,struct intel_crtc_state * crtc_state,int min_scale,int max_scale,bool can_position)1062 int intel_plane_check_clipping(struct intel_plane_state *plane_state,
1063 struct intel_crtc_state *crtc_state,
1064 int min_scale, int max_scale,
1065 bool can_position)
1066 {
1067 struct intel_display *display = to_intel_display(plane_state);
1068 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1069 struct drm_framebuffer *fb = plane_state->hw.fb;
1070 struct drm_rect *src = &plane_state->uapi.src;
1071 struct drm_rect *dst = &plane_state->uapi.dst;
1072 const struct drm_rect *clip = &crtc_state->pipe_src;
1073 unsigned int rotation = plane_state->hw.rotation;
1074 int hscale, vscale;
1075
1076 if (!fb) {
1077 plane_state->uapi.visible = false;
1078 return 0;
1079 }
1080
1081 drm_rect_rotate(src, fb->width << 16, fb->height << 16, rotation);
1082
1083 /* Check scaling */
1084 hscale = drm_rect_calc_hscale(src, dst, min_scale, max_scale);
1085 vscale = drm_rect_calc_vscale(src, dst, min_scale, max_scale);
1086 if (hscale < 0 || vscale < 0) {
1087 drm_dbg_kms(display->drm,
1088 "[PLANE:%d:%s] invalid scaling "DRM_RECT_FP_FMT " -> " DRM_RECT_FMT "\n",
1089 plane->base.base.id, plane->base.name,
1090 DRM_RECT_FP_ARG(src), DRM_RECT_ARG(dst));
1091 return -ERANGE;
1092 }
1093
1094 /*
1095 * FIXME: This might need further adjustment for seamless scaling
1096 * with phase information, for the 2p2 and 2p1 scenarios.
1097 */
1098 plane_state->uapi.visible = drm_rect_clip_scaled(src, dst, clip);
1099
1100 drm_rect_rotate_inv(src, fb->width << 16, fb->height << 16, rotation);
1101
1102 if (!can_position && plane_state->uapi.visible &&
1103 !drm_rect_equals(dst, clip)) {
1104 drm_dbg_kms(display->drm,
1105 "[PLANE:%d:%s] plane (" DRM_RECT_FMT ") must cover entire CRTC (" DRM_RECT_FMT ")\n",
1106 plane->base.base.id, plane->base.name,
1107 DRM_RECT_ARG(dst), DRM_RECT_ARG(clip));
1108 return -EINVAL;
1109 }
1110
1111 /* final plane coordinates will be relative to the plane's pipe */
1112 drm_rect_translate(dst, -clip->x1, -clip->y1);
1113
1114 return 0;
1115 }
1116
intel_plane_check_src_coordinates(struct intel_plane_state * plane_state)1117 int intel_plane_check_src_coordinates(struct intel_plane_state *plane_state)
1118 {
1119 struct intel_display *display = to_intel_display(plane_state);
1120 struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
1121 const struct drm_framebuffer *fb = plane_state->hw.fb;
1122 struct drm_rect *src = &plane_state->uapi.src;
1123 u32 src_x, src_y, src_w, src_h, hsub, vsub;
1124 bool rotated = drm_rotation_90_or_270(plane_state->hw.rotation);
1125
1126 /*
1127 * FIXME hsub/vsub vs. block size is a mess. Pre-tgl CCS
1128 * abuses hsub/vsub so we can't use them here. But as they
1129 * are limited to 32bpp RGB formats we don't actually need
1130 * to check anything.
1131 */
1132 if (fb->modifier == I915_FORMAT_MOD_Y_TILED_CCS ||
1133 fb->modifier == I915_FORMAT_MOD_Yf_TILED_CCS)
1134 return 0;
1135
1136 /*
1137 * Hardware doesn't handle subpixel coordinates.
1138 * Adjust to (macro)pixel boundary, but be careful not to
1139 * increase the source viewport size, because that could
1140 * push the downscaling factor out of bounds.
1141 */
1142 src_x = src->x1 >> 16;
1143 src_w = drm_rect_width(src) >> 16;
1144 src_y = src->y1 >> 16;
1145 src_h = drm_rect_height(src) >> 16;
1146
1147 drm_rect_init(src, src_x << 16, src_y << 16,
1148 src_w << 16, src_h << 16);
1149
1150 if (fb->format->format == DRM_FORMAT_RGB565 && rotated) {
1151 hsub = 2;
1152 vsub = 2;
1153 } else if (DISPLAY_VER(display) >= 20 &&
1154 intel_format_info_is_yuv_semiplanar(fb->format, fb->modifier)) {
1155 /*
1156 * This allows NV12 and P0xx formats to have odd size and/or odd
1157 * source coordinates on DISPLAY_VER(display) >= 20
1158 */
1159 hsub = 1;
1160 vsub = 1;
1161
1162 /* Wa_16023981245 */
1163 if ((DISPLAY_VERx100(display) == 2000 ||
1164 DISPLAY_VERx100(display) == 3000 ||
1165 DISPLAY_VERx100(display) == 3002) &&
1166 src_x % 2 != 0)
1167 hsub = 2;
1168
1169 if (DISPLAY_VER(display) == 35)
1170 vsub = 2;
1171 } else {
1172 hsub = fb->format->hsub;
1173 vsub = fb->format->vsub;
1174 }
1175
1176 if (rotated)
1177 hsub = vsub = max(hsub, vsub);
1178
1179 if (src_x % hsub || src_w % hsub) {
1180 drm_dbg_kms(display->drm,
1181 "[PLANE:%d:%s] src x/w (%u, %u) must be a multiple of %u (rotated: %s)\n",
1182 plane->base.base.id, plane->base.name,
1183 src_x, src_w, hsub, str_yes_no(rotated));
1184 return -EINVAL;
1185 }
1186
1187 if (src_y % vsub || src_h % vsub) {
1188 drm_dbg_kms(display->drm,
1189 "[PLANE:%d:%s] src y/h (%u, %u) must be a multiple of %u (rotated: %s)\n",
1190 plane->base.base.id, plane->base.name,
1191 src_y, src_h, vsub, str_yes_no(rotated));
1192 return -EINVAL;
1193 }
1194
1195 return 0;
1196 }
1197
add_dma_resv_fences(struct dma_resv * resv,struct drm_plane_state * new_plane_state)1198 static int add_dma_resv_fences(struct dma_resv *resv,
1199 struct drm_plane_state *new_plane_state)
1200 {
1201 struct dma_fence *fence = dma_fence_get(new_plane_state->fence);
1202 struct dma_fence *new;
1203 int ret;
1204
1205 ret = dma_resv_get_singleton(resv, dma_resv_usage_rw(false), &new);
1206 if (ret)
1207 goto error;
1208
1209 if (new && fence) {
1210 struct dma_fence_chain *chain = dma_fence_chain_alloc();
1211
1212 if (!chain) {
1213 ret = -ENOMEM;
1214 goto error;
1215 }
1216
1217 dma_fence_chain_init(chain, fence, new, 1);
1218 fence = &chain->base;
1219
1220 } else if (new) {
1221 fence = new;
1222 }
1223
1224 dma_fence_put(new_plane_state->fence);
1225 new_plane_state->fence = fence;
1226 return 0;
1227
1228 error:
1229 dma_fence_put(fence);
1230 return ret;
1231 }
1232
1233 /**
1234 * intel_prepare_plane_fb - Prepare fb for usage on plane
1235 * @_plane: drm plane to prepare for
1236 * @_new_plane_state: the plane state being prepared
1237 *
1238 * Prepares a framebuffer for usage on a display plane. Generally this
1239 * involves pinning the underlying object and updating the frontbuffer tracking
1240 * bits. Some older platforms need special physical address handling for
1241 * cursor planes.
1242 *
1243 * Returns 0 on success, negative error code on failure.
1244 */
1245 static int
intel_prepare_plane_fb(struct drm_plane * _plane,struct drm_plane_state * _new_plane_state)1246 intel_prepare_plane_fb(struct drm_plane *_plane,
1247 struct drm_plane_state *_new_plane_state)
1248 {
1249 struct intel_plane *plane = to_intel_plane(_plane);
1250 struct intel_display *display = to_intel_display(plane);
1251 struct intel_plane_state *new_plane_state =
1252 to_intel_plane_state(_new_plane_state);
1253 struct intel_atomic_state *state =
1254 to_intel_atomic_state(new_plane_state->uapi.state);
1255 struct intel_plane_state *old_plane_state =
1256 intel_atomic_get_old_plane_state(state, plane);
1257 struct drm_gem_object *obj = intel_fb_bo(new_plane_state->hw.fb);
1258 struct drm_gem_object *old_obj = intel_fb_bo(old_plane_state->hw.fb);
1259 int ret;
1260
1261 if (old_obj) {
1262 const struct intel_crtc_state *new_crtc_state =
1263 intel_atomic_get_new_crtc_state(state,
1264 to_intel_crtc(old_plane_state->hw.crtc));
1265
1266 /* Big Hammer, we also need to ensure that any pending
1267 * MI_WAIT_FOR_EVENT inside a user batch buffer on the
1268 * current scanout is retired before unpinning the old
1269 * framebuffer. Note that we rely on userspace rendering
1270 * into the buffer attached to the pipe they are waiting
1271 * on. If not, userspace generates a GPU hang with IPEHR
1272 * point to the MI_WAIT_FOR_EVENT.
1273 *
1274 * This should only fail upon a hung GPU, in which case we
1275 * can safely continue.
1276 */
1277 if (intel_crtc_needs_modeset(new_crtc_state)) {
1278 ret = add_dma_resv_fences(old_obj->resv,
1279 &new_plane_state->uapi);
1280 if (ret < 0)
1281 return ret;
1282 }
1283 }
1284
1285 if (!obj)
1286 return 0;
1287
1288 ret = intel_plane_pin_fb(new_plane_state, old_plane_state);
1289 if (ret)
1290 return ret;
1291
1292 ret = drm_gem_plane_helper_prepare_fb(&plane->base, &new_plane_state->uapi);
1293 if (ret < 0)
1294 goto unpin_fb;
1295
1296 if (new_plane_state->uapi.fence) {
1297 intel_parent_fence_priority_display(display, new_plane_state->uapi.fence);
1298 intel_display_rps_boost_after_vblank(new_plane_state->hw.crtc,
1299 new_plane_state->uapi.fence);
1300 }
1301
1302 /*
1303 * We declare pageflips to be interactive and so merit a small bias
1304 * towards upclocking to deliver the frame on time. By only changing
1305 * the RPS thresholds to sample more regularly and aim for higher
1306 * clocks we can hopefully deliver low power workloads (like kodi)
1307 * that are not quite steady state without resorting to forcing
1308 * maximum clocks following a vblank miss (see do_rps_boost()).
1309 */
1310 intel_display_rps_mark_interactive(display, state, true);
1311
1312 return 0;
1313
1314 unpin_fb:
1315 intel_plane_unpin_fb(new_plane_state);
1316
1317 return ret;
1318 }
1319
1320 /**
1321 * intel_cleanup_plane_fb - Cleans up an fb after plane use
1322 * @plane: drm plane to clean up for
1323 * @_old_plane_state: the state from the previous modeset
1324 *
1325 * Cleans up a framebuffer that has just been removed from a plane.
1326 */
1327 static void
intel_cleanup_plane_fb(struct drm_plane * plane,struct drm_plane_state * _old_plane_state)1328 intel_cleanup_plane_fb(struct drm_plane *plane,
1329 struct drm_plane_state *_old_plane_state)
1330 {
1331 struct intel_display *display = to_intel_display(plane->dev);
1332 struct intel_plane_state *old_plane_state =
1333 to_intel_plane_state(_old_plane_state);
1334 struct intel_atomic_state *state =
1335 to_intel_atomic_state(old_plane_state->uapi.state);
1336 struct drm_gem_object *obj = intel_fb_bo(old_plane_state->hw.fb);
1337
1338 if (!obj)
1339 return;
1340
1341 intel_display_rps_mark_interactive(display, state, false);
1342
1343 intel_plane_unpin_fb(old_plane_state);
1344 }
1345
1346 /* Handle Y-tiling, only if DPT is enabled (otherwise disabling tiling is easier)
1347 * All DPT hardware have 128-bytes width tiling, so Y-tile dimension is 32x32
1348 * pixels for 32bits pixels.
1349 */
1350 #define YTILE_WIDTH 32
1351 #define YTILE_HEIGHT 32
1352 #define YTILE_SIZE (YTILE_WIDTH * YTILE_HEIGHT * 4)
1353
intel_ytile_get_offset(unsigned int width,unsigned int x,unsigned int y)1354 static unsigned int intel_ytile_get_offset(unsigned int width, unsigned int x, unsigned int y)
1355 {
1356 u32 offset;
1357 unsigned int swizzle;
1358 unsigned int width_in_blocks = DIV_ROUND_UP(width, 32);
1359
1360 /* Block offset */
1361 offset = ((y / YTILE_HEIGHT) * width_in_blocks + (x / YTILE_WIDTH)) * YTILE_SIZE;
1362
1363 x = x % YTILE_WIDTH;
1364 y = y % YTILE_HEIGHT;
1365
1366 /* bit order inside a block is x4 x3 x2 y4 y3 y2 y1 y0 x1 x0 */
1367 swizzle = (x & 3) | ((y & 0x1f) << 2) | ((x & 0x1c) << 5);
1368 offset += swizzle * 4;
1369 return offset;
1370 }
1371
intel_4tile_get_offset(unsigned int width,unsigned int x,unsigned int y)1372 static unsigned int intel_4tile_get_offset(unsigned int width, unsigned int x, unsigned int y)
1373 {
1374 u32 offset;
1375 unsigned int swizzle;
1376 unsigned int width_in_blocks = DIV_ROUND_UP(width, 32);
1377
1378 /* Block offset */
1379 offset = ((y / YTILE_HEIGHT) * width_in_blocks + (x / YTILE_WIDTH)) * YTILE_SIZE;
1380
1381 x = x % YTILE_WIDTH;
1382 y = y % YTILE_HEIGHT;
1383
1384 /* bit order inside a block is y4 y3 x4 y2 x3 x2 y1 y0 x1 x0 */
1385 swizzle = (x & 3) | ((y & 3) << 2) | ((x & 0xc) << 2) | (y & 4) << 4 |
1386 ((x & 0x10) << 3) | ((y & 0x18) << 5);
1387 offset += swizzle * 4;
1388 return offset;
1389 }
1390
intel_panic_flush(struct drm_plane * _plane)1391 static void intel_panic_flush(struct drm_plane *_plane)
1392 {
1393 struct intel_plane *plane = to_intel_plane(_plane);
1394 struct intel_display *display = to_intel_display(plane);
1395 const struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state);
1396 struct intel_crtc *crtc = to_intel_crtc(plane_state->hw.crtc);
1397 const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state);
1398 const struct intel_framebuffer *fb = to_intel_framebuffer(plane_state->hw.fb);
1399
1400 intel_parent_panic_finish(display, fb->panic);
1401
1402 if (crtc_state->enable_psr2_sel_fetch) {
1403 /* Force a full update for psr2 */
1404 intel_psr2_panic_force_full_update(crtc_state);
1405 }
1406
1407 /* Flush the cache and don't disable tiling if it's the fbdev framebuffer.*/
1408 if (fb == intel_fbdev_framebuffer(display->fbdev.fbdev)) {
1409 struct iosys_map map;
1410
1411 intel_fbdev_get_map(display->fbdev.fbdev, &map);
1412 drm_clflush_virt_range(map.vaddr, fb->base.pitches[0] * fb->base.height);
1413 return;
1414 }
1415
1416 if (fb->base.modifier != DRM_FORMAT_MOD_LINEAR && plane->disable_tiling)
1417 plane->disable_tiling(plane);
1418 }
1419
intel_get_tiling_func(u64 fb_modifier)1420 static unsigned int (*intel_get_tiling_func(u64 fb_modifier))(unsigned int width,
1421 unsigned int x,
1422 unsigned int y)
1423 {
1424 switch (fb_modifier) {
1425 case I915_FORMAT_MOD_Y_TILED:
1426 case I915_FORMAT_MOD_Y_TILED_CCS:
1427 case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC:
1428 case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS:
1429 case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS:
1430 return intel_ytile_get_offset;
1431 case I915_FORMAT_MOD_4_TILED:
1432 case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS:
1433 case I915_FORMAT_MOD_4_TILED_DG2_MC_CCS:
1434 case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC:
1435 case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS:
1436 case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC:
1437 case I915_FORMAT_MOD_4_TILED_MTL_MC_CCS:
1438 case I915_FORMAT_MOD_4_TILED_BMG_CCS:
1439 case I915_FORMAT_MOD_4_TILED_LNL_CCS:
1440 return intel_4tile_get_offset;
1441 case I915_FORMAT_MOD_X_TILED:
1442 case I915_FORMAT_MOD_Yf_TILED:
1443 case I915_FORMAT_MOD_Yf_TILED_CCS:
1444 default:
1445 /* Not supported yet */
1446 return NULL;
1447 }
1448 }
1449
intel_get_scanout_buffer(struct drm_plane * plane,struct drm_scanout_buffer * sb)1450 static int intel_get_scanout_buffer(struct drm_plane *plane,
1451 struct drm_scanout_buffer *sb)
1452 {
1453 struct intel_plane_state *plane_state;
1454 struct drm_gem_object *obj;
1455 struct intel_framebuffer *fb;
1456 struct intel_display *display = to_intel_display(plane->dev);
1457
1458 if (!plane->state || !plane->state->fb || !plane->state->visible)
1459 return -ENODEV;
1460
1461 plane_state = to_intel_plane_state(plane->state);
1462 fb = to_intel_framebuffer(plane_state->hw.fb);
1463
1464 obj = intel_fb_bo(&fb->base);
1465 if (!obj)
1466 return -ENODEV;
1467
1468 if (fb == intel_fbdev_framebuffer(display->fbdev.fbdev)) {
1469 intel_fbdev_get_map(display->fbdev.fbdev, &sb->map[0]);
1470 } else {
1471 int ret;
1472 /* Can't disable tiling if DPT is in use */
1473 if (intel_fb_uses_dpt(&fb->base)) {
1474 if (fb->base.format->cpp[0] != 4)
1475 return -EOPNOTSUPP;
1476 fb->panic_tiling = intel_get_tiling_func(fb->base.modifier);
1477 if (!fb->panic_tiling)
1478 return -EOPNOTSUPP;
1479 }
1480 sb->private = fb;
1481 ret = intel_parent_panic_setup(display, fb->panic, sb);
1482 if (ret)
1483 return ret;
1484 }
1485 sb->width = fb->base.width;
1486 sb->height = fb->base.height;
1487 /* Use the generic linear format, because tiling, RC, CCS, CC
1488 * will be disabled in disable_tiling()
1489 */
1490 sb->format = drm_format_info(fb->base.format->format);
1491 sb->pitch[0] = fb->base.pitches[0];
1492
1493 return 0;
1494 }
1495
1496 static const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
1497 .prepare_fb = intel_prepare_plane_fb,
1498 .cleanup_fb = intel_cleanup_plane_fb,
1499 };
1500
1501 static const struct drm_plane_helper_funcs intel_primary_plane_helper_funcs = {
1502 .prepare_fb = intel_prepare_plane_fb,
1503 .cleanup_fb = intel_cleanup_plane_fb,
1504 .get_scanout_buffer = intel_get_scanout_buffer,
1505 .panic_flush = intel_panic_flush,
1506 };
1507
intel_plane_helper_add(struct intel_plane * plane)1508 void intel_plane_helper_add(struct intel_plane *plane)
1509 {
1510 if (plane->base.type == DRM_PLANE_TYPE_PRIMARY)
1511 drm_plane_helper_add(&plane->base, &intel_primary_plane_helper_funcs);
1512 else
1513 drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
1514 }
1515
intel_plane_init_cursor_vblank_work(struct intel_plane_state * old_plane_state,struct intel_plane_state * new_plane_state)1516 void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state,
1517 struct intel_plane_state *new_plane_state)
1518 {
1519 if (!old_plane_state->ggtt_vma ||
1520 old_plane_state->ggtt_vma == new_plane_state->ggtt_vma)
1521 return;
1522
1523 drm_vblank_work_init(&old_plane_state->unpin_work, old_plane_state->hw.crtc,
1524 intel_cursor_unpin_work);
1525 }
1526
link_nv12_planes(struct intel_crtc_state * crtc_state,struct intel_plane_state * uv_plane_state,struct intel_plane_state * y_plane_state)1527 static void link_nv12_planes(struct intel_crtc_state *crtc_state,
1528 struct intel_plane_state *uv_plane_state,
1529 struct intel_plane_state *y_plane_state)
1530 {
1531 struct intel_display *display = to_intel_display(uv_plane_state);
1532 struct intel_plane *uv_plane = to_intel_plane(uv_plane_state->uapi.plane);
1533 struct intel_plane *y_plane = to_intel_plane(y_plane_state->uapi.plane);
1534
1535 drm_dbg_kms(display->drm, "UV plane [PLANE:%d:%s] using Y plane [PLANE:%d:%s]\n",
1536 uv_plane->base.base.id, uv_plane->base.name,
1537 y_plane->base.base.id, y_plane->base.name);
1538
1539 uv_plane_state->planar_linked_plane = y_plane;
1540
1541 y_plane_state->is_y_plane = true;
1542 y_plane_state->planar_linked_plane = uv_plane;
1543
1544 crtc_state->enabled_planes |= BIT(y_plane->id);
1545 crtc_state->active_planes |= BIT(y_plane->id);
1546 crtc_state->update_planes |= BIT(y_plane->id);
1547
1548 crtc_state->data_rate[y_plane->id] = crtc_state->data_rate_y[uv_plane->id];
1549 crtc_state->rel_data_rate[y_plane->id] = crtc_state->rel_data_rate_y[uv_plane->id];
1550
1551 /* Copy parameters to Y plane */
1552 intel_plane_copy_hw_state(y_plane_state, uv_plane_state);
1553 y_plane_state->uapi.src = uv_plane_state->uapi.src;
1554 y_plane_state->uapi.dst = uv_plane_state->uapi.dst;
1555
1556 y_plane_state->ctl = uv_plane_state->ctl;
1557 y_plane_state->color_ctl = uv_plane_state->color_ctl;
1558 y_plane_state->view = uv_plane_state->view;
1559 y_plane_state->decrypt = uv_plane_state->decrypt;
1560
1561 icl_link_nv12_planes(uv_plane_state, y_plane_state);
1562 }
1563
icl_check_nv12_planes(struct intel_atomic_state * state,struct intel_crtc * crtc)1564 static int icl_check_nv12_planes(struct intel_atomic_state *state,
1565 struct intel_crtc *crtc)
1566 {
1567 struct intel_display *display = to_intel_display(state);
1568 struct intel_crtc_state *crtc_state =
1569 intel_atomic_get_new_crtc_state(state, crtc);
1570 struct intel_plane_state *plane_state;
1571 struct intel_plane *plane;
1572 int i;
1573
1574 if (DISPLAY_VER(display) < 11)
1575 return 0;
1576
1577 if (!crtc_state->nv12_planes)
1578 return 0;
1579
1580 for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
1581 struct intel_plane_state *y_plane_state = NULL;
1582 struct intel_plane *y_plane;
1583
1584 if (plane->pipe != crtc->pipe)
1585 continue;
1586
1587 if ((crtc_state->nv12_planes & BIT(plane->id)) == 0)
1588 continue;
1589
1590 for_each_intel_plane_on_crtc(display->drm, crtc, y_plane) {
1591 if (!icl_is_nv12_y_plane(display, y_plane->id))
1592 continue;
1593
1594 if (crtc_state->active_planes & BIT(y_plane->id))
1595 continue;
1596
1597 y_plane_state = intel_atomic_get_plane_state(state, y_plane);
1598 if (IS_ERR(y_plane_state))
1599 return PTR_ERR(y_plane_state);
1600
1601 break;
1602 }
1603
1604 if (!y_plane_state) {
1605 drm_dbg_kms(display->drm,
1606 "[CRTC:%d:%s] need %d free Y planes for planar YUV\n",
1607 crtc->base.base.id, crtc->base.name,
1608 hweight8(crtc_state->nv12_planes));
1609 return -EINVAL;
1610 }
1611
1612 link_nv12_planes(crtc_state, plane_state, y_plane_state);
1613 }
1614
1615 return 0;
1616 }
1617
intel_crtc_add_planes_to_state(struct intel_atomic_state * state,struct intel_crtc * crtc,u8 plane_ids_mask)1618 static int intel_crtc_add_planes_to_state(struct intel_atomic_state *state,
1619 struct intel_crtc *crtc,
1620 u8 plane_ids_mask)
1621 {
1622 struct intel_display *display = to_intel_display(state);
1623 struct intel_plane *plane;
1624
1625 for_each_intel_plane_on_crtc(display->drm, crtc, plane) {
1626 struct intel_plane_state *plane_state;
1627
1628 if ((plane_ids_mask & BIT(plane->id)) == 0)
1629 continue;
1630
1631 plane_state = intel_atomic_get_plane_state(state, plane);
1632 if (IS_ERR(plane_state))
1633 return PTR_ERR(plane_state);
1634 }
1635
1636 return 0;
1637 }
1638
intel_plane_add_affected(struct intel_atomic_state * state,struct intel_crtc * crtc)1639 int intel_plane_add_affected(struct intel_atomic_state *state,
1640 struct intel_crtc *crtc)
1641 {
1642 const struct intel_crtc_state *old_crtc_state =
1643 intel_atomic_get_old_crtc_state(state, crtc);
1644 const struct intel_crtc_state *new_crtc_state =
1645 intel_atomic_get_new_crtc_state(state, crtc);
1646
1647 return intel_crtc_add_planes_to_state(state, crtc,
1648 old_crtc_state->enabled_planes |
1649 new_crtc_state->enabled_planes);
1650 }
1651
active_planes_affects_min_cdclk(struct intel_display * display)1652 static bool active_planes_affects_min_cdclk(struct intel_display *display)
1653 {
1654 /* See {hsw,vlv,ivb}_plane_ratio() */
1655 return display->platform.broadwell || display->platform.haswell ||
1656 display->platform.cherryview || display->platform.valleyview ||
1657 display->platform.ivybridge;
1658 }
1659
intel_joiner_affected_planes(struct intel_atomic_state * state,u8 joined_pipes)1660 static u8 intel_joiner_affected_planes(struct intel_atomic_state *state,
1661 u8 joined_pipes)
1662 {
1663 const struct intel_plane_state *plane_state;
1664 struct intel_plane *plane;
1665 u8 affected_planes = 0;
1666 int i;
1667
1668 for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
1669 struct intel_plane *linked = plane_state->planar_linked_plane;
1670
1671 if ((joined_pipes & BIT(plane->pipe)) == 0)
1672 continue;
1673
1674 affected_planes |= BIT(plane->id);
1675 if (linked)
1676 affected_planes |= BIT(linked->id);
1677 }
1678
1679 return affected_planes;
1680 }
1681
intel_joiner_add_affected_planes(struct intel_atomic_state * state,u8 joined_pipes)1682 static int intel_joiner_add_affected_planes(struct intel_atomic_state *state,
1683 u8 joined_pipes)
1684 {
1685 u8 prev_affected_planes, affected_planes = 0;
1686
1687 /*
1688 * We want all the joined pipes to have the same
1689 * set of planes in the atomic state, to make sure
1690 * state copying always works correctly, and the
1691 * UV<->Y plane linkage is always up to date.
1692 * Keep pulling planes in until we've determined
1693 * the full set of affected planes. A bit complicated
1694 * on account of each pipe being capable of selecting
1695 * their own Y planes independently of the other pipes,
1696 * and the selection being done from the set of
1697 * inactive planes.
1698 */
1699 do {
1700 struct intel_crtc *crtc;
1701
1702 for_each_intel_crtc_in_pipe_mask(state->base.dev, crtc, joined_pipes) {
1703 int ret;
1704
1705 ret = intel_crtc_add_planes_to_state(state, crtc, affected_planes);
1706 if (ret)
1707 return ret;
1708 }
1709
1710 prev_affected_planes = affected_planes;
1711 affected_planes = intel_joiner_affected_planes(state, joined_pipes);
1712 } while (affected_planes != prev_affected_planes);
1713
1714 return 0;
1715 }
1716
intel_add_affected_planes(struct intel_atomic_state * state)1717 static int intel_add_affected_planes(struct intel_atomic_state *state)
1718 {
1719 const struct intel_crtc_state *crtc_state;
1720 struct intel_crtc *crtc;
1721 int i;
1722
1723 for_each_new_intel_crtc_in_state(state, crtc, crtc_state, i) {
1724 int ret;
1725
1726 ret = intel_joiner_add_affected_planes(state, intel_crtc_joined_pipe_mask(crtc_state));
1727 if (ret)
1728 return ret;
1729 }
1730
1731 return 0;
1732 }
1733
intel_plane_atomic_check(struct intel_atomic_state * state)1734 int intel_plane_atomic_check(struct intel_atomic_state *state)
1735 {
1736 struct intel_display *display = to_intel_display(state);
1737 struct intel_crtc_state *old_crtc_state, *new_crtc_state;
1738 struct intel_plane_state __maybe_unused *plane_state;
1739 struct intel_plane *plane;
1740 struct intel_crtc *crtc;
1741 int i, ret;
1742
1743 ret = intel_add_affected_planes(state);
1744 if (ret)
1745 return ret;
1746
1747 for_each_new_intel_plane_in_state(state, plane, plane_state, i) {
1748 ret = plane_atomic_check(state, plane);
1749 if (ret) {
1750 drm_dbg_atomic(display->drm,
1751 "[PLANE:%d:%s] atomic driver check failed\n",
1752 plane->base.base.id, plane->base.name);
1753 return ret;
1754 }
1755 }
1756
1757 for_each_oldnew_intel_crtc_in_state(state, crtc, old_crtc_state,
1758 new_crtc_state, i) {
1759 u8 old_active_planes, new_active_planes;
1760
1761 ret = icl_check_nv12_planes(state, crtc);
1762 if (ret)
1763 return ret;
1764
1765 /*
1766 * On some platforms the number of active planes affects
1767 * the planes' minimum cdclk calculation. Add such planes
1768 * to the state before we compute the minimum cdclk.
1769 */
1770 if (!active_planes_affects_min_cdclk(display))
1771 continue;
1772
1773 old_active_planes = old_crtc_state->active_planes & ~BIT(PLANE_CURSOR);
1774 new_active_planes = new_crtc_state->active_planes & ~BIT(PLANE_CURSOR);
1775
1776 if (hweight8(old_active_planes) == hweight8(new_active_planes))
1777 continue;
1778
1779 ret = intel_crtc_add_planes_to_state(state, crtc, new_active_planes);
1780 if (ret)
1781 return ret;
1782 }
1783
1784 for_each_new_intel_plane_in_state(state, plane, plane_state, i)
1785 intel_plane_calc_min_cdclk(state, plane);
1786
1787 return 0;
1788 }
1789