2 * Copyright (C) 2015 Texas Instruments
3 * Author: Jyri Sarha <jsarha@ti.com>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <drm/drm_atomic.h>
21 #include <drm/drm_plane_helper.h>
22 #include <drm/drm_atomic_helper.h>
23 #include <uapi/drm/drm_fourcc.h>
25 #include "tilcdc_drv.h"
27 static struct drm_plane_funcs tilcdc_plane_funcs
= {
28 .update_plane
= drm_atomic_helper_update_plane
,
29 .disable_plane
= drm_atomic_helper_disable_plane
,
30 .destroy
= drm_plane_cleanup
,
31 .reset
= drm_atomic_helper_plane_reset
,
32 .atomic_duplicate_state
= drm_atomic_helper_plane_duplicate_state
,
33 .atomic_destroy_state
= drm_atomic_helper_plane_destroy_state
,
36 static int tilcdc_plane_atomic_check(struct drm_plane
*plane
,
37 struct drm_plane_state
*state
)
39 struct drm_crtc_state
*crtc_state
;
40 struct drm_plane_state
*old_state
= plane
->state
;
46 if (WARN_ON(!state
->fb
))
49 if (state
->crtc_x
|| state
->crtc_y
) {
50 dev_err(plane
->dev
->dev
, "%s: crtc position must be zero.",
55 crtc_state
= drm_atomic_get_existing_crtc_state(state
->state
,
57 /* we should have a crtc state if the plane is attached to a crtc */
58 if (WARN_ON(!crtc_state
))
61 if (crtc_state
->mode
.hdisplay
!= state
->crtc_w
||
62 crtc_state
->mode
.vdisplay
!= state
->crtc_h
) {
63 dev_err(plane
->dev
->dev
,
64 "%s: Size must match mode (%dx%d == %dx%d)", __func__
,
65 crtc_state
->mode
.hdisplay
, crtc_state
->mode
.vdisplay
,
66 state
->crtc_w
, state
->crtc_h
);
70 pitch
= crtc_state
->mode
.hdisplay
*
71 state
->fb
->format
->cpp
[0];
72 if (state
->fb
->pitches
[0] != pitch
) {
73 dev_err(plane
->dev
->dev
,
74 "Invalid pitch: fb and crtc widths must be the same");
78 if (state
->fb
&& old_state
->fb
&&
79 state
->fb
->format
!= old_state
->fb
->format
) {
80 dev_dbg(plane
->dev
->dev
,
81 "%s(): pixel format change requires mode_change\n",
83 crtc_state
->mode_changed
= true;
89 static void tilcdc_plane_atomic_update(struct drm_plane
*plane
,
90 struct drm_plane_state
*old_state
)
92 struct drm_plane_state
*state
= plane
->state
;
97 if (WARN_ON(!state
->fb
|| !state
->crtc
->state
))
100 tilcdc_crtc_update_fb(state
->crtc
,
102 state
->crtc
->state
->event
);
105 static const struct drm_plane_helper_funcs plane_helper_funcs
= {
106 .atomic_check
= tilcdc_plane_atomic_check
,
107 .atomic_update
= tilcdc_plane_atomic_update
,
110 int tilcdc_plane_init(struct drm_device
*dev
,
111 struct drm_plane
*plane
)
113 struct tilcdc_drm_private
*priv
= dev
->dev_private
;
116 ret
= drm_plane_init(dev
, plane
, 1,
119 priv
->num_pixelformats
,
122 dev_err(dev
->dev
, "Failed to initialize plane: %d\n", ret
);
126 drm_plane_helper_add(plane
, &plane_helper_funcs
);