diff options
author | Dmitry Osipenko <digetx@gmail.com> | 2018-05-04 10:39:59 -0400 |
---|---|---|
committer | Thierry Reding <treding@nvidia.com> | 2018-05-17 08:08:44 -0400 |
commit | 3dae08bc076b93487ed2df50bcfa892113e89d9d (patch) | |
tree | ddbb3a4b0de1dca357b921ff037aedaea72a59bf | |
parent | acc6a3a9afdd4e0537342012656cdb5c4a3127c5 (diff) |
drm/tegra: plane: Implement zpos plane property for older Tegras
Older Tegra's do not support plane's Z position handling in hardware,
but the hardware provides knobs to implement it in software.
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r-- | drivers/gpu/drm/tegra/dc.c | 134 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/plane.c | 193 | ||||
-rw-r--r-- | drivers/gpu/drm/tegra/plane.h | 13 |
3 files changed, 244 insertions, 96 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c index a4dd866fc8be..51581d9da509 100644 --- a/drivers/gpu/drm/tegra/dc.c +++ b/drivers/gpu/drm/tegra/dc.c | |||
@@ -163,28 +163,89 @@ static void tegra_plane_setup_blending_legacy(struct tegra_plane *plane) | |||
163 | BLEND_COLOR_KEY_NONE; | 163 | BLEND_COLOR_KEY_NONE; |
164 | u32 blendnokey = BLEND_WEIGHT1(255) | BLEND_WEIGHT0(255); | 164 | u32 blendnokey = BLEND_WEIGHT1(255) | BLEND_WEIGHT0(255); |
165 | struct tegra_plane_state *state; | 165 | struct tegra_plane_state *state; |
166 | u32 blending[2]; | ||
166 | unsigned int i; | 167 | unsigned int i; |
167 | 168 | ||
169 | /* disable blending for non-overlapping case */ | ||
170 | tegra_plane_writel(plane, blendnokey, DC_WIN_BLEND_NOKEY); | ||
171 | tegra_plane_writel(plane, foreground, DC_WIN_BLEND_1WIN); | ||
172 | |||
168 | state = to_tegra_plane_state(plane->base.state); | 173 | state = to_tegra_plane_state(plane->base.state); |
169 | 174 | ||
170 | /* alpha contribution is 1 minus sum of overlapping windows */ | 175 | if (state->opaque) { |
171 | for (i = 0; i < 3; i++) { | 176 | /* |
172 | if (state->dependent[i]) | 177 | * Since custom fix-weight blending isn't utilized and weight |
173 | background[i] |= BLEND_CONTROL_DEPENDENT; | 178 | * of top window is set to max, we can enforce dependent |
174 | } | 179 | * blending which in this case results in transparent bottom |
180 | * window if top window is opaque and if top window enables | ||
181 | * alpha blending, then bottom window is getting alpha value | ||
182 | * of 1 minus the sum of alpha components of the overlapping | ||
183 | * plane. | ||
184 | */ | ||
185 | background[0] |= BLEND_CONTROL_DEPENDENT; | ||
186 | background[1] |= BLEND_CONTROL_DEPENDENT; | ||
175 | 187 | ||
176 | /* enable alpha blending if pixel format has an alpha component */ | 188 | /* |
177 | if (!state->opaque) | 189 | * The region where three windows overlap is the intersection |
190 | * of the two regions where two windows overlap. It contributes | ||
191 | * to the area if all of the windows on top of it have an alpha | ||
192 | * component. | ||
193 | */ | ||
194 | switch (state->base.normalized_zpos) { | ||
195 | case 0: | ||
196 | if (state->blending[0].alpha && | ||
197 | state->blending[1].alpha) | ||
198 | background[2] |= BLEND_CONTROL_DEPENDENT; | ||
199 | break; | ||
200 | |||
201 | case 1: | ||
202 | background[2] |= BLEND_CONTROL_DEPENDENT; | ||
203 | break; | ||
204 | } | ||
205 | } else { | ||
206 | /* | ||
207 | * Enable alpha blending if pixel format has an alpha | ||
208 | * component. | ||
209 | */ | ||
178 | foreground |= BLEND_CONTROL_ALPHA; | 210 | foreground |= BLEND_CONTROL_ALPHA; |
179 | 211 | ||
180 | /* | 212 | /* |
181 | * Disable blending and assume Window A is the bottom-most window, | 213 | * If any of the windows on top of this window is opaque, it |
182 | * Window C is the top-most window and Window B is in the middle. | 214 | * will completely conceal this window within that area. If |
183 | */ | 215 | * top window has an alpha component, it is blended over the |
184 | tegra_plane_writel(plane, blendnokey, DC_WIN_BLEND_NOKEY); | 216 | * bottom window. |
185 | tegra_plane_writel(plane, foreground, DC_WIN_BLEND_1WIN); | 217 | */ |
218 | for (i = 0; i < 2; i++) { | ||
219 | if (state->blending[i].alpha && | ||
220 | state->blending[i].top) | ||
221 | background[i] |= BLEND_CONTROL_DEPENDENT; | ||
222 | } | ||
186 | 223 | ||
187 | switch (plane->index) { | 224 | switch (state->base.normalized_zpos) { |
225 | case 0: | ||
226 | if (state->blending[0].alpha && | ||
227 | state->blending[1].alpha) | ||
228 | background[2] |= BLEND_CONTROL_DEPENDENT; | ||
229 | break; | ||
230 | |||
231 | case 1: | ||
232 | /* | ||
233 | * When both middle and topmost windows have an alpha, | ||
234 | * these windows a mixed together and then the result | ||
235 | * is blended over the bottom window. | ||
236 | */ | ||
237 | if (state->blending[0].alpha && | ||
238 | state->blending[0].top) | ||
239 | background[2] |= BLEND_CONTROL_ALPHA; | ||
240 | |||
241 | if (state->blending[1].alpha && | ||
242 | state->blending[1].top) | ||
243 | background[2] |= BLEND_CONTROL_ALPHA; | ||
244 | break; | ||
245 | } | ||
246 | } | ||
247 | |||
248 | switch (state->base.normalized_zpos) { | ||
188 | case 0: | 249 | case 0: |
189 | tegra_plane_writel(plane, background[0], DC_WIN_BLEND_2WIN_X); | 250 | tegra_plane_writel(plane, background[0], DC_WIN_BLEND_2WIN_X); |
190 | tegra_plane_writel(plane, background[1], DC_WIN_BLEND_2WIN_Y); | 251 | tegra_plane_writel(plane, background[1], DC_WIN_BLEND_2WIN_Y); |
@@ -192,8 +253,21 @@ static void tegra_plane_setup_blending_legacy(struct tegra_plane *plane) | |||
192 | break; | 253 | break; |
193 | 254 | ||
194 | case 1: | 255 | case 1: |
195 | tegra_plane_writel(plane, foreground, DC_WIN_BLEND_2WIN_X); | 256 | /* |
196 | tegra_plane_writel(plane, background[1], DC_WIN_BLEND_2WIN_Y); | 257 | * If window B / C is topmost, then X / Y registers are |
258 | * matching the order of blending[...] state indices, | ||
259 | * otherwise a swap is required. | ||
260 | */ | ||
261 | if (!state->blending[0].top && state->blending[1].top) { | ||
262 | blending[0] = foreground; | ||
263 | blending[1] = background[1]; | ||
264 | } else { | ||
265 | blending[0] = background[0]; | ||
266 | blending[1] = foreground; | ||
267 | } | ||
268 | |||
269 | tegra_plane_writel(plane, blending[0], DC_WIN_BLEND_2WIN_X); | ||
270 | tegra_plane_writel(plane, blending[1], DC_WIN_BLEND_2WIN_Y); | ||
197 | tegra_plane_writel(plane, background[2], DC_WIN_BLEND_3WIN_XY); | 271 | tegra_plane_writel(plane, background[2], DC_WIN_BLEND_3WIN_XY); |
198 | break; | 272 | break; |
199 | 273 | ||
@@ -525,14 +599,14 @@ static int tegra_plane_atomic_check(struct drm_plane *plane, | |||
525 | struct tegra_bo_tiling *tiling = &plane_state->tiling; | 599 | struct tegra_bo_tiling *tiling = &plane_state->tiling; |
526 | struct tegra_plane *tegra = to_tegra_plane(plane); | 600 | struct tegra_plane *tegra = to_tegra_plane(plane); |
527 | struct tegra_dc *dc = to_tegra_dc(state->crtc); | 601 | struct tegra_dc *dc = to_tegra_dc(state->crtc); |
528 | unsigned int format; | ||
529 | int err; | 602 | int err; |
530 | 603 | ||
531 | /* no need for further checks if the plane is being disabled */ | 604 | /* no need for further checks if the plane is being disabled */ |
532 | if (!state->crtc) | 605 | if (!state->crtc) |
533 | return 0; | 606 | return 0; |
534 | 607 | ||
535 | err = tegra_plane_format(state->fb->format->format, &format, | 608 | err = tegra_plane_format(state->fb->format->format, |
609 | &plane_state->format, | ||
536 | &plane_state->swap); | 610 | &plane_state->swap); |
537 | if (err < 0) | 611 | if (err < 0) |
538 | return err; | 612 | return err; |
@@ -544,21 +618,11 @@ static int tegra_plane_atomic_check(struct drm_plane *plane, | |||
544 | * be emulated by disabling alpha blending for the plane. | 618 | * be emulated by disabling alpha blending for the plane. |
545 | */ | 619 | */ |
546 | if (!dc->soc->supports_blending) { | 620 | if (!dc->soc->supports_blending) { |
547 | if (!tegra_plane_format_has_alpha(format)) { | 621 | err = tegra_plane_setup_legacy_state(tegra, plane_state); |
548 | err = tegra_plane_format_get_alpha(format, &format); | 622 | if (err < 0) |
549 | if (err < 0) | 623 | return err; |
550 | return err; | ||
551 | |||
552 | plane_state->opaque = true; | ||
553 | } else { | ||
554 | plane_state->opaque = false; | ||
555 | } | ||
556 | |||
557 | tegra_plane_check_dependent(tegra, plane_state); | ||
558 | } | 624 | } |
559 | 625 | ||
560 | plane_state->format = format; | ||
561 | |||
562 | err = tegra_fb_get_tiling(state->fb, tiling); | 626 | err = tegra_fb_get_tiling(state->fb, tiling); |
563 | if (err < 0) | 627 | if (err < 0) |
564 | return err; | 628 | return err; |
@@ -710,9 +774,7 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm, | |||
710 | } | 774 | } |
711 | 775 | ||
712 | drm_plane_helper_add(&plane->base, &tegra_plane_helper_funcs); | 776 | drm_plane_helper_add(&plane->base, &tegra_plane_helper_funcs); |
713 | 777 | drm_plane_create_zpos_property(&plane->base, plane->index, 0, 255); | |
714 | if (dc->soc->supports_blending) | ||
715 | drm_plane_create_zpos_property(&plane->base, 0, 0, 255); | ||
716 | 778 | ||
717 | return &plane->base; | 779 | return &plane->base; |
718 | } | 780 | } |
@@ -989,9 +1051,7 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm, | |||
989 | } | 1051 | } |
990 | 1052 | ||
991 | drm_plane_helper_add(&plane->base, &tegra_plane_helper_funcs); | 1053 | drm_plane_helper_add(&plane->base, &tegra_plane_helper_funcs); |
992 | 1054 | drm_plane_create_zpos_property(&plane->base, plane->index, 0, 255); | |
993 | if (dc->soc->supports_blending) | ||
994 | drm_plane_create_zpos_property(&plane->base, 0, 0, 255); | ||
995 | 1055 | ||
996 | return &plane->base; | 1056 | return &plane->base; |
997 | } | 1057 | } |
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c index 176ef46c615c..0406c2ef432c 100644 --- a/drivers/gpu/drm/tegra/plane.c +++ b/drivers/gpu/drm/tegra/plane.c | |||
@@ -23,6 +23,7 @@ static void tegra_plane_destroy(struct drm_plane *plane) | |||
23 | 23 | ||
24 | static void tegra_plane_reset(struct drm_plane *plane) | 24 | static void tegra_plane_reset(struct drm_plane *plane) |
25 | { | 25 | { |
26 | struct tegra_plane *p = to_tegra_plane(plane); | ||
26 | struct tegra_plane_state *state; | 27 | struct tegra_plane_state *state; |
27 | 28 | ||
28 | if (plane->state) | 29 | if (plane->state) |
@@ -35,6 +36,8 @@ static void tegra_plane_reset(struct drm_plane *plane) | |||
35 | if (state) { | 36 | if (state) { |
36 | plane->state = &state->base; | 37 | plane->state = &state->base; |
37 | plane->state->plane = plane; | 38 | plane->state->plane = plane; |
39 | plane->state->zpos = p->index; | ||
40 | plane->state->normalized_zpos = p->index; | ||
38 | } | 41 | } |
39 | } | 42 | } |
40 | 43 | ||
@@ -55,8 +58,8 @@ tegra_plane_atomic_duplicate_state(struct drm_plane *plane) | |||
55 | copy->swap = state->swap; | 58 | copy->swap = state->swap; |
56 | copy->opaque = state->opaque; | 59 | copy->opaque = state->opaque; |
57 | 60 | ||
58 | for (i = 0; i < 3; i++) | 61 | for (i = 0; i < 2; i++) |
59 | copy->dependent[i] = state->dependent[i]; | 62 | copy->blending[i] = state->blending[i]; |
60 | 63 | ||
61 | return ©->base; | 64 | return ©->base; |
62 | } | 65 | } |
@@ -267,24 +270,8 @@ static bool __drm_format_has_alpha(u32 format) | |||
267 | return false; | 270 | return false; |
268 | } | 271 | } |
269 | 272 | ||
270 | /* | 273 | static int tegra_plane_format_get_alpha(unsigned int opaque, |
271 | * This is applicable to Tegra20 and Tegra30 only where the opaque formats can | 274 | unsigned int *alpha) |
272 | * be emulated using the alpha formats and alpha blending disabled. | ||
273 | */ | ||
274 | bool tegra_plane_format_has_alpha(unsigned int format) | ||
275 | { | ||
276 | switch (format) { | ||
277 | case WIN_COLOR_DEPTH_B5G5R5A1: | ||
278 | case WIN_COLOR_DEPTH_A1B5G5R5: | ||
279 | case WIN_COLOR_DEPTH_R8G8B8A8: | ||
280 | case WIN_COLOR_DEPTH_B8G8R8A8: | ||
281 | return true; | ||
282 | } | ||
283 | |||
284 | return false; | ||
285 | } | ||
286 | |||
287 | int tegra_plane_format_get_alpha(unsigned int opaque, unsigned int *alpha) | ||
288 | { | 275 | { |
289 | if (tegra_plane_format_is_yuv(opaque, NULL)) { | 276 | if (tegra_plane_format_is_yuv(opaque, NULL)) { |
290 | *alpha = opaque; | 277 | *alpha = opaque; |
@@ -316,6 +303,67 @@ int tegra_plane_format_get_alpha(unsigned int opaque, unsigned int *alpha) | |||
316 | return -EINVAL; | 303 | return -EINVAL; |
317 | } | 304 | } |
318 | 305 | ||
306 | /* | ||
307 | * This is applicable to Tegra20 and Tegra30 only where the opaque formats can | ||
308 | * be emulated using the alpha formats and alpha blending disabled. | ||
309 | */ | ||
310 | static int tegra_plane_setup_opacity(struct tegra_plane *tegra, | ||
311 | struct tegra_plane_state *state) | ||
312 | { | ||
313 | unsigned int format; | ||
314 | int err; | ||
315 | |||
316 | switch (state->format) { | ||
317 | case WIN_COLOR_DEPTH_B5G5R5A1: | ||
318 | case WIN_COLOR_DEPTH_A1B5G5R5: | ||
319 | case WIN_COLOR_DEPTH_R8G8B8A8: | ||
320 | case WIN_COLOR_DEPTH_B8G8R8A8: | ||
321 | state->opaque = false; | ||
322 | break; | ||
323 | |||
324 | default: | ||
325 | err = tegra_plane_format_get_alpha(state->format, &format); | ||
326 | if (err < 0) | ||
327 | return err; | ||
328 | |||
329 | state->format = format; | ||
330 | state->opaque = true; | ||
331 | break; | ||
332 | } | ||
333 | |||
334 | return 0; | ||
335 | } | ||
336 | |||
337 | static int tegra_plane_check_transparency(struct tegra_plane *tegra, | ||
338 | struct tegra_plane_state *state) | ||
339 | { | ||
340 | struct drm_plane_state *old, *plane_state; | ||
341 | struct drm_plane *plane; | ||
342 | |||
343 | old = drm_atomic_get_old_plane_state(state->base.state, &tegra->base); | ||
344 | |||
345 | /* check if zpos / transparency changed */ | ||
346 | if (old->normalized_zpos == state->base.normalized_zpos && | ||
347 | to_tegra_plane_state(old)->opaque == state->opaque) | ||
348 | return 0; | ||
349 | |||
350 | /* include all sibling planes into this commit */ | ||
351 | drm_for_each_plane(plane, tegra->base.dev) { | ||
352 | struct tegra_plane *p = to_tegra_plane(plane); | ||
353 | |||
354 | /* skip this plane and planes on different CRTCs */ | ||
355 | if (p == tegra || p->dc != tegra->dc) | ||
356 | continue; | ||
357 | |||
358 | plane_state = drm_atomic_get_plane_state(state->base.state, | ||
359 | plane); | ||
360 | if (IS_ERR(plane_state)) | ||
361 | return PTR_ERR(plane_state); | ||
362 | } | ||
363 | |||
364 | return 1; | ||
365 | } | ||
366 | |||
319 | static unsigned int tegra_plane_get_overlap_index(struct tegra_plane *plane, | 367 | static unsigned int tegra_plane_get_overlap_index(struct tegra_plane *plane, |
320 | struct tegra_plane *other) | 368 | struct tegra_plane *other) |
321 | { | 369 | { |
@@ -336,61 +384,98 @@ static unsigned int tegra_plane_get_overlap_index(struct tegra_plane *plane, | |||
336 | return index; | 384 | return index; |
337 | } | 385 | } |
338 | 386 | ||
339 | void tegra_plane_check_dependent(struct tegra_plane *tegra, | 387 | static void tegra_plane_update_transparency(struct tegra_plane *tegra, |
340 | struct tegra_plane_state *state) | 388 | struct tegra_plane_state *state) |
341 | { | 389 | { |
342 | struct drm_plane_state *old, *new; | 390 | struct drm_plane_state *new; |
343 | struct drm_plane *plane; | 391 | struct drm_plane *plane; |
344 | unsigned int zpos[2]; | ||
345 | unsigned int i; | 392 | unsigned int i; |
346 | 393 | ||
347 | for (i = 0; i < 2; i++) | 394 | for_each_new_plane_in_state(state->base.state, plane, new, i) { |
348 | zpos[i] = 0; | ||
349 | |||
350 | for_each_oldnew_plane_in_state(state->base.state, plane, old, new, i) { | ||
351 | struct tegra_plane *p = to_tegra_plane(plane); | 395 | struct tegra_plane *p = to_tegra_plane(plane); |
352 | unsigned index; | 396 | unsigned index; |
353 | 397 | ||
354 | /* skip this plane and planes on different CRTCs */ | 398 | /* skip this plane and planes on different CRTCs */ |
355 | if (p == tegra || new->crtc != state->base.crtc) | 399 | if (p == tegra || p->dc != tegra->dc) |
356 | continue; | 400 | continue; |
357 | 401 | ||
358 | index = tegra_plane_get_overlap_index(tegra, p); | 402 | index = tegra_plane_get_overlap_index(tegra, p); |
359 | 403 | ||
360 | state->dependent[index] = false; | 404 | if (new->fb && __drm_format_has_alpha(new->fb->format->format)) |
405 | state->blending[index].alpha = true; | ||
406 | else | ||
407 | state->blending[index].alpha = false; | ||
408 | |||
409 | if (new->normalized_zpos > state->base.normalized_zpos) | ||
410 | state->blending[index].top = true; | ||
411 | else | ||
412 | state->blending[index].top = false; | ||
361 | 413 | ||
362 | /* | 414 | /* |
363 | * If any of the other planes is on top of this plane and uses | 415 | * Missing framebuffer means that plane is disabled, in this |
364 | * a format with an alpha component, mark this plane as being | 416 | * case mark B / C window as top to be able to differentiate |
365 | * dependent, meaning it's alpha value will be 1 minus the sum | 417 | * windows indices order in regards to zPos for the middle |
366 | * of alpha components of the overlapping planes. | 418 | * window X / Y registers programming. |
367 | */ | 419 | */ |
368 | if (p->index > tegra->index) { | 420 | if (!new->fb) |
369 | if (__drm_format_has_alpha(new->fb->format->format)) | 421 | state->blending[index].top = (index == 1); |
370 | state->dependent[index] = true; | ||
371 | |||
372 | /* keep track of the Z position */ | ||
373 | zpos[index] = p->index; | ||
374 | } | ||
375 | } | 422 | } |
423 | } | ||
424 | |||
425 | static int tegra_plane_setup_transparency(struct tegra_plane *tegra, | ||
426 | struct tegra_plane_state *state) | ||
427 | { | ||
428 | struct tegra_plane_state *tegra_state; | ||
429 | struct drm_plane_state *new; | ||
430 | struct drm_plane *plane; | ||
431 | int err; | ||
376 | 432 | ||
377 | /* | 433 | /* |
378 | * The region where three windows overlap is the intersection of the | 434 | * If planes zpos / transparency changed, sibling planes blending |
379 | * two regions where two windows overlap. It contributes to the area | 435 | * state may require adjustment and in this case they will be included |
380 | * if any of the windows on top of it have an alpha component. | 436 | * into this atom commit, otherwise blending state is unchanged. |
381 | */ | 437 | */ |
382 | for (i = 0; i < 2; i++) | 438 | err = tegra_plane_check_transparency(tegra, state); |
383 | state->dependent[2] = state->dependent[2] || | 439 | if (err <= 0) |
384 | state->dependent[i]; | 440 | return err; |
385 | 441 | ||
386 | /* | 442 | /* |
387 | * However, if any of the windows on top of this window is opaque, it | 443 | * All planes are now in the atomic state, walk them up and update |
388 | * will completely conceal this window within that area, so avoid the | 444 | * transparency state for each plane. |
389 | * window from contributing to the area. | ||
390 | */ | 445 | */ |
391 | for (i = 0; i < 2; i++) { | 446 | drm_for_each_plane(plane, tegra->base.dev) { |
392 | if (zpos[i] > tegra->index) | 447 | struct tegra_plane *p = to_tegra_plane(plane); |
393 | state->dependent[2] = state->dependent[2] && | 448 | |
394 | state->dependent[i]; | 449 | /* skip planes on different CRTCs */ |
450 | if (p->dc != tegra->dc) | ||
451 | continue; | ||
452 | |||
453 | new = drm_atomic_get_new_plane_state(state->base.state, plane); | ||
454 | tegra_state = to_tegra_plane_state(new); | ||
455 | |||
456 | /* | ||
457 | * There is no need to update blending state for the disabled | ||
458 | * plane. | ||
459 | */ | ||
460 | if (new->fb) | ||
461 | tegra_plane_update_transparency(p, tegra_state); | ||
395 | } | 462 | } |
463 | |||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | int tegra_plane_setup_legacy_state(struct tegra_plane *tegra, | ||
468 | struct tegra_plane_state *state) | ||
469 | { | ||
470 | int err; | ||
471 | |||
472 | err = tegra_plane_setup_opacity(tegra, state); | ||
473 | if (err < 0) | ||
474 | return err; | ||
475 | |||
476 | err = tegra_plane_setup_transparency(tegra, state); | ||
477 | if (err < 0) | ||
478 | return err; | ||
479 | |||
480 | return 0; | ||
396 | } | 481 | } |
diff --git a/drivers/gpu/drm/tegra/plane.h b/drivers/gpu/drm/tegra/plane.h index 6938719e7e5d..7360ddfafee8 100644 --- a/drivers/gpu/drm/tegra/plane.h +++ b/drivers/gpu/drm/tegra/plane.h | |||
@@ -34,6 +34,11 @@ static inline struct tegra_plane *to_tegra_plane(struct drm_plane *plane) | |||
34 | return container_of(plane, struct tegra_plane, base); | 34 | return container_of(plane, struct tegra_plane, base); |
35 | } | 35 | } |
36 | 36 | ||
37 | struct tegra_plane_legacy_blending_state { | ||
38 | bool alpha; | ||
39 | bool top; | ||
40 | }; | ||
41 | |||
37 | struct tegra_plane_state { | 42 | struct tegra_plane_state { |
38 | struct drm_plane_state base; | 43 | struct drm_plane_state base; |
39 | 44 | ||
@@ -42,8 +47,8 @@ struct tegra_plane_state { | |||
42 | u32 swap; | 47 | u32 swap; |
43 | 48 | ||
44 | /* used for legacy blending support only */ | 49 | /* used for legacy blending support only */ |
50 | struct tegra_plane_legacy_blending_state blending[2]; | ||
45 | bool opaque; | 51 | bool opaque; |
46 | bool dependent[3]; | ||
47 | }; | 52 | }; |
48 | 53 | ||
49 | static inline struct tegra_plane_state * | 54 | static inline struct tegra_plane_state * |
@@ -62,9 +67,7 @@ int tegra_plane_state_add(struct tegra_plane *plane, | |||
62 | 67 | ||
63 | int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap); | 68 | int tegra_plane_format(u32 fourcc, u32 *format, u32 *swap); |
64 | bool tegra_plane_format_is_yuv(unsigned int format, bool *planar); | 69 | bool tegra_plane_format_is_yuv(unsigned int format, bool *planar); |
65 | bool tegra_plane_format_has_alpha(unsigned int format); | 70 | int tegra_plane_setup_legacy_state(struct tegra_plane *tegra, |
66 | int tegra_plane_format_get_alpha(unsigned int opaque, unsigned int *alpha); | 71 | struct tegra_plane_state *state); |
67 | void tegra_plane_check_dependent(struct tegra_plane *tegra, | ||
68 | struct tegra_plane_state *state); | ||
69 | 72 | ||
70 | #endif /* TEGRA_PLANE_H */ | 73 | #endif /* TEGRA_PLANE_H */ |