xref: /linux/drivers/gpu/drm/i915/display/intel_plane.c (revision 8e65320d91cdc3b241d4b94855c88459b91abf66)
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