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_display_types.h"
42 #include "intel_sprite.h"
44 static void intel_plane_state_reset(struct intel_plane_state
*plane_state
,
45 struct intel_plane
*plane
)
47 memset(plane_state
, 0, sizeof(*plane_state
));
49 __drm_atomic_helper_plane_state_reset(&plane_state
->uapi
, &plane
->base
);
51 plane_state
->scaler_id
= -1;
54 struct intel_plane
*intel_plane_alloc(void)
56 struct intel_plane_state
*plane_state
;
57 struct intel_plane
*plane
;
59 plane
= kzalloc(sizeof(*plane
), GFP_KERNEL
);
61 return ERR_PTR(-ENOMEM
);
63 plane_state
= kzalloc(sizeof(*plane_state
), GFP_KERNEL
);
66 return ERR_PTR(-ENOMEM
);
69 intel_plane_state_reset(plane_state
, plane
);
71 plane
->base
.state
= &plane_state
->uapi
;
76 void intel_plane_free(struct intel_plane
*plane
)
78 intel_plane_destroy_state(&plane
->base
, plane
->base
.state
);
83 * intel_plane_duplicate_state - duplicate plane state
86 * Allocates and returns a copy of the plane state (both common and
87 * Intel-specific) for the specified plane.
89 * Returns: The newly allocated plane state, or NULL on failure.
91 struct drm_plane_state
*
92 intel_plane_duplicate_state(struct drm_plane
*plane
)
94 struct intel_plane_state
*intel_state
;
96 intel_state
= to_intel_plane_state(plane
->state
);
97 intel_state
= kmemdup(intel_state
, sizeof(*intel_state
), GFP_KERNEL
);
102 __drm_atomic_helper_plane_duplicate_state(plane
, &intel_state
->uapi
);
104 intel_state
->vma
= NULL
;
105 intel_state
->flags
= 0;
107 /* add reference to fb */
108 if (intel_state
->hw
.fb
)
109 drm_framebuffer_get(intel_state
->hw
.fb
);
111 return &intel_state
->uapi
;
115 * intel_plane_destroy_state - destroy plane state
117 * @state: state object to destroy
119 * Destroys the plane state (both common and Intel-specific) for the
123 intel_plane_destroy_state(struct drm_plane
*plane
,
124 struct drm_plane_state
*state
)
126 struct intel_plane_state
*plane_state
= to_intel_plane_state(state
);
127 WARN_ON(plane_state
->vma
);
129 __drm_atomic_helper_plane_destroy_state(&plane_state
->uapi
);
130 if (plane_state
->hw
.fb
)
131 drm_framebuffer_put(plane_state
->hw
.fb
);
135 unsigned int intel_plane_data_rate(const struct intel_crtc_state
*crtc_state
,
136 const struct intel_plane_state
*plane_state
)
138 const struct drm_framebuffer
*fb
= plane_state
->hw
.fb
;
141 if (!plane_state
->uapi
.visible
)
144 cpp
= fb
->format
->cpp
[0];
147 * Based on HSD#:1408715493
148 * NV12 cpp == 4, P010 cpp == 8
150 * FIXME what is the logic behind this?
152 if (fb
->format
->is_yuv
&& fb
->format
->num_planes
> 1)
155 return cpp
* crtc_state
->pixel_rate
;
158 bool intel_plane_calc_min_cdclk(struct intel_atomic_state
*state
,
159 struct intel_plane
*plane
)
161 struct drm_i915_private
*dev_priv
= to_i915(plane
->base
.dev
);
162 const struct intel_plane_state
*plane_state
=
163 intel_atomic_get_new_plane_state(state
, plane
);
164 struct intel_crtc
*crtc
= to_intel_crtc(plane_state
->hw
.crtc
);
165 struct intel_crtc_state
*crtc_state
;
167 if (!plane_state
->uapi
.visible
|| !plane
->min_cdclk
)
170 crtc_state
= intel_atomic_get_new_crtc_state(state
, crtc
);
172 crtc_state
->min_cdclk
[plane
->id
] =
173 plane
->min_cdclk(crtc_state
, plane_state
);
176 * Does the cdclk need to be bumbed up?
178 * Note: we obviously need to be called before the new
179 * cdclk frequency is calculated so state->cdclk.logical
180 * hasn't been populated yet. Hence we look at the old
181 * cdclk state under dev_priv->cdclk.logical. This is
182 * safe as long we hold at least one crtc mutex (which
183 * must be true since we have crtc_state).
185 if (crtc_state
->min_cdclk
[plane
->id
] > dev_priv
->cdclk
.logical
.cdclk
) {
186 DRM_DEBUG_KMS("[PLANE:%d:%s] min_cdclk (%d kHz) > logical cdclk (%d kHz)\n",
187 plane
->base
.base
.id
, plane
->base
.name
,
188 crtc_state
->min_cdclk
[plane
->id
],
189 dev_priv
->cdclk
.logical
.cdclk
);
196 static void intel_plane_clear_hw_state(struct intel_plane_state
*plane_state
)
198 if (plane_state
->hw
.fb
)
199 drm_framebuffer_put(plane_state
->hw
.fb
);
201 memset(&plane_state
->hw
, 0, sizeof(plane_state
->hw
));
204 void intel_plane_copy_uapi_to_hw_state(struct intel_plane_state
*plane_state
,
205 const struct intel_plane_state
*from_plane_state
)
207 intel_plane_clear_hw_state(plane_state
);
209 plane_state
->hw
.crtc
= from_plane_state
->uapi
.crtc
;
210 plane_state
->hw
.fb
= from_plane_state
->uapi
.fb
;
211 if (plane_state
->hw
.fb
)
212 drm_framebuffer_get(plane_state
->hw
.fb
);
214 plane_state
->hw
.alpha
= from_plane_state
->uapi
.alpha
;
215 plane_state
->hw
.pixel_blend_mode
=
216 from_plane_state
->uapi
.pixel_blend_mode
;
217 plane_state
->hw
.rotation
= from_plane_state
->uapi
.rotation
;
218 plane_state
->hw
.color_encoding
= from_plane_state
->uapi
.color_encoding
;
219 plane_state
->hw
.color_range
= from_plane_state
->uapi
.color_range
;
222 int intel_plane_atomic_check_with_state(const struct intel_crtc_state
*old_crtc_state
,
223 struct intel_crtc_state
*new_crtc_state
,
224 const struct intel_plane_state
*old_plane_state
,
225 struct intel_plane_state
*new_plane_state
)
227 struct intel_plane
*plane
= to_intel_plane(new_plane_state
->uapi
.plane
);
228 const struct drm_framebuffer
*fb
;
231 intel_plane_copy_uapi_to_hw_state(new_plane_state
, new_plane_state
);
232 fb
= new_plane_state
->hw
.fb
;
234 new_crtc_state
->active_planes
&= ~BIT(plane
->id
);
235 new_crtc_state
->nv12_planes
&= ~BIT(plane
->id
);
236 new_crtc_state
->c8_planes
&= ~BIT(plane
->id
);
237 new_crtc_state
->data_rate
[plane
->id
] = 0;
238 new_crtc_state
->min_cdclk
[plane
->id
] = 0;
239 new_plane_state
->uapi
.visible
= false;
241 if (!new_plane_state
->hw
.crtc
&& !old_plane_state
->hw
.crtc
)
244 ret
= plane
->check_plane(new_crtc_state
, new_plane_state
);
248 /* FIXME pre-g4x don't work like this */
249 if (new_plane_state
->uapi
.visible
)
250 new_crtc_state
->active_planes
|= BIT(plane
->id
);
252 if (new_plane_state
->uapi
.visible
&&
253 intel_format_info_is_yuv_semiplanar(fb
->format
, fb
->modifier
))
254 new_crtc_state
->nv12_planes
|= BIT(plane
->id
);
256 if (new_plane_state
->uapi
.visible
&&
257 fb
->format
->format
== DRM_FORMAT_C8
)
258 new_crtc_state
->c8_planes
|= BIT(plane
->id
);
260 if (new_plane_state
->uapi
.visible
|| old_plane_state
->uapi
.visible
)
261 new_crtc_state
->update_planes
|= BIT(plane
->id
);
263 new_crtc_state
->data_rate
[plane
->id
] =
264 intel_plane_data_rate(new_crtc_state
, new_plane_state
);
266 return intel_plane_atomic_calc_changes(old_crtc_state
, new_crtc_state
,
267 old_plane_state
, new_plane_state
);
270 static struct intel_crtc
*
271 get_crtc_from_states(const struct intel_plane_state
*old_plane_state
,
272 const struct intel_plane_state
*new_plane_state
)
274 if (new_plane_state
->uapi
.crtc
)
275 return to_intel_crtc(new_plane_state
->uapi
.crtc
);
277 if (old_plane_state
->uapi
.crtc
)
278 return to_intel_crtc(old_plane_state
->uapi
.crtc
);
283 int intel_plane_atomic_check(struct intel_atomic_state
*state
,
284 struct intel_plane
*plane
)
286 struct intel_plane_state
*new_plane_state
=
287 intel_atomic_get_new_plane_state(state
, plane
);
288 const struct intel_plane_state
*old_plane_state
=
289 intel_atomic_get_old_plane_state(state
, plane
);
290 struct intel_crtc
*crtc
=
291 get_crtc_from_states(old_plane_state
, new_plane_state
);
292 const struct intel_crtc_state
*old_crtc_state
;
293 struct intel_crtc_state
*new_crtc_state
;
295 new_plane_state
->uapi
.visible
= false;
299 old_crtc_state
= intel_atomic_get_old_crtc_state(state
, crtc
);
300 new_crtc_state
= intel_atomic_get_new_crtc_state(state
, crtc
);
302 return intel_plane_atomic_check_with_state(old_crtc_state
,
308 static struct intel_plane
*
309 skl_next_plane_to_commit(struct intel_atomic_state
*state
,
310 struct intel_crtc
*crtc
,
311 struct skl_ddb_entry entries_y
[I915_MAX_PLANES
],
312 struct skl_ddb_entry entries_uv
[I915_MAX_PLANES
],
313 unsigned int *update_mask
)
315 struct intel_crtc_state
*crtc_state
=
316 intel_atomic_get_new_crtc_state(state
, crtc
);
317 struct intel_plane_state
*plane_state
;
318 struct intel_plane
*plane
;
321 if (*update_mask
== 0)
324 for_each_new_intel_plane_in_state(state
, plane
, plane_state
, i
) {
325 enum plane_id plane_id
= plane
->id
;
327 if (crtc
->pipe
!= plane
->pipe
||
328 !(*update_mask
& BIT(plane_id
)))
331 if (skl_ddb_allocation_overlaps(&crtc_state
->wm
.skl
.plane_ddb_y
[plane_id
],
333 I915_MAX_PLANES
, plane_id
) ||
334 skl_ddb_allocation_overlaps(&crtc_state
->wm
.skl
.plane_ddb_uv
[plane_id
],
336 I915_MAX_PLANES
, plane_id
))
339 *update_mask
&= ~BIT(plane_id
);
340 entries_y
[plane_id
] = crtc_state
->wm
.skl
.plane_ddb_y
[plane_id
];
341 entries_uv
[plane_id
] = crtc_state
->wm
.skl
.plane_ddb_uv
[plane_id
];
346 /* should never happen */
352 void intel_update_plane(struct intel_plane
*plane
,
353 const struct intel_crtc_state
*crtc_state
,
354 const struct intel_plane_state
*plane_state
)
356 struct intel_crtc
*crtc
= to_intel_crtc(crtc_state
->uapi
.crtc
);
358 trace_intel_update_plane(&plane
->base
, crtc
);
359 plane
->update_plane(plane
, crtc_state
, plane_state
);
362 void intel_disable_plane(struct intel_plane
*plane
,
363 const struct intel_crtc_state
*crtc_state
)
365 struct intel_crtc
*crtc
= to_intel_crtc(crtc_state
->uapi
.crtc
);
367 trace_intel_disable_plane(&plane
->base
, crtc
);
368 plane
->disable_plane(plane
, crtc_state
);
371 void skl_update_planes_on_crtc(struct intel_atomic_state
*state
,
372 struct intel_crtc
*crtc
)
374 struct intel_crtc_state
*old_crtc_state
=
375 intel_atomic_get_old_crtc_state(state
, crtc
);
376 struct intel_crtc_state
*new_crtc_state
=
377 intel_atomic_get_new_crtc_state(state
, crtc
);
378 struct skl_ddb_entry entries_y
[I915_MAX_PLANES
];
379 struct skl_ddb_entry entries_uv
[I915_MAX_PLANES
];
380 u32 update_mask
= new_crtc_state
->update_planes
;
381 struct intel_plane
*plane
;
383 memcpy(entries_y
, old_crtc_state
->wm
.skl
.plane_ddb_y
,
384 sizeof(old_crtc_state
->wm
.skl
.plane_ddb_y
));
385 memcpy(entries_uv
, old_crtc_state
->wm
.skl
.plane_ddb_uv
,
386 sizeof(old_crtc_state
->wm
.skl
.plane_ddb_uv
));
388 while ((plane
= skl_next_plane_to_commit(state
, crtc
,
389 entries_y
, entries_uv
,
391 struct intel_plane_state
*new_plane_state
=
392 intel_atomic_get_new_plane_state(state
, plane
);
394 if (new_plane_state
->uapi
.visible
||
395 new_plane_state
->planar_slave
) {
396 intel_update_plane(plane
, new_crtc_state
, new_plane_state
);
398 intel_disable_plane(plane
, new_crtc_state
);
403 void i9xx_update_planes_on_crtc(struct intel_atomic_state
*state
,
404 struct intel_crtc
*crtc
)
406 struct intel_crtc_state
*new_crtc_state
=
407 intel_atomic_get_new_crtc_state(state
, crtc
);
408 u32 update_mask
= new_crtc_state
->update_planes
;
409 struct intel_plane_state
*new_plane_state
;
410 struct intel_plane
*plane
;
413 for_each_new_intel_plane_in_state(state
, plane
, new_plane_state
, i
) {
414 if (crtc
->pipe
!= plane
->pipe
||
415 !(update_mask
& BIT(plane
->id
)))
418 if (new_plane_state
->uapi
.visible
)
419 intel_update_plane(plane
, new_crtc_state
, new_plane_state
);
421 intel_disable_plane(plane
, new_crtc_state
);
425 const struct drm_plane_helper_funcs intel_plane_helper_funcs
= {
426 .prepare_fb
= intel_prepare_plane_fb
,
427 .cleanup_fb
= intel_cleanup_plane_fb
,