1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2015 Texas Instruments
4 * Author: Jyri Sarha <jsarha@ti.com>
7 #include <drm/drm_atomic.h>
8 #include <drm/drm_plane_helper.h>
9 #include <drm/drm_atomic_helper.h>
10 #include <drm/drm_fourcc.h>
12 #include "tilcdc_drv.h"
14 static const struct drm_plane_funcs tilcdc_plane_funcs
= {
15 .update_plane
= drm_atomic_helper_update_plane
,
16 .disable_plane
= drm_atomic_helper_disable_plane
,
17 .destroy
= drm_plane_cleanup
,
18 .reset
= drm_atomic_helper_plane_reset
,
19 .atomic_duplicate_state
= drm_atomic_helper_plane_duplicate_state
,
20 .atomic_destroy_state
= drm_atomic_helper_plane_destroy_state
,
23 static int tilcdc_plane_atomic_check(struct drm_plane
*plane
,
24 struct drm_plane_state
*state
)
26 struct drm_crtc_state
*crtc_state
;
27 struct drm_plane_state
*old_state
= plane
->state
;
33 if (WARN_ON(!state
->fb
))
36 if (state
->crtc_x
|| state
->crtc_y
) {
37 dev_err(plane
->dev
->dev
, "%s: crtc position must be zero.",
42 crtc_state
= drm_atomic_get_existing_crtc_state(state
->state
,
44 /* we should have a crtc state if the plane is attached to a crtc */
45 if (WARN_ON(!crtc_state
))
48 if (crtc_state
->mode
.hdisplay
!= state
->crtc_w
||
49 crtc_state
->mode
.vdisplay
!= state
->crtc_h
) {
50 dev_err(plane
->dev
->dev
,
51 "%s: Size must match mode (%dx%d == %dx%d)", __func__
,
52 crtc_state
->mode
.hdisplay
, crtc_state
->mode
.vdisplay
,
53 state
->crtc_w
, state
->crtc_h
);
57 pitch
= crtc_state
->mode
.hdisplay
*
58 state
->fb
->format
->cpp
[0];
59 if (state
->fb
->pitches
[0] != pitch
) {
60 dev_err(plane
->dev
->dev
,
61 "Invalid pitch: fb and crtc widths must be the same");
65 if (state
->fb
&& old_state
->fb
&&
66 state
->fb
->format
!= old_state
->fb
->format
) {
67 dev_dbg(plane
->dev
->dev
,
68 "%s(): pixel format change requires mode_change\n",
70 crtc_state
->mode_changed
= true;
76 static void tilcdc_plane_atomic_update(struct drm_plane
*plane
,
77 struct drm_plane_state
*old_state
)
79 struct drm_plane_state
*state
= plane
->state
;
84 if (WARN_ON(!state
->fb
|| !state
->crtc
->state
))
87 tilcdc_crtc_update_fb(state
->crtc
,
89 state
->crtc
->state
->event
);
92 static const struct drm_plane_helper_funcs plane_helper_funcs
= {
93 .atomic_check
= tilcdc_plane_atomic_check
,
94 .atomic_update
= tilcdc_plane_atomic_update
,
97 int tilcdc_plane_init(struct drm_device
*dev
,
98 struct drm_plane
*plane
)
100 struct tilcdc_drm_private
*priv
= dev
->dev_private
;
103 ret
= drm_plane_init(dev
, plane
, 1,
106 priv
->num_pixelformats
,
109 dev_err(dev
->dev
, "Failed to initialize plane: %d\n", ret
);
113 drm_plane_helper_add(plane
, &plane_helper_funcs
);