Skip to content

Commit ea2c67b

Browse files
mattropedanvet
authored andcommitted
drm/i915: Move to atomic plane helpers (v9)
Switch plane handling to use the atomic plane helpers. This means that rather than provide our own implementations of .update_plane() and .disable_plane(), we expose the lower-level check/prepare/commit/cleanup entrypoints and let the DRM core implement update/disable for us using those entrypoints. The other main change that falls out of this patch is that our drm_plane's will now always have a valid plane->state that contains the relevant plane state (initial state is allocated at plane creation). The base drm_plane_state pointed to holds the requested source/dest coordinates, and the subclassed intel_plane_state holds the adjusted values that our driver actually uses. v2: - Renamed file from intel_atomic.c to intel_atomic_plane.c (Daniel) - Fix a copy/paste comment mistake (Bob) v3: - Use prepare/cleanup functions that we've already factored out - Use newly refactored pre_commit/commit/post_commit to avoid sleeping during vblank evasion v4: - Rebase to latest di-nightly requires adding an 'old_state' parameter to atomic_update; v5: - Must have botched a rebase somewhere and lost some work. Restore state 'dirty' flag to let begin/end code know which planes to run the pre_commit/post_commit hooks for. This would have actually shown up as broken in the next commit rather than this one. v6: - Squash kerneldoc patch into this one. - Previous patches have now already taken care of most of the infrastructure that used to be in this patch. All we're adding here now is some thin wrappers. v7: - Check return of intel_plane_duplicate_state() for allocation failures. v8: - Drop unused drm_plane_state -> intel_plane_state cast. (Ander) - Squash in actual transition to plane helpers. Significant refactoring earlier in the patchset has made the combined prep+transition much easier to swallow than it was in earlier iterations. (Ander) v9: - s/track_fbs/disabled_planes/ in the atomic crtc flags. The only fb's we need to update frontbuffer tracking for are those on a plane about to be disabled (since the atomic helpers never call prepare_fb() when disabling a plane), so the new name more accurately describes what we're actually tracking. Testcase: igt/kms_plane Testcase: igt/kms_universal_plane Testcase: igt/kms_cursor_crc Signed-off-by: Matt Roper <matthew.d.roper@intel.com> Reviewed-by: Ander Conselvan de Oliveira <conselvan2@gmail.com> Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
1 parent 4a3b876 commit ea2c67b

File tree

6 files changed

+303
-165
lines changed

6 files changed

+303
-165
lines changed

Documentation/DocBook/drm.tmpl

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3931,6 +3931,11 @@ int num_ioctls;</synopsis>
39313931
framebuffer compression and panel self refresh.
39323932
</para>
39333933
</sect2>
3934+
<sect2>
3935+
<title>Atomic Plane Helpers</title>
3936+
!Pdrivers/gpu/drm/i915/intel_atomic_plane.c atomic plane helpers
3937+
!Idrivers/gpu/drm/i915/intel_atomic_plane.c
3938+
</sect2>
39343939
<sect2>
39353940
<title>Output Probing</title>
39363941
<para>

drivers/gpu/drm/i915/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ i915-y += dvo_ch7017.o \
6666
dvo_ns2501.o \
6767
dvo_sil164.o \
6868
dvo_tfp410.o \
69+
intel_atomic_plane.o \
6970
intel_crt.o \
7071
intel_ddi.o \
7172
intel_dp.o \
Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
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 helper support
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 <drm/drmP.h>
35+
#include <drm/drm_atomic_helper.h>
36+
#include <drm/drm_plane_helper.h>
37+
#include "intel_drv.h"
38+
39+
/**
40+
* intel_plane_duplicate_state - duplicate plane state
41+
* @plane: drm plane
42+
*
43+
* Allocates and returns a copy of the plane state (both common and
44+
* Intel-specific) for the specified plane.
45+
*
46+
* Returns: The newly allocated plane state, or NULL or failure.
47+
*/
48+
struct drm_plane_state *
49+
intel_plane_duplicate_state(struct drm_plane *plane)
50+
{
51+
struct intel_plane_state *state;
52+
53+
if (plane->state)
54+
state = kmemdup(plane->state, sizeof(*state), GFP_KERNEL);
55+
else
56+
state = kzalloc(sizeof(*state), GFP_KERNEL);
57+
58+
if (!state)
59+
return NULL;
60+
61+
if (state->base.fb)
62+
drm_framebuffer_reference(state->base.fb);
63+
64+
return &state->base;
65+
}
66+
67+
/**
68+
* intel_plane_destroy_state - destroy plane state
69+
* @plane: drm plane
70+
*
71+
* Destroys the plane state (both common and Intel-specific) for the
72+
* specified plane.
73+
*/
74+
void
75+
intel_plane_destroy_state(struct drm_plane *plane,
76+
struct drm_plane_state *state)
77+
{
78+
drm_atomic_helper_plane_destroy_state(plane, state);
79+
}
80+
81+
static int intel_plane_atomic_check(struct drm_plane *plane,
82+
struct drm_plane_state *state)
83+
{
84+
struct drm_crtc *crtc = state->crtc;
85+
struct intel_crtc *intel_crtc;
86+
struct intel_plane *intel_plane = to_intel_plane(plane);
87+
struct intel_plane_state *intel_state = to_intel_plane_state(state);
88+
89+
crtc = crtc ? crtc : plane->crtc;
90+
intel_crtc = to_intel_crtc(crtc);
91+
92+
/*
93+
* The original src/dest coordinates are stored in state->base, but
94+
* we want to keep another copy internal to our driver that we can
95+
* clip/modify ourselves.
96+
*/
97+
intel_state->src.x1 = state->src_x;
98+
intel_state->src.y1 = state->src_y;
99+
intel_state->src.x2 = state->src_x + state->src_w;
100+
intel_state->src.y2 = state->src_y + state->src_h;
101+
intel_state->dst.x1 = state->crtc_x;
102+
intel_state->dst.y1 = state->crtc_y;
103+
intel_state->dst.x2 = state->crtc_x + state->crtc_w;
104+
intel_state->dst.y2 = state->crtc_y + state->crtc_h;
105+
106+
/* Clip all planes to CRTC size, or 0x0 if CRTC is disabled */
107+
intel_state->clip.x1 = 0;
108+
intel_state->clip.y1 = 0;
109+
intel_state->clip.x2 =
110+
intel_crtc->active ? intel_crtc->config.pipe_src_w : 0;
111+
intel_state->clip.y2 =
112+
intel_crtc->active ? intel_crtc->config.pipe_src_h : 0;
113+
114+
/*
115+
* Disabling a plane is always okay; we just need to update
116+
* fb tracking in a special way since cleanup_fb() won't
117+
* get called by the plane helpers.
118+
*/
119+
if (state->fb == NULL && plane->state->fb != NULL) {
120+
/*
121+
* 'prepare' is never called when plane is being disabled, so
122+
* we need to handle frontbuffer tracking as a special case
123+
*/
124+
intel_crtc->atomic.disabled_planes |=
125+
(1 << drm_plane_index(plane));
126+
}
127+
128+
return intel_plane->check_plane(plane, intel_state);
129+
}
130+
131+
static void intel_plane_atomic_update(struct drm_plane *plane,
132+
struct drm_plane_state *old_state)
133+
{
134+
struct intel_plane *intel_plane = to_intel_plane(plane);
135+
struct intel_plane_state *intel_state =
136+
to_intel_plane_state(plane->state);
137+
138+
/* Don't disable an already disabled plane */
139+
if (!plane->state->fb && !old_state->fb)
140+
return;
141+
142+
intel_plane->commit_plane(plane, intel_state);
143+
}
144+
145+
const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
146+
.prepare_fb = intel_prepare_plane_fb,
147+
.cleanup_fb = intel_cleanup_plane_fb,
148+
.atomic_check = intel_plane_atomic_check,
149+
.atomic_update = intel_plane_atomic_update,
150+
};
151+

0 commit comments

Comments
 (0)