diff options
author | Matt Roper <matthew.d.roper@intel.com> | 2014-12-23 13:41:52 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2015-01-12 17:59:31 -0500 |
commit | ea2c67bb4affa84080c616920f3899f123786e56 (patch) | |
tree | 595c4e7deafc2093bf60790530e85ec998c8128b | |
parent | 4a3b8769f8b847d1dc3c0c14a0b0e1878be2d01c (diff) |
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>
-rw-r--r-- | Documentation/DocBook/drm.tmpl | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_atomic_plane.c | 151 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_display.c | 251 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_drv.h | 10 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_sprite.c | 50 |
6 files changed, 303 insertions, 165 deletions
diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl index 0d1e70c37a33..10cffd95fd7e 100644 --- a/Documentation/DocBook/drm.tmpl +++ b/Documentation/DocBook/drm.tmpl | |||
@@ -3932,6 +3932,11 @@ int num_ioctls;</synopsis> | |||
3932 | </para> | 3932 | </para> |
3933 | </sect2> | 3933 | </sect2> |
3934 | <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> | ||
3939 | <sect2> | ||
3935 | <title>Output Probing</title> | 3940 | <title>Output Probing</title> |
3936 | <para> | 3941 | <para> |
3937 | This section covers output probing and related infrastructure like the | 3942 | This section covers output probing and related infrastructure like the |
diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 1849ffae61ae..16e3dc350274 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile | |||
@@ -66,6 +66,7 @@ i915-y += dvo_ch7017.o \ | |||
66 | dvo_ns2501.o \ | 66 | dvo_ns2501.o \ |
67 | dvo_sil164.o \ | 67 | dvo_sil164.o \ |
68 | dvo_tfp410.o \ | 68 | dvo_tfp410.o \ |
69 | intel_atomic_plane.o \ | ||
69 | intel_crt.o \ | 70 | intel_crt.o \ |
70 | intel_ddi.o \ | 71 | intel_ddi.o \ |
71 | intel_dp.o \ | 72 | intel_dp.o \ |
diff --git a/drivers/gpu/drm/i915/intel_atomic_plane.c b/drivers/gpu/drm/i915/intel_atomic_plane.c new file mode 100644 index 000000000000..e7425d6ca36f --- /dev/null +++ b/drivers/gpu/drm/i915/intel_atomic_plane.c | |||
@@ -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 | |||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index d304cb87493d..73f9a755cc91 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -98,6 +98,8 @@ static void vlv_prepare_pll(struct intel_crtc *crtc, | |||
98 | const struct intel_crtc_config *pipe_config); | 98 | const struct intel_crtc_config *pipe_config); |
99 | static void chv_prepare_pll(struct intel_crtc *crtc, | 99 | static void chv_prepare_pll(struct intel_crtc *crtc, |
100 | const struct intel_crtc_config *pipe_config); | 100 | const struct intel_crtc_config *pipe_config); |
101 | static void intel_begin_crtc_commit(struct drm_crtc *crtc); | ||
102 | static void intel_finish_crtc_commit(struct drm_crtc *crtc); | ||
101 | 103 | ||
102 | static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe) | 104 | static struct intel_encoder *intel_find_encoder(struct intel_connector *connector, int pipe) |
103 | { | 105 | { |
@@ -9794,6 +9796,8 @@ out_hang: | |||
9794 | static struct drm_crtc_helper_funcs intel_helper_funcs = { | 9796 | static struct drm_crtc_helper_funcs intel_helper_funcs = { |
9795 | .mode_set_base_atomic = intel_pipe_set_base_atomic, | 9797 | .mode_set_base_atomic = intel_pipe_set_base_atomic, |
9796 | .load_lut = intel_crtc_load_lut, | 9798 | .load_lut = intel_crtc_load_lut, |
9799 | .atomic_begin = intel_begin_crtc_commit, | ||
9800 | .atomic_flush = intel_finish_crtc_commit, | ||
9797 | }; | 9801 | }; |
9798 | 9802 | ||
9799 | /** | 9803 | /** |
@@ -11674,7 +11678,7 @@ intel_prepare_plane_fb(struct drm_plane *plane, | |||
11674 | unsigned frontbuffer_bits = 0; | 11678 | unsigned frontbuffer_bits = 0; |
11675 | int ret = 0; | 11679 | int ret = 0; |
11676 | 11680 | ||
11677 | if (WARN_ON(fb == plane->fb || !obj)) | 11681 | if (!obj) |
11678 | return 0; | 11682 | return 0; |
11679 | 11683 | ||
11680 | switch (plane->type) { | 11684 | switch (plane->type) { |
@@ -11741,7 +11745,7 @@ intel_check_primary_plane(struct drm_plane *plane, | |||
11741 | struct drm_device *dev = plane->dev; | 11745 | struct drm_device *dev = plane->dev; |
11742 | struct drm_i915_private *dev_priv = dev->dev_private; | 11746 | struct drm_i915_private *dev_priv = dev->dev_private; |
11743 | struct drm_crtc *crtc = state->base.crtc; | 11747 | struct drm_crtc *crtc = state->base.crtc; |
11744 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 11748 | struct intel_crtc *intel_crtc; |
11745 | struct intel_plane *intel_plane = to_intel_plane(plane); | 11749 | struct intel_plane *intel_plane = to_intel_plane(plane); |
11746 | struct drm_framebuffer *fb = state->base.fb; | 11750 | struct drm_framebuffer *fb = state->base.fb; |
11747 | struct drm_rect *dest = &state->dst; | 11751 | struct drm_rect *dest = &state->dst; |
@@ -11749,6 +11753,9 @@ intel_check_primary_plane(struct drm_plane *plane, | |||
11749 | const struct drm_rect *clip = &state->clip; | 11753 | const struct drm_rect *clip = &state->clip; |
11750 | int ret; | 11754 | int ret; |
11751 | 11755 | ||
11756 | crtc = crtc ? crtc : plane->crtc; | ||
11757 | intel_crtc = to_intel_crtc(crtc); | ||
11758 | |||
11752 | ret = drm_plane_helper_check_update(plane, crtc, fb, | 11759 | ret = drm_plane_helper_check_update(plane, crtc, fb, |
11753 | src, dest, clip, | 11760 | src, dest, clip, |
11754 | DRM_PLANE_HELPER_NO_SCALING, | 11761 | DRM_PLANE_HELPER_NO_SCALING, |
@@ -11804,23 +11811,26 @@ intel_commit_primary_plane(struct drm_plane *plane, | |||
11804 | struct drm_framebuffer *fb = state->base.fb; | 11811 | struct drm_framebuffer *fb = state->base.fb; |
11805 | struct drm_device *dev = plane->dev; | 11812 | struct drm_device *dev = plane->dev; |
11806 | struct drm_i915_private *dev_priv = dev->dev_private; | 11813 | struct drm_i915_private *dev_priv = dev->dev_private; |
11807 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 11814 | struct intel_crtc *intel_crtc; |
11808 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); | 11815 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); |
11809 | struct intel_plane *intel_plane = to_intel_plane(plane); | 11816 | struct intel_plane *intel_plane = to_intel_plane(plane); |
11810 | struct drm_rect *src = &state->src; | 11817 | struct drm_rect *src = &state->src; |
11811 | 11818 | ||
11819 | crtc = crtc ? crtc : plane->crtc; | ||
11820 | intel_crtc = to_intel_crtc(crtc); | ||
11821 | |||
11812 | plane->fb = fb; | 11822 | plane->fb = fb; |
11813 | crtc->x = src->x1 >> 16; | 11823 | crtc->x = src->x1 >> 16; |
11814 | crtc->y = src->y1 >> 16; | 11824 | crtc->y = src->y1 >> 16; |
11815 | 11825 | ||
11816 | intel_plane->crtc_x = state->orig_dst.x1; | 11826 | intel_plane->crtc_x = state->base.crtc_x; |
11817 | intel_plane->crtc_y = state->orig_dst.y1; | 11827 | intel_plane->crtc_y = state->base.crtc_y; |
11818 | intel_plane->crtc_w = drm_rect_width(&state->orig_dst); | 11828 | intel_plane->crtc_w = state->base.crtc_w; |
11819 | intel_plane->crtc_h = drm_rect_height(&state->orig_dst); | 11829 | intel_plane->crtc_h = state->base.crtc_h; |
11820 | intel_plane->src_x = state->orig_src.x1; | 11830 | intel_plane->src_x = state->base.src_x; |
11821 | intel_plane->src_y = state->orig_src.y1; | 11831 | intel_plane->src_y = state->base.src_y; |
11822 | intel_plane->src_w = drm_rect_width(&state->orig_src); | 11832 | intel_plane->src_w = state->base.src_w; |
11823 | intel_plane->src_h = drm_rect_height(&state->orig_src); | 11833 | intel_plane->src_h = state->base.src_h; |
11824 | intel_plane->obj = obj; | 11834 | intel_plane->obj = obj; |
11825 | 11835 | ||
11826 | if (intel_crtc->active) { | 11836 | if (intel_crtc->active) { |
@@ -11850,6 +11860,33 @@ static void intel_begin_crtc_commit(struct drm_crtc *crtc) | |||
11850 | struct drm_device *dev = crtc->dev; | 11860 | struct drm_device *dev = crtc->dev; |
11851 | struct drm_i915_private *dev_priv = dev->dev_private; | 11861 | struct drm_i915_private *dev_priv = dev->dev_private; |
11852 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 11862 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); |
11863 | struct intel_plane *intel_plane; | ||
11864 | struct drm_plane *p; | ||
11865 | unsigned fb_bits = 0; | ||
11866 | |||
11867 | /* Track fb's for any planes being disabled */ | ||
11868 | list_for_each_entry(p, &dev->mode_config.plane_list, head) { | ||
11869 | intel_plane = to_intel_plane(p); | ||
11870 | |||
11871 | if (intel_crtc->atomic.disabled_planes & | ||
11872 | (1 << drm_plane_index(p))) { | ||
11873 | switch (p->type) { | ||
11874 | case DRM_PLANE_TYPE_PRIMARY: | ||
11875 | fb_bits = INTEL_FRONTBUFFER_PRIMARY(intel_plane->pipe); | ||
11876 | break; | ||
11877 | case DRM_PLANE_TYPE_CURSOR: | ||
11878 | fb_bits = INTEL_FRONTBUFFER_CURSOR(intel_plane->pipe); | ||
11879 | break; | ||
11880 | case DRM_PLANE_TYPE_OVERLAY: | ||
11881 | fb_bits = INTEL_FRONTBUFFER_SPRITE(intel_plane->pipe); | ||
11882 | break; | ||
11883 | } | ||
11884 | |||
11885 | mutex_lock(&dev->struct_mutex); | ||
11886 | i915_gem_track_fb(intel_fb_obj(p->fb), NULL, fb_bits); | ||
11887 | mutex_unlock(&dev->struct_mutex); | ||
11888 | } | ||
11889 | } | ||
11853 | 11890 | ||
11854 | if (intel_crtc->atomic.wait_for_flips) | 11891 | if (intel_crtc->atomic.wait_for_flips) |
11855 | intel_crtc_wait_for_pending_flips(crtc); | 11892 | intel_crtc_wait_for_pending_flips(crtc); |
@@ -11907,111 +11944,6 @@ static void intel_finish_crtc_commit(struct drm_crtc *crtc) | |||
11907 | memset(&intel_crtc->atomic, 0, sizeof(intel_crtc->atomic)); | 11944 | memset(&intel_crtc->atomic, 0, sizeof(intel_crtc->atomic)); |
11908 | } | 11945 | } |
11909 | 11946 | ||
11910 | int | ||
11911 | intel_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, | ||
11912 | struct drm_framebuffer *fb, int crtc_x, int crtc_y, | ||
11913 | unsigned int crtc_w, unsigned int crtc_h, | ||
11914 | uint32_t src_x, uint32_t src_y, | ||
11915 | uint32_t src_w, uint32_t src_h) | ||
11916 | { | ||
11917 | struct drm_device *dev = plane->dev; | ||
11918 | struct drm_framebuffer *old_fb = plane->fb; | ||
11919 | struct intel_plane_state state = {{ 0 }}; | ||
11920 | struct intel_plane *intel_plane = to_intel_plane(plane); | ||
11921 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | ||
11922 | int ret; | ||
11923 | |||
11924 | state.base.crtc = crtc ? crtc : plane->crtc; | ||
11925 | state.base.fb = fb; | ||
11926 | |||
11927 | /* sample coordinates in 16.16 fixed point */ | ||
11928 | state.src.x1 = src_x; | ||
11929 | state.src.x2 = src_x + src_w; | ||
11930 | state.src.y1 = src_y; | ||
11931 | state.src.y2 = src_y + src_h; | ||
11932 | |||
11933 | /* integer pixels */ | ||
11934 | state.dst.x1 = crtc_x; | ||
11935 | state.dst.x2 = crtc_x + crtc_w; | ||
11936 | state.dst.y1 = crtc_y; | ||
11937 | state.dst.y2 = crtc_y + crtc_h; | ||
11938 | |||
11939 | state.clip.x1 = 0; | ||
11940 | state.clip.y1 = 0; | ||
11941 | state.clip.x2 = intel_crtc->active ? intel_crtc->config.pipe_src_w : 0; | ||
11942 | state.clip.y2 = intel_crtc->active ? intel_crtc->config.pipe_src_h : 0; | ||
11943 | |||
11944 | state.orig_src = state.src; | ||
11945 | state.orig_dst = state.dst; | ||
11946 | |||
11947 | ret = intel_plane->check_plane(plane, &state); | ||
11948 | if (ret) | ||
11949 | return ret; | ||
11950 | |||
11951 | if (fb != old_fb && fb) { | ||
11952 | ret = intel_prepare_plane_fb(plane, fb); | ||
11953 | if (ret) | ||
11954 | return ret; | ||
11955 | } | ||
11956 | |||
11957 | if (!state.base.fb) { | ||
11958 | unsigned fb_bits = 0; | ||
11959 | |||
11960 | switch (plane->type) { | ||
11961 | case DRM_PLANE_TYPE_PRIMARY: | ||
11962 | fb_bits = INTEL_FRONTBUFFER_PRIMARY(intel_plane->pipe); | ||
11963 | break; | ||
11964 | case DRM_PLANE_TYPE_CURSOR: | ||
11965 | fb_bits = INTEL_FRONTBUFFER_CURSOR(intel_plane->pipe); | ||
11966 | break; | ||
11967 | case DRM_PLANE_TYPE_OVERLAY: | ||
11968 | fb_bits = INTEL_FRONTBUFFER_SPRITE(intel_plane->pipe); | ||
11969 | break; | ||
11970 | } | ||
11971 | |||
11972 | /* | ||
11973 | * 'prepare' is never called when plane is being disabled, so | ||
11974 | * we need to handle frontbuffer tracking here | ||
11975 | */ | ||
11976 | mutex_lock(&dev->struct_mutex); | ||
11977 | i915_gem_track_fb(intel_fb_obj(plane->fb), NULL, fb_bits); | ||
11978 | mutex_unlock(&dev->struct_mutex); | ||
11979 | } | ||
11980 | |||
11981 | intel_begin_crtc_commit(crtc); | ||
11982 | intel_plane->commit_plane(plane, &state); | ||
11983 | intel_finish_crtc_commit(crtc); | ||
11984 | |||
11985 | if (fb != old_fb && old_fb) { | ||
11986 | if (intel_crtc->active) | ||
11987 | intel_wait_for_vblank(dev, intel_crtc->pipe); | ||
11988 | intel_cleanup_plane_fb(plane, old_fb); | ||
11989 | } | ||
11990 | |||
11991 | plane->fb = fb; | ||
11992 | |||
11993 | return 0; | ||
11994 | } | ||
11995 | |||
11996 | /** | ||
11997 | * intel_disable_plane - disable a plane | ||
11998 | * @plane: plane to disable | ||
11999 | * | ||
12000 | * General disable handler for all plane types. | ||
12001 | */ | ||
12002 | int | ||
12003 | intel_disable_plane(struct drm_plane *plane) | ||
12004 | { | ||
12005 | if (!plane->fb) | ||
12006 | return 0; | ||
12007 | |||
12008 | if (WARN_ON(!plane->crtc)) | ||
12009 | return -EINVAL; | ||
12010 | |||
12011 | return plane->funcs->update_plane(plane, plane->crtc, NULL, | ||
12012 | 0, 0, 0, 0, 0, 0, 0, 0); | ||
12013 | } | ||
12014 | |||
12015 | /** | 11947 | /** |
12016 | * intel_plane_destroy - destroy a plane | 11948 | * intel_plane_destroy - destroy a plane |
12017 | * @plane: plane to destroy | 11949 | * @plane: plane to destroy |
@@ -12022,15 +11954,19 @@ intel_disable_plane(struct drm_plane *plane) | |||
12022 | void intel_plane_destroy(struct drm_plane *plane) | 11954 | void intel_plane_destroy(struct drm_plane *plane) |
12023 | { | 11955 | { |
12024 | struct intel_plane *intel_plane = to_intel_plane(plane); | 11956 | struct intel_plane *intel_plane = to_intel_plane(plane); |
11957 | intel_plane_destroy_state(plane, plane->state); | ||
12025 | drm_plane_cleanup(plane); | 11958 | drm_plane_cleanup(plane); |
12026 | kfree(intel_plane); | 11959 | kfree(intel_plane); |
12027 | } | 11960 | } |
12028 | 11961 | ||
12029 | static const struct drm_plane_funcs intel_primary_plane_funcs = { | 11962 | static const struct drm_plane_funcs intel_primary_plane_funcs = { |
12030 | .update_plane = intel_update_plane, | 11963 | .update_plane = drm_plane_helper_update, |
12031 | .disable_plane = intel_disable_plane, | 11964 | .disable_plane = drm_plane_helper_disable, |
12032 | .destroy = intel_plane_destroy, | 11965 | .destroy = intel_plane_destroy, |
12033 | .set_property = intel_plane_set_property | 11966 | .set_property = intel_plane_set_property, |
11967 | .atomic_duplicate_state = intel_plane_duplicate_state, | ||
11968 | .atomic_destroy_state = intel_plane_destroy_state, | ||
11969 | |||
12034 | }; | 11970 | }; |
12035 | 11971 | ||
12036 | static struct drm_plane *intel_primary_plane_create(struct drm_device *dev, | 11972 | static struct drm_plane *intel_primary_plane_create(struct drm_device *dev, |
@@ -12044,6 +11980,12 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev, | |||
12044 | if (primary == NULL) | 11980 | if (primary == NULL) |
12045 | return NULL; | 11981 | return NULL; |
12046 | 11982 | ||
11983 | primary->base.state = intel_plane_duplicate_state(&primary->base); | ||
11984 | if (primary->base.state == NULL) { | ||
11985 | kfree(primary); | ||
11986 | return NULL; | ||
11987 | } | ||
11988 | |||
12047 | primary->can_scale = false; | 11989 | primary->can_scale = false; |
12048 | primary->max_downscale = 1; | 11990 | primary->max_downscale = 1; |
12049 | primary->pipe = pipe; | 11991 | primary->pipe = pipe; |
@@ -12079,6 +12021,8 @@ static struct drm_plane *intel_primary_plane_create(struct drm_device *dev, | |||
12079 | primary->rotation); | 12021 | primary->rotation); |
12080 | } | 12022 | } |
12081 | 12023 | ||
12024 | drm_plane_helper_add(&primary->base, &intel_plane_helper_funcs); | ||
12025 | |||
12082 | return &primary->base; | 12026 | return &primary->base; |
12083 | } | 12027 | } |
12084 | 12028 | ||
@@ -12087,17 +12031,19 @@ intel_check_cursor_plane(struct drm_plane *plane, | |||
12087 | struct intel_plane_state *state) | 12031 | struct intel_plane_state *state) |
12088 | { | 12032 | { |
12089 | struct drm_crtc *crtc = state->base.crtc; | 12033 | struct drm_crtc *crtc = state->base.crtc; |
12090 | struct drm_device *dev = crtc->dev; | 12034 | struct drm_device *dev = plane->dev; |
12091 | struct drm_framebuffer *fb = state->base.fb; | 12035 | struct drm_framebuffer *fb = state->base.fb; |
12092 | struct drm_rect *dest = &state->dst; | 12036 | struct drm_rect *dest = &state->dst; |
12093 | struct drm_rect *src = &state->src; | 12037 | struct drm_rect *src = &state->src; |
12094 | const struct drm_rect *clip = &state->clip; | 12038 | const struct drm_rect *clip = &state->clip; |
12095 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); | 12039 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); |
12096 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 12040 | struct intel_crtc *intel_crtc; |
12097 | int crtc_w, crtc_h; | ||
12098 | unsigned stride; | 12041 | unsigned stride; |
12099 | int ret; | 12042 | int ret; |
12100 | 12043 | ||
12044 | crtc = crtc ? crtc : plane->crtc; | ||
12045 | intel_crtc = to_intel_crtc(crtc); | ||
12046 | |||
12101 | ret = drm_plane_helper_check_update(plane, crtc, fb, | 12047 | ret = drm_plane_helper_check_update(plane, crtc, fb, |
12102 | src, dest, clip, | 12048 | src, dest, clip, |
12103 | DRM_PLANE_HELPER_NO_SCALING, | 12049 | DRM_PLANE_HELPER_NO_SCALING, |
@@ -12112,15 +12058,14 @@ intel_check_cursor_plane(struct drm_plane *plane, | |||
12112 | goto finish; | 12058 | goto finish; |
12113 | 12059 | ||
12114 | /* Check for which cursor types we support */ | 12060 | /* Check for which cursor types we support */ |
12115 | crtc_w = drm_rect_width(&state->orig_dst); | 12061 | if (!cursor_size_ok(dev, state->base.crtc_w, state->base.crtc_h)) { |
12116 | crtc_h = drm_rect_height(&state->orig_dst); | 12062 | DRM_DEBUG("Cursor dimension %dx%d not supported\n", |
12117 | if (!cursor_size_ok(dev, crtc_w, crtc_h)) { | 12063 | state->base.crtc_w, state->base.crtc_h); |
12118 | DRM_DEBUG("Cursor dimension not supported\n"); | ||
12119 | return -EINVAL; | 12064 | return -EINVAL; |
12120 | } | 12065 | } |
12121 | 12066 | ||
12122 | stride = roundup_pow_of_two(crtc_w) * 4; | 12067 | stride = roundup_pow_of_two(state->base.crtc_w) * 4; |
12123 | if (obj->base.size < stride * crtc_h) { | 12068 | if (obj->base.size < stride * state->base.crtc_h) { |
12124 | DRM_DEBUG_KMS("buffer is too small\n"); | 12069 | DRM_DEBUG_KMS("buffer is too small\n"); |
12125 | return -ENOMEM; | 12070 | return -ENOMEM; |
12126 | } | 12071 | } |
@@ -12138,8 +12083,7 @@ intel_check_cursor_plane(struct drm_plane *plane, | |||
12138 | 12083 | ||
12139 | finish: | 12084 | finish: |
12140 | if (intel_crtc->active) { | 12085 | if (intel_crtc->active) { |
12141 | if (intel_crtc->cursor_width != | 12086 | if (intel_crtc->cursor_width != state->base.crtc_w) |
12142 | drm_rect_width(&state->orig_dst)) | ||
12143 | intel_crtc->atomic.update_wm = true; | 12087 | intel_crtc->atomic.update_wm = true; |
12144 | 12088 | ||
12145 | intel_crtc->atomic.fb_bits |= | 12089 | intel_crtc->atomic.fb_bits |= |
@@ -12154,24 +12098,27 @@ intel_commit_cursor_plane(struct drm_plane *plane, | |||
12154 | struct intel_plane_state *state) | 12098 | struct intel_plane_state *state) |
12155 | { | 12099 | { |
12156 | struct drm_crtc *crtc = state->base.crtc; | 12100 | struct drm_crtc *crtc = state->base.crtc; |
12157 | struct drm_device *dev = crtc->dev; | 12101 | struct drm_device *dev = plane->dev; |
12158 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 12102 | struct intel_crtc *intel_crtc; |
12159 | struct intel_plane *intel_plane = to_intel_plane(plane); | 12103 | struct intel_plane *intel_plane = to_intel_plane(plane); |
12160 | struct drm_i915_gem_object *obj = intel_fb_obj(state->base.fb); | 12104 | struct drm_i915_gem_object *obj = intel_fb_obj(state->base.fb); |
12161 | uint32_t addr; | 12105 | uint32_t addr; |
12162 | 12106 | ||
12107 | crtc = crtc ? crtc : plane->crtc; | ||
12108 | intel_crtc = to_intel_crtc(crtc); | ||
12109 | |||
12163 | plane->fb = state->base.fb; | 12110 | plane->fb = state->base.fb; |
12164 | crtc->cursor_x = state->orig_dst.x1; | 12111 | crtc->cursor_x = state->base.crtc_x; |
12165 | crtc->cursor_y = state->orig_dst.y1; | 12112 | crtc->cursor_y = state->base.crtc_y; |
12166 | 12113 | ||
12167 | intel_plane->crtc_x = state->orig_dst.x1; | 12114 | intel_plane->crtc_x = state->base.crtc_x; |
12168 | intel_plane->crtc_y = state->orig_dst.y1; | 12115 | intel_plane->crtc_y = state->base.crtc_y; |
12169 | intel_plane->crtc_w = drm_rect_width(&state->orig_dst); | 12116 | intel_plane->crtc_w = state->base.crtc_w; |
12170 | intel_plane->crtc_h = drm_rect_height(&state->orig_dst); | 12117 | intel_plane->crtc_h = state->base.crtc_h; |
12171 | intel_plane->src_x = state->orig_src.x1; | 12118 | intel_plane->src_x = state->base.src_x; |
12172 | intel_plane->src_y = state->orig_src.y1; | 12119 | intel_plane->src_y = state->base.src_y; |
12173 | intel_plane->src_w = drm_rect_width(&state->orig_src); | 12120 | intel_plane->src_w = state->base.src_w; |
12174 | intel_plane->src_h = drm_rect_height(&state->orig_src); | 12121 | intel_plane->src_h = state->base.src_h; |
12175 | intel_plane->obj = obj; | 12122 | intel_plane->obj = obj; |
12176 | 12123 | ||
12177 | if (intel_crtc->cursor_bo == obj) | 12124 | if (intel_crtc->cursor_bo == obj) |
@@ -12187,18 +12134,20 @@ intel_commit_cursor_plane(struct drm_plane *plane, | |||
12187 | intel_crtc->cursor_addr = addr; | 12134 | intel_crtc->cursor_addr = addr; |
12188 | intel_crtc->cursor_bo = obj; | 12135 | intel_crtc->cursor_bo = obj; |
12189 | update: | 12136 | update: |
12190 | intel_crtc->cursor_width = drm_rect_width(&state->orig_dst); | 12137 | intel_crtc->cursor_width = state->base.crtc_w; |
12191 | intel_crtc->cursor_height = drm_rect_height(&state->orig_dst); | 12138 | intel_crtc->cursor_height = state->base.crtc_h; |
12192 | 12139 | ||
12193 | if (intel_crtc->active) | 12140 | if (intel_crtc->active) |
12194 | intel_crtc_update_cursor(crtc, state->visible); | 12141 | intel_crtc_update_cursor(crtc, state->visible); |
12195 | } | 12142 | } |
12196 | 12143 | ||
12197 | static const struct drm_plane_funcs intel_cursor_plane_funcs = { | 12144 | static const struct drm_plane_funcs intel_cursor_plane_funcs = { |
12198 | .update_plane = intel_update_plane, | 12145 | .update_plane = drm_plane_helper_update, |
12199 | .disable_plane = intel_disable_plane, | 12146 | .disable_plane = drm_plane_helper_disable, |
12200 | .destroy = intel_plane_destroy, | 12147 | .destroy = intel_plane_destroy, |
12201 | .set_property = intel_plane_set_property, | 12148 | .set_property = intel_plane_set_property, |
12149 | .atomic_duplicate_state = intel_plane_duplicate_state, | ||
12150 | .atomic_destroy_state = intel_plane_destroy_state, | ||
12202 | }; | 12151 | }; |
12203 | 12152 | ||
12204 | static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev, | 12153 | static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev, |
@@ -12210,6 +12159,12 @@ static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev, | |||
12210 | if (cursor == NULL) | 12159 | if (cursor == NULL) |
12211 | return NULL; | 12160 | return NULL; |
12212 | 12161 | ||
12162 | cursor->base.state = intel_plane_duplicate_state(&cursor->base); | ||
12163 | if (cursor->base.state == NULL) { | ||
12164 | kfree(cursor); | ||
12165 | return NULL; | ||
12166 | } | ||
12167 | |||
12213 | cursor->can_scale = false; | 12168 | cursor->can_scale = false; |
12214 | cursor->max_downscale = 1; | 12169 | cursor->max_downscale = 1; |
12215 | cursor->pipe = pipe; | 12170 | cursor->pipe = pipe; |
@@ -12236,6 +12191,8 @@ static struct drm_plane *intel_cursor_plane_create(struct drm_device *dev, | |||
12236 | cursor->rotation); | 12191 | cursor->rotation); |
12237 | } | 12192 | } |
12238 | 12193 | ||
12194 | drm_plane_helper_add(&cursor->base, &intel_plane_helper_funcs); | ||
12195 | |||
12239 | return &cursor->base; | 12196 | return &cursor->base; |
12240 | } | 12197 | } |
12241 | 12198 | ||
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 8022ea570a21..be85ae98811e 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -248,8 +248,6 @@ struct intel_plane_state { | |||
248 | struct drm_rect src; | 248 | struct drm_rect src; |
249 | struct drm_rect dst; | 249 | struct drm_rect dst; |
250 | struct drm_rect clip; | 250 | struct drm_rect clip; |
251 | struct drm_rect orig_src; | ||
252 | struct drm_rect orig_dst; | ||
253 | bool visible; | 251 | bool visible; |
254 | 252 | ||
255 | /* | 253 | /* |
@@ -437,6 +435,7 @@ struct intel_crtc_atomic_commit { | |||
437 | bool disable_fbc; | 435 | bool disable_fbc; |
438 | bool pre_disable_primary; | 436 | bool pre_disable_primary; |
439 | bool update_wm; | 437 | bool update_wm; |
438 | unsigned disabled_planes; | ||
440 | 439 | ||
441 | /* Sleepable operations to perform after commit */ | 440 | /* Sleepable operations to perform after commit */ |
442 | unsigned fb_bits; | 441 | unsigned fb_bits; |
@@ -575,6 +574,7 @@ struct cxsr_latency { | |||
575 | #define to_intel_encoder(x) container_of(x, struct intel_encoder, base) | 574 | #define to_intel_encoder(x) container_of(x, struct intel_encoder, base) |
576 | #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) | 575 | #define to_intel_framebuffer(x) container_of(x, struct intel_framebuffer, base) |
577 | #define to_intel_plane(x) container_of(x, struct intel_plane, base) | 576 | #define to_intel_plane(x) container_of(x, struct intel_plane, base) |
577 | #define to_intel_plane_state(x) container_of(x, struct intel_plane_state, base) | ||
578 | #define intel_fb_obj(x) (x ? to_intel_framebuffer(x)->obj : NULL) | 578 | #define intel_fb_obj(x) (x ? to_intel_framebuffer(x)->obj : NULL) |
579 | 579 | ||
580 | struct intel_hdmi { | 580 | struct intel_hdmi { |
@@ -1255,4 +1255,10 @@ void intel_pre_disable_primary(struct drm_crtc *crtc); | |||
1255 | /* intel_tv.c */ | 1255 | /* intel_tv.c */ |
1256 | void intel_tv_init(struct drm_device *dev); | 1256 | void intel_tv_init(struct drm_device *dev); |
1257 | 1257 | ||
1258 | /* intel_atomic.c */ | ||
1259 | struct drm_plane_state *intel_plane_duplicate_state(struct drm_plane *plane); | ||
1260 | void intel_plane_destroy_state(struct drm_plane *plane, | ||
1261 | struct drm_plane_state *state); | ||
1262 | extern const struct drm_plane_helper_funcs intel_plane_helper_funcs; | ||
1263 | |||
1258 | #endif /* __INTEL_DRV_H__ */ | 1264 | #endif /* __INTEL_DRV_H__ */ |
diff --git a/drivers/gpu/drm/i915/intel_sprite.c b/drivers/gpu/drm/i915/intel_sprite.c index bb67ae70dafd..c7e70511d25e 100644 --- a/drivers/gpu/drm/i915/intel_sprite.c +++ b/drivers/gpu/drm/i915/intel_sprite.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <drm/drm_crtc.h> | 33 | #include <drm/drm_crtc.h> |
34 | #include <drm/drm_fourcc.h> | 34 | #include <drm/drm_fourcc.h> |
35 | #include <drm/drm_rect.h> | 35 | #include <drm/drm_rect.h> |
36 | #include <drm/drm_plane_helper.h> | ||
36 | #include "intel_drv.h" | 37 | #include "intel_drv.h" |
37 | #include <drm/i915_drm.h> | 38 | #include <drm/i915_drm.h> |
38 | #include "i915_drv.h" | 39 | #include "i915_drv.h" |
@@ -1081,12 +1082,13 @@ intel_check_sprite_plane(struct drm_plane *plane, | |||
1081 | uint32_t src_x, src_y, src_w, src_h; | 1082 | uint32_t src_x, src_y, src_w, src_h; |
1082 | struct drm_rect *src = &state->src; | 1083 | struct drm_rect *src = &state->src; |
1083 | struct drm_rect *dst = &state->dst; | 1084 | struct drm_rect *dst = &state->dst; |
1084 | struct drm_rect *orig_src = &state->orig_src; | ||
1085 | const struct drm_rect *clip = &state->clip; | 1085 | const struct drm_rect *clip = &state->clip; |
1086 | int hscale, vscale; | 1086 | int hscale, vscale; |
1087 | int max_scale, min_scale; | 1087 | int max_scale, min_scale; |
1088 | int pixel_size; | 1088 | int pixel_size; |
1089 | 1089 | ||
1090 | intel_crtc = intel_crtc ? intel_crtc : to_intel_crtc(plane->crtc); | ||
1091 | |||
1090 | if (!fb) { | 1092 | if (!fb) { |
1091 | state->visible = false; | 1093 | state->visible = false; |
1092 | goto finish; | 1094 | goto finish; |
@@ -1167,10 +1169,10 @@ intel_check_sprite_plane(struct drm_plane *plane, | |||
1167 | intel_plane->rotation); | 1169 | intel_plane->rotation); |
1168 | 1170 | ||
1169 | /* sanity check to make sure the src viewport wasn't enlarged */ | 1171 | /* sanity check to make sure the src viewport wasn't enlarged */ |
1170 | WARN_ON(src->x1 < (int) orig_src->x1 || | 1172 | WARN_ON(src->x1 < (int) state->base.src_x || |
1171 | src->y1 < (int) orig_src->y1 || | 1173 | src->y1 < (int) state->base.src_y || |
1172 | src->x2 > (int) orig_src->x2 || | 1174 | src->x2 > (int) state->base.src_x + state->base.src_w || |
1173 | src->y2 > (int) orig_src->y2); | 1175 | src->y2 > (int) state->base.src_y + state->base.src_h); |
1174 | 1176 | ||
1175 | /* | 1177 | /* |
1176 | * Hardware doesn't handle subpixel coordinates. | 1178 | * Hardware doesn't handle subpixel coordinates. |
@@ -1267,7 +1269,7 @@ intel_commit_sprite_plane(struct drm_plane *plane, | |||
1267 | struct intel_plane_state *state) | 1269 | struct intel_plane_state *state) |
1268 | { | 1270 | { |
1269 | struct drm_crtc *crtc = state->base.crtc; | 1271 | struct drm_crtc *crtc = state->base.crtc; |
1270 | struct intel_crtc *intel_crtc = to_intel_crtc(crtc); | 1272 | struct intel_crtc *intel_crtc; |
1271 | struct intel_plane *intel_plane = to_intel_plane(plane); | 1273 | struct intel_plane *intel_plane = to_intel_plane(plane); |
1272 | struct drm_framebuffer *fb = state->base.fb; | 1274 | struct drm_framebuffer *fb = state->base.fb; |
1273 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); | 1275 | struct drm_i915_gem_object *obj = intel_fb_obj(fb); |
@@ -1275,14 +1277,19 @@ intel_commit_sprite_plane(struct drm_plane *plane, | |||
1275 | unsigned int crtc_w, crtc_h; | 1277 | unsigned int crtc_w, crtc_h; |
1276 | uint32_t src_x, src_y, src_w, src_h; | 1278 | uint32_t src_x, src_y, src_w, src_h; |
1277 | 1279 | ||
1278 | intel_plane->crtc_x = state->orig_dst.x1; | 1280 | intel_plane->crtc_x = state->base.crtc_x; |
1279 | intel_plane->crtc_y = state->orig_dst.y1; | 1281 | intel_plane->crtc_y = state->base.crtc_y; |
1280 | intel_plane->crtc_w = drm_rect_width(&state->orig_dst); | 1282 | intel_plane->crtc_w = state->base.crtc_w; |
1281 | intel_plane->crtc_h = drm_rect_height(&state->orig_dst); | 1283 | intel_plane->crtc_h = state->base.crtc_h; |
1282 | intel_plane->src_x = state->orig_src.x1; | 1284 | intel_plane->src_x = state->base.src_x; |
1283 | intel_plane->src_y = state->orig_src.y1; | 1285 | intel_plane->src_y = state->base.src_y; |
1284 | intel_plane->src_w = drm_rect_width(&state->orig_src); | 1286 | intel_plane->src_w = state->base.src_w; |
1285 | intel_plane->src_h = drm_rect_height(&state->orig_src); | 1287 | intel_plane->src_h = state->base.src_h; |
1288 | |||
1289 | crtc = crtc ? crtc : plane->crtc; | ||
1290 | intel_crtc = to_intel_crtc(crtc); | ||
1291 | |||
1292 | plane->fb = state->base.fb; | ||
1286 | intel_plane->obj = obj; | 1293 | intel_plane->obj = obj; |
1287 | 1294 | ||
1288 | if (intel_crtc->active) { | 1295 | if (intel_crtc->active) { |
@@ -1406,10 +1413,12 @@ int intel_plane_restore(struct drm_plane *plane) | |||
1406 | } | 1413 | } |
1407 | 1414 | ||
1408 | static const struct drm_plane_funcs intel_sprite_plane_funcs = { | 1415 | static const struct drm_plane_funcs intel_sprite_plane_funcs = { |
1409 | .update_plane = intel_update_plane, | 1416 | .update_plane = drm_plane_helper_update, |
1410 | .disable_plane = intel_disable_plane, | 1417 | .disable_plane = drm_plane_helper_disable, |
1411 | .destroy = intel_plane_destroy, | 1418 | .destroy = intel_plane_destroy, |
1412 | .set_property = intel_plane_set_property, | 1419 | .set_property = intel_plane_set_property, |
1420 | .atomic_duplicate_state = intel_plane_duplicate_state, | ||
1421 | .atomic_destroy_state = intel_plane_destroy_state, | ||
1413 | }; | 1422 | }; |
1414 | 1423 | ||
1415 | static uint32_t ilk_plane_formats[] = { | 1424 | static uint32_t ilk_plane_formats[] = { |
@@ -1471,6 +1480,13 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) | |||
1471 | if (!intel_plane) | 1480 | if (!intel_plane) |
1472 | return -ENOMEM; | 1481 | return -ENOMEM; |
1473 | 1482 | ||
1483 | intel_plane->base.state = | ||
1484 | intel_plane_duplicate_state(&intel_plane->base); | ||
1485 | if (intel_plane->base.state == NULL) { | ||
1486 | kfree(intel_plane); | ||
1487 | return -ENOMEM; | ||
1488 | } | ||
1489 | |||
1474 | switch (INTEL_INFO(dev)->gen) { | 1490 | switch (INTEL_INFO(dev)->gen) { |
1475 | case 5: | 1491 | case 5: |
1476 | case 6: | 1492 | case 6: |
@@ -1564,6 +1580,8 @@ intel_plane_init(struct drm_device *dev, enum pipe pipe, int plane) | |||
1564 | dev->mode_config.rotation_property, | 1580 | dev->mode_config.rotation_property, |
1565 | intel_plane->rotation); | 1581 | intel_plane->rotation); |
1566 | 1582 | ||
1583 | drm_plane_helper_add(&intel_plane->base, &intel_plane_helper_funcs); | ||
1584 | |||
1567 | out: | 1585 | out: |
1568 | return ret; | 1586 | return ret; |
1569 | } | 1587 | } |