2 * Copyright © 2014 Intel Corporation
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:
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
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.
25 * DOC: atomic plane helpers
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.
34 #include <drm/drm_atomic_helper.h>
35 #include <drm/drm_fourcc.h>
36 #include <drm/drm_plane_helper.h>
38 #include "i915_trace.h"
39 #include "intel_atomic_plane.h"
40 #include "intel_cdclk.h"
41 #include "intel_display_types.h"
43 #include "intel_sprite.h"
45 static void intel_plane_state_reset(struct intel_plane_state
*plane_state
,
46 struct intel_plane
*plane
)
48 memset(plane_state
, 0, sizeof(*plane_state
));
50 __drm_atomic_helper_plane_state_reset(&plane_state
->uapi
, &plane
->base
);
52 plane_state
->scaler_id
= -1;
55 struct intel_plane
*intel_plane_alloc(void)
57 struct intel_plane_state
*plane_state
;
58 struct intel_plane
*plane
;
60 plane
= kzalloc(sizeof(*plane
), GFP_KERNEL
);
62 return ERR_PTR(-ENOMEM
);
64 plane_state
= kzalloc(sizeof(*plane_state
), GFP_KERNEL
);
67 return ERR_PTR(-ENOMEM
);
70 intel_plane_state_reset(plane_state
, plane
);
72 plane
->base
.state
= &plane_state
->uapi
;
77 void intel_plane_free(struct intel_plane
*plane
)
79 intel_plane_destroy_state(&plane
->base
, plane
->base
.state
);
84 * intel_plane_duplicate_state - duplicate plane state
87 * Allocates and returns a copy of the plane state (both common and
88 * Intel-specific) for the specified plane.
90 * Returns: The newly allocated plane state, or NULL on failure.
92 struct drm_plane_state
*
93 intel_plane_duplicate_state(struct drm_plane
*plane
)
95 struct intel_plane_state
*intel_state
;
97 intel_state
= to_intel_plane_state(plane
->state
);
98 intel_state
= kmemdup(intel_state
, sizeof(*intel_state
), GFP_KERNEL
);
103 __drm_atomic_helper_plane_duplicate_state(plane
, &intel_state
->uapi
);
105 intel_state
->vma
= NULL
;
106 intel_state
->flags
= 0;
108 /* add reference to fb */
109 if (intel_state
->hw
.fb
)
110 drm_framebuffer_get(intel_state
->hw
.fb
);
112 return &intel_state
->uapi
;
116 * intel_plane_destroy_state - destroy plane state
118 * @state: state object to destroy
120 * Destroys the plane state (both common and Intel-specific) for the
124 intel_plane_destroy_state(struct drm_plane
*plane
,
125 struct drm_plane_state
*state
)
127 struct intel_plane_state
*plane_state
= to_intel_plane_state(state
);
128 drm_WARN_ON(plane
->dev
, plane_state
->vma
);
130 __drm_atomic_helper_plane_destroy_state(&plane_state
->uapi
);
131 if (plane_state
->hw
.fb
)
132 drm_framebuffer_put(plane_state
->hw
.fb
);
136 unsigned int intel_plane_pixel_rate(const struct intel_crtc_state
*crtc_state
,
137 const struct intel_plane_state
*plane_state
)
139 unsigned int src_w
, src_h
, dst_w
, dst_h
;
140 unsigned int pixel_rate
= crtc_state
->pixel_rate
;
142 src_w
= drm_rect_width(&plane_state
->uapi
.src
) >> 16;
143 src_h
= drm_rect_height(&plane_state
->uapi
.src
) >> 16;
144 dst_w
= drm_rect_width(&plane_state
->uapi
.dst
);
145 dst_h
= drm_rect_height(&plane_state
->uapi
.dst
);
147 /* Downscaling limits the maximum pixel rate */
148 dst_w
= min(src_w
, dst_w
);
149 dst_h
= min(src_h
, dst_h
);
151 return DIV_ROUND_UP_ULL(mul_u32_u32(pixel_rate
, src_w
* src_h
),
155 unsigned int intel_plane_data_rate(const struct intel_crtc_state
*crtc_state
,
156 const struct intel_plane_state
*plane_state
)
158 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
160 unsigned int pixel_rate
;
162 if (!plane_state
->uapi
.visible
)
165 pixel_rate
= intel_plane_pixel_rate(crtc_state
, plane_state
);
167 cpp
= fb
->format
->cpp
[0];
170 * Based on HSD#:1408715493
171 * NV12 cpp == 4, P010 cpp == 8
173 * FIXME what is the logic behind this?
175 if (fb
->format
->is_yuv
&& fb
->format
->num_planes
> 1)
178 return pixel_rate
* cpp
;
181 int intel_plane_calc_min_cdclk(struct intel_atomic_state
*state
,
182 struct intel_plane
*plane
,
183 bool *need_cdclk_calc
)
185 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
186 const struct intel_plane_state
*plane_state
=
187 intel_atomic_get_new_plane_state(state
, plane
);
188 struct intel_crtc
*crtc
= to_intel_crtc(plane_state
->hw
.crtc
);
189 const struct intel_cdclk_state
*cdclk_state
;
190 const struct intel_crtc_state
*old_crtc_state
;
191 struct intel_crtc_state
*new_crtc_state
;
193 if (!plane_state
->uapi
.visible
|| !plane
->min_cdclk
)
196 old_crtc_state
= intel_atomic_get_old_crtc_state(state
, crtc
);
197 new_crtc_state
= intel_atomic_get_new_crtc_state(state
, crtc
);
199 new_crtc_state
->min_cdclk
[plane
->id
] =
200 plane
->min_cdclk(new_crtc_state
, plane_state
);
203 * No need to check against the cdclk state if
204 * the min cdclk for the plane doesn't increase.
206 * Ie. we only ever increase the cdclk due to plane
207 * requirements. This can reduce back and forth
208 * display blinking due to constant cdclk changes.
210 if (new_crtc_state
->min_cdclk
[plane
->id
] <=
211 old_crtc_state
->min_cdclk
[plane
->id
])
214 cdclk_state
= intel_atomic_get_cdclk_state(state
);
215 if (IS_ERR(cdclk_state
))
216 return PTR_ERR(cdclk_state
);
219 * No need to recalculate the cdclk state if
220 * the min cdclk for the pipe doesn't increase.
222 * Ie. we only ever increase the cdclk due to plane
223 * requirements. This can reduce back and forth
224 * display blinking due to constant cdclk changes.
226 if (new_crtc_state
->min_cdclk
[plane
->id
] <=
227 cdclk_state
->min_cdclk
[crtc
->pipe
])
230 drm_dbg_kms(&dev_priv
->drm
,
231 "[PLANE:%d:%s] min cdclk (%d kHz) > [CRTC:%d:%s] min cdclk (%d kHz)\n",
232 plane
->base
.base
.id
, plane
->base
.name
,
233 new_crtc_state
->min_cdclk
[plane
->id
],
234 crtc
->base
.base
.id
, crtc
->base
.name
,
235 cdclk_state
->min_cdclk
[crtc
->pipe
]);
236 *need_cdclk_calc
= true;
241 static void intel_plane_clear_hw_state(struct intel_plane_state
*plane_state
)
243 if (plane_state
->hw
.fb
)
244 drm_framebuffer_put(plane_state
->hw
.fb
);
246 memset(&plane_state
->hw
, 0, sizeof(plane_state
->hw
));
249 void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state
*plane_state
,
250 const struct intel_plane_state
*from_plane_state
,
251 struct intel_crtc
*crtc
)
253 intel_plane_clear_hw_state(plane_state
);
256 * For the bigjoiner slave uapi.crtc will point at
257 * the master crtc. So we explicitly assign the right
258 * slave crtc to hw.crtc. uapi.crtc!=NULL simply indicates
259 * the plane is logically enabled on the uapi level.
261 plane_state
->hw
.crtc
= from_plane_state
->uapi
.crtc
? &crtc
->base
: NULL
;
263 plane_state
->hw
.fb
= from_plane_state
->uapi
.fb
;
264 if (plane_state
->hw
.fb
)
265 drm_framebuffer_get(plane_state
->hw
.fb
);
267 plane_state
->hw
.alpha
= from_plane_state
->uapi
.alpha
;
268 plane_state
->hw
.pixel_blend_mode
=
269 from_plane_state
->uapi
.pixel_blend_mode
;
270 plane_state
->hw
.rotation
= from_plane_state
->uapi
.rotation
;
271 plane_state
->hw
.color_encoding
= from_plane_state
->uapi
.color_encoding
;
272 plane_state
->hw
.color_range
= from_plane_state
->uapi
.color_range
;
273 plane_state
->hw
.scaling_filter
= from_plane_state
->uapi
.scaling_filter
;
275 plane_state
->uapi
.src
= drm_plane_state_src(&from_plane_state
->uapi
);
276 plane_state
->uapi
.dst
= drm_plane_state_dest(&from_plane_state
->uapi
);
279 void intel_plane_copy_hw_state(struct intel_plane_state
*plane_state
,
280 const struct intel_plane_state
*from_plane_state
)
282 intel_plane_clear_hw_state(plane_state
);
284 memcpy(&plane_state
->hw
, &from_plane_state
->hw
,
285 sizeof(plane_state
->hw
));
287 if (plane_state
->hw
.fb
)
288 drm_framebuffer_get(plane_state
->hw
.fb
);
291 void intel_plane_set_invisible(struct intel_crtc_state
*crtc_state
,
292 struct intel_plane_state
*plane_state
)
294 struct intel_plane
*plane
= to_intel_plane(plane_state
->uapi
.plane
);
296 crtc_state
->active_planes
&= ~BIT(plane
->id
);
297 crtc_state
->nv12_planes
&= ~BIT(plane
->id
);
298 crtc_state
->c8_planes
&= ~BIT(plane
->id
);
299 crtc_state
->data_rate
[plane
->id
] = 0;
300 crtc_state
->min_cdclk
[plane
->id
] = 0;
302 plane_state
->uapi
.visible
= false;
305 int intel_plane_atomic_check_with_state(const struct intel_crtc_state
*old_crtc_state
,
306 struct intel_crtc_state
*new_crtc_state
,
307 const struct intel_plane_state
*old_plane_state
,
308 struct intel_plane_state
*new_plane_state
)
310 struct intel_plane
*plane
= to_intel_plane(new_plane_state
->uapi
.plane
);
311 const struct drm_framebuffer
*fb
= new_plane_state
->hw
.fb
;
314 intel_plane_set_invisible(new_crtc_state
, new_plane_state
);
316 if (!new_plane_state
->hw
.crtc
&& !old_plane_state
->hw
.crtc
)
319 ret
= plane
->check_plane(new_crtc_state
, new_plane_state
);
323 /* FIXME pre-g4x don't work like this */
324 if (new_plane_state
->uapi
.visible
)
325 new_crtc_state
->active_planes
|= BIT(plane
->id
);
327 if (new_plane_state
->uapi
.visible
&&
328 intel_format_info_is_yuv_semiplanar(fb
->format
, fb
->modifier
))
329 new_crtc_state
->nv12_planes
|= BIT(plane
->id
);
331 if (new_plane_state
->uapi
.visible
&&
332 fb
->format
->format
== DRM_FORMAT_C8
)
333 new_crtc_state
->c8_planes
|= BIT(plane
->id
);
335 if (new_plane_state
->uapi
.visible
|| old_plane_state
->uapi
.visible
)
336 new_crtc_state
->update_planes
|= BIT(plane
->id
);
338 new_crtc_state
->data_rate
[plane
->id
] =
339 intel_plane_data_rate(new_crtc_state
, new_plane_state
);
341 return intel_plane_atomic_calc_changes(old_crtc_state
, new_crtc_state
,
342 old_plane_state
, new_plane_state
);
345 static struct intel_plane
*
346 intel_crtc_get_plane(struct intel_crtc
*crtc
, enum plane_id plane_id
)
348 struct drm_i915_private
*i915
= to_i915(crtc
->base
.dev
);
349 struct intel_plane
*plane
;
351 for_each_intel_plane_on_crtc(&i915
->drm
, crtc
, plane
) {
352 if (plane
->id
== plane_id
)
359 int intel_plane_atomic_check(struct intel_atomic_state
*state
,
360 struct intel_plane
*plane
)
362 struct drm_i915_private
*i915
= to_i915(state
->base
.dev
);
363 struct intel_plane_state
*new_plane_state
=
364 intel_atomic_get_new_plane_state(state
, plane
);
365 const struct intel_plane_state
*old_plane_state
=
366 intel_atomic_get_old_plane_state(state
, plane
);
367 const struct intel_plane_state
*new_master_plane_state
;
368 struct intel_crtc
*crtc
= intel_get_crtc_for_pipe(i915
, plane
->pipe
);
369 const struct intel_crtc_state
*old_crtc_state
=
370 intel_atomic_get_old_crtc_state(state
, crtc
);
371 struct intel_crtc_state
*new_crtc_state
=
372 intel_atomic_get_new_crtc_state(state
, crtc
);
374 if (new_crtc_state
&& new_crtc_state
->bigjoiner_slave
) {
375 struct intel_plane
*master_plane
=
376 intel_crtc_get_plane(new_crtc_state
->bigjoiner_linked_crtc
,
379 new_master_plane_state
=
380 intel_atomic_get_new_plane_state(state
, master_plane
);
382 new_master_plane_state
= new_plane_state
;
385 intel_plane_copy_uapi_to_hw_state(new_plane_state
,
386 new_master_plane_state
,
389 new_plane_state
->uapi
.visible
= false;
393 return intel_plane_atomic_check_with_state(old_crtc_state
,
399 static struct intel_plane
*
400 skl_next_plane_to_commit(struct intel_atomic_state
*state
,
401 struct intel_crtc
*crtc
,
402 struct skl_ddb_entry entries_y
[I915_MAX_PLANES
],
403 struct skl_ddb_entry entries_uv
[I915_MAX_PLANES
],
404 unsigned int *update_mask
)
406 struct intel_crtc_state
*crtc_state
=
407 intel_atomic_get_new_crtc_state(state
, crtc
);
408 struct intel_plane_state
*plane_state
;
409 struct intel_plane
*plane
;
412 if (*update_mask
== 0)
415 for_each_new_intel_plane_in_state(state
, plane
, plane_state
, i
) {
416 enum plane_id plane_id
= plane
->id
;
418 if (crtc
->pipe
!= plane
->pipe
||
419 !(*update_mask
& BIT(plane_id
)))
422 if (skl_ddb_allocation_overlaps(&crtc_state
->wm
.skl
.plane_ddb_y
[plane_id
],
424 I915_MAX_PLANES
, plane_id
) ||
425 skl_ddb_allocation_overlaps(&crtc_state
->wm
.skl
.plane_ddb_uv
[plane_id
],
427 I915_MAX_PLANES
, plane_id
))
430 *update_mask
&= ~BIT(plane_id
);
431 entries_y
[plane_id
] = crtc_state
->wm
.skl
.plane_ddb_y
[plane_id
];
432 entries_uv
[plane_id
] = crtc_state
->wm
.skl
.plane_ddb_uv
[plane_id
];
437 /* should never happen */
438 drm_WARN_ON(state
->base
.dev
, 1);
443 void intel_update_plane(struct intel_plane
*plane
,
444 const struct intel_crtc_state
*crtc_state
,
445 const struct intel_plane_state
*plane_state
)
447 struct intel_crtc
*crtc
= to_intel_crtc(crtc_state
->uapi
.crtc
);
449 trace_intel_update_plane(&plane
->base
, crtc
);
451 if (crtc_state
->uapi
.async_flip
&& plane
->async_flip
)
452 plane
->async_flip(plane
, crtc_state
, plane_state
);
454 plane
->update_plane(plane
, crtc_state
, plane_state
);
457 void intel_disable_plane(struct intel_plane
*plane
,
458 const struct intel_crtc_state
*crtc_state
)
460 struct intel_crtc
*crtc
= to_intel_crtc(crtc_state
->uapi
.crtc
);
462 trace_intel_disable_plane(&plane
->base
, crtc
);
463 plane
->disable_plane(plane
, crtc_state
);
466 void skl_update_planes_on_crtc(struct intel_atomic_state
*state
,
467 struct intel_crtc
*crtc
)
469 struct intel_crtc_state
*old_crtc_state
=
470 intel_atomic_get_old_crtc_state(state
, crtc
);
471 struct intel_crtc_state
*new_crtc_state
=
472 intel_atomic_get_new_crtc_state(state
, crtc
);
473 struct skl_ddb_entry entries_y
[I915_MAX_PLANES
];
474 struct skl_ddb_entry entries_uv
[I915_MAX_PLANES
];
475 u32 update_mask
= new_crtc_state
->update_planes
;
476 struct intel_plane
*plane
;
478 memcpy(entries_y
, old_crtc_state
->wm
.skl
.plane_ddb_y
,
479 sizeof(old_crtc_state
->wm
.skl
.plane_ddb_y
));
480 memcpy(entries_uv
, old_crtc_state
->wm
.skl
.plane_ddb_uv
,
481 sizeof(old_crtc_state
->wm
.skl
.plane_ddb_uv
));
483 while ((plane
= skl_next_plane_to_commit(state
, crtc
,
484 entries_y
, entries_uv
,
486 struct intel_plane_state
*new_plane_state
=
487 intel_atomic_get_new_plane_state(state
, plane
);
489 if (new_plane_state
->uapi
.visible
||
490 new_plane_state
->planar_slave
) {
491 intel_update_plane(plane
, new_crtc_state
, new_plane_state
);
493 intel_disable_plane(plane
, new_crtc_state
);
498 void i9xx_update_planes_on_crtc(struct intel_atomic_state
*state
,
499 struct intel_crtc
*crtc
)
501 struct intel_crtc_state
*new_crtc_state
=
502 intel_atomic_get_new_crtc_state(state
, crtc
);
503 u32 update_mask
= new_crtc_state
->update_planes
;
504 struct intel_plane_state
*new_plane_state
;
505 struct intel_plane
*plane
;
508 for_each_new_intel_plane_in_state(state
, plane
, new_plane_state
, i
) {
509 if (crtc
->pipe
!= plane
->pipe
||
510 !(update_mask
& BIT(plane
->id
)))
513 if (new_plane_state
->uapi
.visible
)
514 intel_update_plane(plane
, new_crtc_state
, new_plane_state
);
516 intel_disable_plane(plane
, new_crtc_state
);
520 int intel_atomic_plane_check_clipping(struct intel_plane_state
*plane_state
,
521 struct intel_crtc_state
*crtc_state
,
522 int min_scale
, int max_scale
,
525 struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
526 struct drm_rect
*src
= &plane_state
->uapi
.src
;
527 struct drm_rect
*dst
= &plane_state
->uapi
.dst
;
528 unsigned int rotation
= plane_state
->hw
.rotation
;
529 struct drm_rect clip
= {};
533 plane_state
->uapi
.visible
= false;
537 drm_rect_rotate(src
, fb
->width
<< 16, fb
->height
<< 16, rotation
);
540 hscale
= drm_rect_calc_hscale(src
, dst
, min_scale
, max_scale
);
541 vscale
= drm_rect_calc_vscale(src
, dst
, min_scale
, max_scale
);
542 if (hscale
< 0 || vscale
< 0) {
543 DRM_DEBUG_KMS("Invalid scaling of plane\n");
544 drm_rect_debug_print("src: ", src
, true);
545 drm_rect_debug_print("dst: ", dst
, false);
549 if (crtc_state
->hw
.enable
) {
550 clip
.x2
= crtc_state
->pipe_src_w
;
551 clip
.y2
= crtc_state
->pipe_src_h
;
554 /* right side of the image is on the slave crtc, adjust dst to match */
555 if (crtc_state
->bigjoiner_slave
)
556 drm_rect_translate(dst
, -crtc_state
->pipe_src_w
, 0);
559 * FIXME: This might need further adjustment for seamless scaling
560 * with phase information, for the 2p2 and 2p1 scenarios.
562 plane_state
->uapi
.visible
= drm_rect_clip_scaled(src
, dst
, &clip
);
564 drm_rect_rotate_inv(src
, fb
->width
<< 16, fb
->height
<< 16, rotation
);
566 if (!can_position
&& plane_state
->uapi
.visible
&&
567 !drm_rect_equals(dst
, &clip
)) {
568 DRM_DEBUG_KMS("Plane must cover entire CRTC\n");
569 drm_rect_debug_print("dst: ", dst
, false);
570 drm_rect_debug_print("clip: ", &clip
, false);
577 const struct drm_plane_helper_funcs intel_plane_helper_funcs
= {
578 .prepare_fb
= intel_prepare_plane_fb
,
579 .cleanup_fb
= intel_cleanup_plane_fb
,