diff options
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_plane.c')
-rw-r--r-- | drivers/gpu/drm/omapdrm/omap_plane.c | 444 |
1 files changed, 190 insertions, 254 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c index 1c6b63f39474..098904696a5c 100644 --- a/drivers/gpu/drm/omapdrm/omap_plane.c +++ b/drivers/gpu/drm/omapdrm/omap_plane.c | |||
@@ -17,10 +17,12 @@ | |||
17 | * this program. If not, see <http://www.gnu.org/licenses/>. | 17 | * this program. If not, see <http://www.gnu.org/licenses/>. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include "drm_flip_work.h" | 20 | #include <drm/drm_atomic.h> |
21 | #include <drm/drm_atomic_helper.h> | ||
22 | #include <drm/drm_plane_helper.h> | ||
21 | 23 | ||
22 | #include "omap_drv.h" | ||
23 | #include "omap_dmm_tiler.h" | 24 | #include "omap_dmm_tiler.h" |
25 | #include "omap_drv.h" | ||
24 | 26 | ||
25 | /* some hackery because omapdss has an 'enum omap_plane' (which would be | 27 | /* some hackery because omapdss has an 'enum omap_plane' (which would be |
26 | * better named omap_plane_id).. and compiler seems unhappy about having | 28 | * better named omap_plane_id).. and compiler seems unhappy about having |
@@ -32,237 +34,183 @@ | |||
32 | * plane funcs | 34 | * plane funcs |
33 | */ | 35 | */ |
34 | 36 | ||
35 | struct callback { | ||
36 | void (*fxn)(void *); | ||
37 | void *arg; | ||
38 | }; | ||
39 | |||
40 | #define to_omap_plane(x) container_of(x, struct omap_plane, base) | 37 | #define to_omap_plane(x) container_of(x, struct omap_plane, base) |
41 | 38 | ||
42 | struct omap_plane { | 39 | struct omap_plane { |
43 | struct drm_plane base; | 40 | struct drm_plane base; |
44 | int id; /* TODO rename omap_plane -> omap_plane_id in omapdss so I can use the enum */ | 41 | int id; /* TODO rename omap_plane -> omap_plane_id in omapdss so I can use the enum */ |
45 | const char *name; | 42 | const char *name; |
46 | struct omap_overlay_info info; | ||
47 | struct omap_drm_apply apply; | ||
48 | |||
49 | /* position/orientation of scanout within the fb: */ | ||
50 | struct omap_drm_window win; | ||
51 | bool enabled; | ||
52 | |||
53 | /* last fb that we pinned: */ | ||
54 | struct drm_framebuffer *pinned_fb; | ||
55 | 43 | ||
56 | uint32_t nformats; | 44 | uint32_t nformats; |
57 | uint32_t formats[32]; | 45 | uint32_t formats[32]; |
58 | 46 | ||
59 | struct omap_drm_irq error_irq; | 47 | struct omap_drm_irq error_irq; |
48 | }; | ||
60 | 49 | ||
61 | /* for deferring bo unpin's until next post_apply(): */ | 50 | struct omap_plane_state { |
62 | struct drm_flip_work unpin_work; | 51 | struct drm_plane_state base; |
63 | 52 | ||
64 | // XXX maybe get rid of this and handle vblank in crtc too? | 53 | unsigned int zorder; |
65 | struct callback apply_done_cb; | ||
66 | }; | 54 | }; |
67 | 55 | ||
68 | static void omap_plane_unpin_worker(struct drm_flip_work *work, void *val) | 56 | static inline struct omap_plane_state * |
57 | to_omap_plane_state(struct drm_plane_state *state) | ||
69 | { | 58 | { |
70 | struct omap_plane *omap_plane = | 59 | return container_of(state, struct omap_plane_state, base); |
71 | container_of(work, struct omap_plane, unpin_work); | ||
72 | struct drm_device *dev = omap_plane->base.dev; | ||
73 | |||
74 | /* | ||
75 | * omap_framebuffer_pin/unpin are always called from priv->wq, | ||
76 | * so there's no need for locking here. | ||
77 | */ | ||
78 | omap_framebuffer_unpin(val); | ||
79 | mutex_lock(&dev->mode_config.mutex); | ||
80 | drm_framebuffer_unreference(val); | ||
81 | mutex_unlock(&dev->mode_config.mutex); | ||
82 | } | 60 | } |
83 | 61 | ||
84 | /* update which fb (if any) is pinned for scanout */ | 62 | static int omap_plane_prepare_fb(struct drm_plane *plane, |
85 | static int omap_plane_update_pin(struct drm_plane *plane, | 63 | struct drm_framebuffer *fb, |
86 | struct drm_framebuffer *fb) | 64 | const struct drm_plane_state *new_state) |
87 | { | 65 | { |
88 | struct omap_plane *omap_plane = to_omap_plane(plane); | 66 | return omap_framebuffer_pin(fb); |
89 | struct drm_framebuffer *pinned_fb = omap_plane->pinned_fb; | 67 | } |
90 | |||
91 | if (pinned_fb != fb) { | ||
92 | int ret = 0; | ||
93 | |||
94 | DBG("%p -> %p", pinned_fb, fb); | ||
95 | |||
96 | if (fb) { | ||
97 | drm_framebuffer_reference(fb); | ||
98 | ret = omap_framebuffer_pin(fb); | ||
99 | } | ||
100 | |||
101 | if (pinned_fb) | ||
102 | drm_flip_work_queue(&omap_plane->unpin_work, pinned_fb); | ||
103 | |||
104 | if (ret) { | ||
105 | dev_err(plane->dev->dev, "could not swap %p -> %p\n", | ||
106 | omap_plane->pinned_fb, fb); | ||
107 | drm_framebuffer_unreference(fb); | ||
108 | omap_plane->pinned_fb = NULL; | ||
109 | return ret; | ||
110 | } | ||
111 | |||
112 | omap_plane->pinned_fb = fb; | ||
113 | } | ||
114 | 68 | ||
115 | return 0; | 69 | static void omap_plane_cleanup_fb(struct drm_plane *plane, |
70 | struct drm_framebuffer *fb, | ||
71 | const struct drm_plane_state *old_state) | ||
72 | { | ||
73 | omap_framebuffer_unpin(fb); | ||
116 | } | 74 | } |
117 | 75 | ||
118 | static void omap_plane_pre_apply(struct omap_drm_apply *apply) | 76 | static void omap_plane_atomic_update(struct drm_plane *plane, |
77 | struct drm_plane_state *old_state) | ||
119 | { | 78 | { |
120 | struct omap_plane *omap_plane = | 79 | struct omap_plane *omap_plane = to_omap_plane(plane); |
121 | container_of(apply, struct omap_plane, apply); | 80 | struct drm_plane_state *state = plane->state; |
122 | struct omap_drm_window *win = &omap_plane->win; | 81 | struct omap_plane_state *omap_state = to_omap_plane_state(state); |
123 | struct drm_plane *plane = &omap_plane->base; | 82 | struct omap_overlay_info info; |
124 | struct drm_device *dev = plane->dev; | 83 | struct omap_drm_window win; |
125 | struct omap_overlay_info *info = &omap_plane->info; | ||
126 | struct drm_crtc *crtc = plane->crtc; | ||
127 | enum omap_channel channel; | ||
128 | bool enabled = omap_plane->enabled && crtc; | ||
129 | int ret; | 84 | int ret; |
130 | 85 | ||
131 | DBG("%s, enabled=%d", omap_plane->name, enabled); | 86 | DBG("%s, crtc=%p fb=%p", omap_plane->name, state->crtc, state->fb); |
132 | 87 | ||
133 | /* if fb has changed, pin new fb: */ | 88 | memset(&info, 0, sizeof(info)); |
134 | omap_plane_update_pin(plane, enabled ? plane->fb : NULL); | 89 | info.rotation_type = OMAP_DSS_ROT_DMA; |
90 | info.rotation = OMAP_DSS_ROT_0; | ||
91 | info.global_alpha = 0xff; | ||
92 | info.mirror = 0; | ||
93 | info.zorder = omap_state->zorder; | ||
135 | 94 | ||
136 | if (!enabled) { | 95 | memset(&win, 0, sizeof(win)); |
137 | dispc_ovl_enable(omap_plane->id, false); | 96 | win.rotation = state->rotation; |
138 | return; | 97 | win.crtc_x = state->crtc_x; |
139 | } | 98 | win.crtc_y = state->crtc_y; |
99 | win.crtc_w = state->crtc_w; | ||
100 | win.crtc_h = state->crtc_h; | ||
101 | |||
102 | /* | ||
103 | * src values are in Q16 fixed point, convert to integer. | ||
104 | * omap_framebuffer_update_scanout() takes adjusted src. | ||
105 | */ | ||
106 | win.src_x = state->src_x >> 16; | ||
107 | win.src_y = state->src_y >> 16; | ||
140 | 108 | ||
141 | channel = omap_crtc_channel(crtc); | 109 | switch (state->rotation & 0xf) { |
110 | case BIT(DRM_ROTATE_90): | ||
111 | case BIT(DRM_ROTATE_270): | ||
112 | win.src_w = state->src_h >> 16; | ||
113 | win.src_h = state->src_w >> 16; | ||
114 | break; | ||
115 | default: | ||
116 | win.src_w = state->src_w >> 16; | ||
117 | win.src_h = state->src_h >> 16; | ||
118 | break; | ||
119 | } | ||
142 | 120 | ||
143 | /* update scanout: */ | 121 | /* update scanout: */ |
144 | omap_framebuffer_update_scanout(plane->fb, win, info); | 122 | omap_framebuffer_update_scanout(state->fb, &win, &info); |
145 | 123 | ||
146 | DBG("%dx%d -> %dx%d (%d)", info->width, info->height, | 124 | DBG("%dx%d -> %dx%d (%d)", info.width, info.height, |
147 | info->out_width, info->out_height, | 125 | info.out_width, info.out_height, |
148 | info->screen_width); | 126 | info.screen_width); |
149 | DBG("%d,%d %pad %pad", info->pos_x, info->pos_y, | 127 | DBG("%d,%d %pad %pad", info.pos_x, info.pos_y, |
150 | &info->paddr, &info->p_uv_addr); | 128 | &info.paddr, &info.p_uv_addr); |
151 | 129 | ||
152 | dispc_ovl_set_channel_out(omap_plane->id, channel); | 130 | dispc_ovl_set_channel_out(omap_plane->id, |
131 | omap_crtc_channel(state->crtc)); | ||
153 | 132 | ||
154 | /* and finally, update omapdss: */ | 133 | /* and finally, update omapdss: */ |
155 | ret = dispc_ovl_setup(omap_plane->id, info, false, | 134 | ret = dispc_ovl_setup(omap_plane->id, &info, false, |
156 | omap_crtc_timings(crtc), false); | 135 | omap_crtc_timings(state->crtc), false); |
157 | if (ret) { | 136 | if (WARN_ON(ret)) { |
158 | dev_err(dev->dev, "dispc_ovl_setup failed: %d\n", ret); | 137 | dispc_ovl_enable(omap_plane->id, false); |
159 | return; | 138 | return; |
160 | } | 139 | } |
161 | 140 | ||
162 | dispc_ovl_enable(omap_plane->id, true); | 141 | dispc_ovl_enable(omap_plane->id, true); |
163 | } | 142 | } |
164 | 143 | ||
165 | static void omap_plane_post_apply(struct omap_drm_apply *apply) | 144 | static void omap_plane_atomic_disable(struct drm_plane *plane, |
145 | struct drm_plane_state *old_state) | ||
166 | { | 146 | { |
167 | struct omap_plane *omap_plane = | 147 | struct omap_plane_state *omap_state = to_omap_plane_state(plane->state); |
168 | container_of(apply, struct omap_plane, apply); | 148 | struct omap_plane *omap_plane = to_omap_plane(plane); |
169 | struct drm_plane *plane = &omap_plane->base; | ||
170 | struct omap_drm_private *priv = plane->dev->dev_private; | ||
171 | struct callback cb; | ||
172 | |||
173 | cb = omap_plane->apply_done_cb; | ||
174 | omap_plane->apply_done_cb.fxn = NULL; | ||
175 | 149 | ||
176 | drm_flip_work_commit(&omap_plane->unpin_work, priv->wq); | 150 | plane->state->rotation = BIT(DRM_ROTATE_0); |
151 | omap_state->zorder = plane->type == DRM_PLANE_TYPE_PRIMARY | ||
152 | ? 0 : omap_plane->id; | ||
177 | 153 | ||
178 | if (cb.fxn) | 154 | dispc_ovl_enable(omap_plane->id, false); |
179 | cb.fxn(cb.arg); | ||
180 | } | 155 | } |
181 | 156 | ||
182 | static int omap_plane_apply(struct drm_plane *plane) | 157 | static int omap_plane_atomic_check(struct drm_plane *plane, |
158 | struct drm_plane_state *state) | ||
183 | { | 159 | { |
184 | if (plane->crtc) { | 160 | struct drm_crtc_state *crtc_state; |
185 | struct omap_plane *omap_plane = to_omap_plane(plane); | 161 | |
186 | return omap_crtc_apply(plane->crtc, &omap_plane->apply); | 162 | if (!state->crtc) |
187 | } | 163 | return 0; |
164 | |||
165 | crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc); | ||
166 | if (IS_ERR(crtc_state)) | ||
167 | return PTR_ERR(crtc_state); | ||
168 | |||
169 | if (state->crtc_x < 0 || state->crtc_y < 0) | ||
170 | return -EINVAL; | ||
171 | |||
172 | if (state->crtc_x + state->crtc_w > crtc_state->adjusted_mode.hdisplay) | ||
173 | return -EINVAL; | ||
174 | |||
175 | if (state->crtc_y + state->crtc_h > crtc_state->adjusted_mode.vdisplay) | ||
176 | return -EINVAL; | ||
177 | |||
188 | return 0; | 178 | return 0; |
189 | } | 179 | } |
190 | 180 | ||
191 | int omap_plane_mode_set(struct drm_plane *plane, | 181 | static const struct drm_plane_helper_funcs omap_plane_helper_funcs = { |
192 | struct drm_crtc *crtc, struct drm_framebuffer *fb, | 182 | .prepare_fb = omap_plane_prepare_fb, |
193 | int crtc_x, int crtc_y, | 183 | .cleanup_fb = omap_plane_cleanup_fb, |
194 | unsigned int crtc_w, unsigned int crtc_h, | 184 | .atomic_check = omap_plane_atomic_check, |
195 | unsigned int src_x, unsigned int src_y, | 185 | .atomic_update = omap_plane_atomic_update, |
196 | unsigned int src_w, unsigned int src_h, | 186 | .atomic_disable = omap_plane_atomic_disable, |
197 | void (*fxn)(void *), void *arg) | 187 | }; |
188 | |||
189 | static void omap_plane_reset(struct drm_plane *plane) | ||
198 | { | 190 | { |
199 | struct omap_plane *omap_plane = to_omap_plane(plane); | 191 | struct omap_plane *omap_plane = to_omap_plane(plane); |
200 | struct omap_drm_window *win = &omap_plane->win; | 192 | struct omap_plane_state *omap_state; |
201 | |||
202 | win->crtc_x = crtc_x; | ||
203 | win->crtc_y = crtc_y; | ||
204 | win->crtc_w = crtc_w; | ||
205 | win->crtc_h = crtc_h; | ||
206 | |||
207 | win->src_x = src_x; | ||
208 | win->src_y = src_y; | ||
209 | win->src_w = src_w; | ||
210 | win->src_h = src_h; | ||
211 | |||
212 | if (fxn) { | ||
213 | /* omap_crtc should ensure that a new page flip | ||
214 | * isn't permitted while there is one pending: | ||
215 | */ | ||
216 | BUG_ON(omap_plane->apply_done_cb.fxn); | ||
217 | |||
218 | omap_plane->apply_done_cb.fxn = fxn; | ||
219 | omap_plane->apply_done_cb.arg = arg; | ||
220 | } | ||
221 | 193 | ||
222 | return omap_plane_apply(plane); | 194 | if (plane->state && plane->state->fb) |
223 | } | 195 | drm_framebuffer_unreference(plane->state->fb); |
224 | 196 | ||
225 | static int omap_plane_update(struct drm_plane *plane, | 197 | kfree(plane->state); |
226 | struct drm_crtc *crtc, struct drm_framebuffer *fb, | 198 | plane->state = NULL; |
227 | int crtc_x, int crtc_y, | ||
228 | unsigned int crtc_w, unsigned int crtc_h, | ||
229 | uint32_t src_x, uint32_t src_y, | ||
230 | uint32_t src_w, uint32_t src_h) | ||
231 | { | ||
232 | struct omap_plane *omap_plane = to_omap_plane(plane); | ||
233 | omap_plane->enabled = true; | ||
234 | 199 | ||
235 | /* omap_plane_mode_set() takes adjusted src */ | 200 | omap_state = kzalloc(sizeof(*omap_state), GFP_KERNEL); |
236 | switch (omap_plane->win.rotation & 0xf) { | 201 | if (omap_state == NULL) |
237 | case BIT(DRM_ROTATE_90): | 202 | return; |
238 | case BIT(DRM_ROTATE_270): | ||
239 | swap(src_w, src_h); | ||
240 | break; | ||
241 | } | ||
242 | 203 | ||
243 | /* | 204 | /* |
244 | * We don't need to take a reference to the framebuffer as the DRM core | 205 | * Set defaults depending on whether we are a primary or overlay |
245 | * has already done so for the purpose of setting plane->fb. | 206 | * plane. |
246 | */ | 207 | */ |
247 | plane->fb = fb; | 208 | omap_state->zorder = plane->type == DRM_PLANE_TYPE_PRIMARY |
248 | plane->crtc = crtc; | 209 | ? 0 : omap_plane->id; |
249 | 210 | omap_state->base.rotation = BIT(DRM_ROTATE_0); | |
250 | /* src values are in Q16 fixed point, convert to integer: */ | ||
251 | return omap_plane_mode_set(plane, crtc, fb, | ||
252 | crtc_x, crtc_y, crtc_w, crtc_h, | ||
253 | src_x >> 16, src_y >> 16, src_w >> 16, src_h >> 16, | ||
254 | NULL, NULL); | ||
255 | } | ||
256 | |||
257 | static int omap_plane_disable(struct drm_plane *plane) | ||
258 | { | ||
259 | struct omap_plane *omap_plane = to_omap_plane(plane); | ||
260 | |||
261 | omap_plane->win.rotation = BIT(DRM_ROTATE_0); | ||
262 | omap_plane->info.zorder = plane->type == DRM_PLANE_TYPE_PRIMARY | ||
263 | ? 0 : omap_plane->id; | ||
264 | 211 | ||
265 | return omap_plane_set_enable(plane, false); | 212 | plane->state = &omap_state->base; |
213 | plane->state->plane = plane; | ||
266 | } | 214 | } |
267 | 215 | ||
268 | static void omap_plane_destroy(struct drm_plane *plane) | 216 | static void omap_plane_destroy(struct drm_plane *plane) |
@@ -275,82 +223,94 @@ static void omap_plane_destroy(struct drm_plane *plane) | |||
275 | 223 | ||
276 | drm_plane_cleanup(plane); | 224 | drm_plane_cleanup(plane); |
277 | 225 | ||
278 | drm_flip_work_cleanup(&omap_plane->unpin_work); | ||
279 | |||
280 | kfree(omap_plane); | 226 | kfree(omap_plane); |
281 | } | 227 | } |
282 | 228 | ||
283 | int omap_plane_set_enable(struct drm_plane *plane, bool enable) | ||
284 | { | ||
285 | struct omap_plane *omap_plane = to_omap_plane(plane); | ||
286 | |||
287 | if (enable == omap_plane->enabled) | ||
288 | return 0; | ||
289 | |||
290 | omap_plane->enabled = enable; | ||
291 | return omap_plane_apply(plane); | ||
292 | } | ||
293 | |||
294 | /* helper to install properties which are common to planes and crtcs */ | 229 | /* helper to install properties which are common to planes and crtcs */ |
295 | void omap_plane_install_properties(struct drm_plane *plane, | 230 | void omap_plane_install_properties(struct drm_plane *plane, |
296 | struct drm_mode_object *obj) | 231 | struct drm_mode_object *obj) |
297 | { | 232 | { |
298 | struct drm_device *dev = plane->dev; | 233 | struct drm_device *dev = plane->dev; |
299 | struct omap_drm_private *priv = dev->dev_private; | 234 | struct omap_drm_private *priv = dev->dev_private; |
300 | struct drm_property *prop; | ||
301 | 235 | ||
302 | if (priv->has_dmm) { | 236 | if (priv->has_dmm) { |
303 | prop = priv->rotation_prop; | 237 | struct drm_property *prop = dev->mode_config.rotation_property; |
304 | if (!prop) { | 238 | |
305 | prop = drm_mode_create_rotation_property(dev, | ||
306 | BIT(DRM_ROTATE_0) | | ||
307 | BIT(DRM_ROTATE_90) | | ||
308 | BIT(DRM_ROTATE_180) | | ||
309 | BIT(DRM_ROTATE_270) | | ||
310 | BIT(DRM_REFLECT_X) | | ||
311 | BIT(DRM_REFLECT_Y)); | ||
312 | if (prop == NULL) | ||
313 | return; | ||
314 | priv->rotation_prop = prop; | ||
315 | } | ||
316 | drm_object_attach_property(obj, prop, 0); | 239 | drm_object_attach_property(obj, prop, 0); |
317 | } | 240 | } |
318 | 241 | ||
319 | prop = priv->zorder_prop; | 242 | drm_object_attach_property(obj, priv->zorder_prop, 0); |
320 | if (!prop) { | ||
321 | prop = drm_property_create_range(dev, 0, "zorder", 0, 3); | ||
322 | if (prop == NULL) | ||
323 | return; | ||
324 | priv->zorder_prop = prop; | ||
325 | } | ||
326 | drm_object_attach_property(obj, prop, 0); | ||
327 | } | 243 | } |
328 | 244 | ||
329 | int omap_plane_set_property(struct drm_plane *plane, | 245 | static struct drm_plane_state * |
330 | struct drm_property *property, uint64_t val) | 246 | omap_plane_atomic_duplicate_state(struct drm_plane *plane) |
247 | { | ||
248 | struct omap_plane_state *state; | ||
249 | struct omap_plane_state *copy; | ||
250 | |||
251 | if (WARN_ON(!plane->state)) | ||
252 | return NULL; | ||
253 | |||
254 | state = to_omap_plane_state(plane->state); | ||
255 | copy = kmemdup(state, sizeof(*state), GFP_KERNEL); | ||
256 | if (copy == NULL) | ||
257 | return NULL; | ||
258 | |||
259 | __drm_atomic_helper_plane_duplicate_state(plane, ©->base); | ||
260 | |||
261 | return ©->base; | ||
262 | } | ||
263 | |||
264 | static void omap_plane_atomic_destroy_state(struct drm_plane *plane, | ||
265 | struct drm_plane_state *state) | ||
266 | { | ||
267 | __drm_atomic_helper_plane_destroy_state(plane, state); | ||
268 | kfree(to_omap_plane_state(state)); | ||
269 | } | ||
270 | |||
271 | static int omap_plane_atomic_set_property(struct drm_plane *plane, | ||
272 | struct drm_plane_state *state, | ||
273 | struct drm_property *property, | ||
274 | uint64_t val) | ||
331 | { | 275 | { |
332 | struct omap_plane *omap_plane = to_omap_plane(plane); | ||
333 | struct omap_drm_private *priv = plane->dev->dev_private; | 276 | struct omap_drm_private *priv = plane->dev->dev_private; |
334 | int ret = -EINVAL; | 277 | struct omap_plane_state *omap_state = to_omap_plane_state(state); |
335 | 278 | ||
336 | if (property == priv->rotation_prop) { | 279 | if (property == priv->zorder_prop) |
337 | DBG("%s: rotation: %02x", omap_plane->name, (uint32_t)val); | 280 | omap_state->zorder = val; |
338 | omap_plane->win.rotation = val; | 281 | else |
339 | ret = omap_plane_apply(plane); | 282 | return -EINVAL; |
340 | } else if (property == priv->zorder_prop) { | ||
341 | DBG("%s: zorder: %02x", omap_plane->name, (uint32_t)val); | ||
342 | omap_plane->info.zorder = val; | ||
343 | ret = omap_plane_apply(plane); | ||
344 | } | ||
345 | 283 | ||
346 | return ret; | 284 | return 0; |
285 | } | ||
286 | |||
287 | static int omap_plane_atomic_get_property(struct drm_plane *plane, | ||
288 | const struct drm_plane_state *state, | ||
289 | struct drm_property *property, | ||
290 | uint64_t *val) | ||
291 | { | ||
292 | struct omap_drm_private *priv = plane->dev->dev_private; | ||
293 | const struct omap_plane_state *omap_state = | ||
294 | container_of(state, const struct omap_plane_state, base); | ||
295 | |||
296 | if (property == priv->zorder_prop) | ||
297 | *val = omap_state->zorder; | ||
298 | else | ||
299 | return -EINVAL; | ||
300 | |||
301 | return 0; | ||
347 | } | 302 | } |
348 | 303 | ||
349 | static const struct drm_plane_funcs omap_plane_funcs = { | 304 | static const struct drm_plane_funcs omap_plane_funcs = { |
350 | .update_plane = omap_plane_update, | 305 | .update_plane = drm_atomic_helper_update_plane, |
351 | .disable_plane = omap_plane_disable, | 306 | .disable_plane = drm_atomic_helper_disable_plane, |
307 | .reset = omap_plane_reset, | ||
352 | .destroy = omap_plane_destroy, | 308 | .destroy = omap_plane_destroy, |
353 | .set_property = omap_plane_set_property, | 309 | .set_property = drm_atomic_helper_plane_set_property, |
310 | .atomic_duplicate_state = omap_plane_atomic_duplicate_state, | ||
311 | .atomic_destroy_state = omap_plane_atomic_destroy_state, | ||
312 | .atomic_set_property = omap_plane_atomic_set_property, | ||
313 | .atomic_get_property = omap_plane_atomic_get_property, | ||
354 | }; | 314 | }; |
355 | 315 | ||
356 | static void omap_plane_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus) | 316 | static void omap_plane_error_irq(struct omap_drm_irq *irq, uint32_t irqstatus) |
@@ -382,7 +342,6 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, | |||
382 | struct omap_drm_private *priv = dev->dev_private; | 342 | struct omap_drm_private *priv = dev->dev_private; |
383 | struct drm_plane *plane; | 343 | struct drm_plane *plane; |
384 | struct omap_plane *omap_plane; | 344 | struct omap_plane *omap_plane; |
385 | struct omap_overlay_info *info; | ||
386 | int ret; | 345 | int ret; |
387 | 346 | ||
388 | DBG("%s: type=%d", plane_names[id], type); | 347 | DBG("%s: type=%d", plane_names[id], type); |
@@ -391,9 +350,6 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, | |||
391 | if (!omap_plane) | 350 | if (!omap_plane) |
392 | return ERR_PTR(-ENOMEM); | 351 | return ERR_PTR(-ENOMEM); |
393 | 352 | ||
394 | drm_flip_work_init(&omap_plane->unpin_work, | ||
395 | "unpin", omap_plane_unpin_worker); | ||
396 | |||
397 | omap_plane->nformats = omap_framebuffer_get_formats( | 353 | omap_plane->nformats = omap_framebuffer_get_formats( |
398 | omap_plane->formats, ARRAY_SIZE(omap_plane->formats), | 354 | omap_plane->formats, ARRAY_SIZE(omap_plane->formats), |
399 | dss_feat_get_supported_color_modes(id)); | 355 | dss_feat_get_supported_color_modes(id)); |
@@ -402,9 +358,6 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, | |||
402 | 358 | ||
403 | plane = &omap_plane->base; | 359 | plane = &omap_plane->base; |
404 | 360 | ||
405 | omap_plane->apply.pre_apply = omap_plane_pre_apply; | ||
406 | omap_plane->apply.post_apply = omap_plane_post_apply; | ||
407 | |||
408 | omap_plane->error_irq.irqmask = error_irqs[id]; | 361 | omap_plane->error_irq.irqmask = error_irqs[id]; |
409 | omap_plane->error_irq.irq = omap_plane_error_irq; | 362 | omap_plane->error_irq.irq = omap_plane_error_irq; |
410 | omap_irq_register(dev, &omap_plane->error_irq); | 363 | omap_irq_register(dev, &omap_plane->error_irq); |
@@ -415,26 +368,9 @@ struct drm_plane *omap_plane_init(struct drm_device *dev, | |||
415 | if (ret < 0) | 368 | if (ret < 0) |
416 | goto error; | 369 | goto error; |
417 | 370 | ||
418 | omap_plane_install_properties(plane, &plane->base); | 371 | drm_plane_helper_add(plane, &omap_plane_helper_funcs); |
419 | 372 | ||
420 | /* get our starting configuration, set defaults for parameters | 373 | omap_plane_install_properties(plane, &plane->base); |
421 | * we don't currently use, etc: | ||
422 | */ | ||
423 | info = &omap_plane->info; | ||
424 | info->rotation_type = OMAP_DSS_ROT_DMA; | ||
425 | info->rotation = OMAP_DSS_ROT_0; | ||
426 | info->global_alpha = 0xff; | ||
427 | info->mirror = 0; | ||
428 | |||
429 | /* Set defaults depending on whether we are a CRTC or overlay | ||
430 | * layer. | ||
431 | * TODO add ioctl to give userspace an API to change this.. this | ||
432 | * will come in a subsequent patch. | ||
433 | */ | ||
434 | if (type == DRM_PLANE_TYPE_PRIMARY) | ||
435 | omap_plane->info.zorder = 0; | ||
436 | else | ||
437 | omap_plane->info.zorder = id; | ||
438 | 374 | ||
439 | return plane; | 375 | return plane; |
440 | 376 | ||