treewide: remove redundant IS_ERR() before error code check
[linux/fpc-iii.git] / drivers / gpu / drm / i915 / display / intel_atomic_plane.c
blob3e97af682b1be3ffd9bc2ef5ed3d29527431cac3
1 /*
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
13 * Software.
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.
24 /**
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"
41 #include "intel_pm.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);
60 if (!plane)
61 return ERR_PTR(-ENOMEM);
63 plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL);
64 if (!plane_state) {
65 kfree(plane);
66 return ERR_PTR(-ENOMEM);
69 intel_plane_state_reset(plane_state, plane);
71 plane->base.state = &plane_state->uapi;
73 return plane;
76 void intel_plane_free(struct intel_plane *plane)
78 intel_plane_destroy_state(&plane->base, plane->base.state);
79 kfree(plane);
82 /**
83 * intel_plane_duplicate_state - duplicate plane state
84 * @plane: drm plane
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);
99 if (!intel_state)
100 return NULL;
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
116 * @plane: drm plane
117 * @state: state object to destroy
119 * Destroys the plane state (both common and Intel-specific) for the
120 * specified plane.
122 void
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);
132 kfree(plane_state);
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;
139 unsigned int cpp;
141 if (!plane_state->uapi.visible)
142 return 0;
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)
153 cpp *= 4;
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)
168 return false;
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);
190 return true;
193 return false;
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;
229 int ret;
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)
242 return 0;
244 ret = plane->check_plane(new_crtc_state, new_plane_state);
245 if (ret)
246 return ret;
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);
280 return NULL;
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;
296 if (!crtc)
297 return 0;
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,
303 new_crtc_state,
304 old_plane_state,
305 new_plane_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;
319 int i;
321 if (*update_mask == 0)
322 return NULL;
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)))
329 continue;
331 if (skl_ddb_allocation_overlaps(&crtc_state->wm.skl.plane_ddb_y[plane_id],
332 entries_y,
333 I915_MAX_PLANES, plane_id) ||
334 skl_ddb_allocation_overlaps(&crtc_state->wm.skl.plane_ddb_uv[plane_id],
335 entries_uv,
336 I915_MAX_PLANES, plane_id))
337 continue;
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];
343 return plane;
346 /* should never happen */
347 WARN_ON(1);
349 return NULL;
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,
390 &update_mask))) {
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);
397 } else {
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;
411 int i;
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)))
416 continue;
418 if (new_plane_state->uapi.visible)
419 intel_update_plane(plane, new_crtc_state, new_plane_state);
420 else
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,