drm/mediatek: Remove mtk_drm_plane
[deliverable/linux.git] / drivers / gpu / drm / mediatek / mtk_drm_plane.c
1 /*
2 * Copyright (c) 2015 MediaTek Inc.
3 * Author: CK Hu <ck.hu@mediatek.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15 #include <drm/drmP.h>
16 #include <drm/drm_atomic.h>
17 #include <drm/drm_atomic_helper.h>
18 #include <drm/drm_plane_helper.h>
19
20 #include "mtk_drm_crtc.h"
21 #include "mtk_drm_ddp_comp.h"
22 #include "mtk_drm_drv.h"
23 #include "mtk_drm_fb.h"
24 #include "mtk_drm_gem.h"
25 #include "mtk_drm_plane.h"
26
27 static const u32 formats[] = {
28 DRM_FORMAT_XRGB8888,
29 DRM_FORMAT_ARGB8888,
30 DRM_FORMAT_RGB565,
31 };
32
33 static void mtk_plane_enable(struct drm_plane *plane,
34 dma_addr_t addr)
35 {
36 struct mtk_plane_state *state = to_mtk_plane_state(plane->state);
37 unsigned int pitch, format;
38 bool enable;
39
40 if (WARN_ON(!plane->state))
41 return;
42
43 enable = state->base.visible;
44
45 if (WARN_ON(enable && !plane->state->fb))
46 return;
47
48 if (plane->state->fb) {
49 pitch = plane->state->fb->pitches[0];
50 format = plane->state->fb->pixel_format;
51 } else {
52 pitch = 0;
53 format = DRM_FORMAT_RGBA8888;
54 }
55
56 addr += (state->base.src.x1 >> 16) * 4;
57 addr += (state->base.src.y1 >> 16) * pitch;
58
59 state->pending.enable = enable;
60 state->pending.pitch = pitch;
61 state->pending.format = format;
62 state->pending.addr = addr;
63 state->pending.x = state->base.dst.x1;
64 state->pending.y = state->base.dst.y1;
65 state->pending.width = drm_rect_width(&state->base.dst);
66 state->pending.height = drm_rect_height(&state->base.dst);
67 wmb(); /* Make sure the above parameters are set before update */
68 state->pending.dirty = true;
69 }
70
71 static void mtk_plane_reset(struct drm_plane *plane)
72 {
73 struct mtk_plane_state *state;
74
75 if (plane->state) {
76 if (plane->state->fb)
77 drm_framebuffer_unreference(plane->state->fb);
78
79 state = to_mtk_plane_state(plane->state);
80 memset(state, 0, sizeof(*state));
81 } else {
82 state = kzalloc(sizeof(*state), GFP_KERNEL);
83 if (!state)
84 return;
85 plane->state = &state->base;
86 }
87
88 state->base.plane = plane;
89 state->pending.format = DRM_FORMAT_RGB565;
90 }
91
92 static struct drm_plane_state *mtk_plane_duplicate_state(struct drm_plane *plane)
93 {
94 struct mtk_plane_state *old_state = to_mtk_plane_state(plane->state);
95 struct mtk_plane_state *state;
96
97 state = kzalloc(sizeof(*state), GFP_KERNEL);
98 if (!state)
99 return NULL;
100
101 __drm_atomic_helper_plane_duplicate_state(plane, &state->base);
102
103 WARN_ON(state->base.plane != plane);
104
105 state->pending = old_state->pending;
106
107 return &state->base;
108 }
109
110 static void mtk_drm_plane_destroy_state(struct drm_plane *plane,
111 struct drm_plane_state *state)
112 {
113 __drm_atomic_helper_plane_destroy_state(state);
114 kfree(to_mtk_plane_state(state));
115 }
116
117 static const struct drm_plane_funcs mtk_plane_funcs = {
118 .update_plane = drm_atomic_helper_update_plane,
119 .disable_plane = drm_atomic_helper_disable_plane,
120 .destroy = drm_plane_cleanup,
121 .reset = mtk_plane_reset,
122 .atomic_duplicate_state = mtk_plane_duplicate_state,
123 .atomic_destroy_state = mtk_drm_plane_destroy_state,
124 };
125
126 static int mtk_plane_atomic_check(struct drm_plane *plane,
127 struct drm_plane_state *state)
128 {
129 struct drm_framebuffer *fb = state->fb;
130 struct drm_crtc_state *crtc_state;
131 struct drm_rect clip = { 0, };
132
133 if (!fb)
134 return 0;
135
136 if (!mtk_fb_get_gem_obj(fb)) {
137 DRM_DEBUG_KMS("buffer is null\n");
138 return -EFAULT;
139 }
140
141 if (!state->crtc)
142 return 0;
143
144 crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
145 if (IS_ERR(crtc_state))
146 return PTR_ERR(crtc_state);
147
148 clip.x2 = crtc_state->mode.hdisplay;
149 clip.y2 = crtc_state->mode.vdisplay;
150
151 return drm_plane_helper_check_state(state, &clip,
152 DRM_PLANE_HELPER_NO_SCALING,
153 DRM_PLANE_HELPER_NO_SCALING,
154 true, true);
155 }
156
157 static void mtk_plane_atomic_update(struct drm_plane *plane,
158 struct drm_plane_state *old_state)
159 {
160 struct mtk_plane_state *state = to_mtk_plane_state(plane->state);
161 struct drm_crtc *crtc = state->base.crtc;
162 struct drm_gem_object *gem;
163 struct mtk_drm_gem_obj *mtk_gem;
164
165 if (!crtc)
166 return;
167
168 gem = mtk_fb_get_gem_obj(state->base.fb);
169 mtk_gem = to_mtk_gem_obj(gem);
170 mtk_plane_enable(plane, mtk_gem->dma_addr);
171 }
172
173 static void mtk_plane_atomic_disable(struct drm_plane *plane,
174 struct drm_plane_state *old_state)
175 {
176 struct mtk_plane_state *state = to_mtk_plane_state(plane->state);
177
178 state->pending.enable = false;
179 wmb(); /* Make sure the above parameter is set before update */
180 state->pending.dirty = true;
181 }
182
183 static const struct drm_plane_helper_funcs mtk_plane_helper_funcs = {
184 .atomic_check = mtk_plane_atomic_check,
185 .atomic_update = mtk_plane_atomic_update,
186 .atomic_disable = mtk_plane_atomic_disable,
187 };
188
189 int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane,
190 unsigned long possible_crtcs, enum drm_plane_type type)
191 {
192 int err;
193
194 err = drm_universal_plane_init(dev, plane, possible_crtcs,
195 &mtk_plane_funcs, formats,
196 ARRAY_SIZE(formats), type, NULL);
197 if (err) {
198 DRM_ERROR("failed to initialize plane\n");
199 return err;
200 }
201
202 drm_plane_helper_add(plane, &mtk_plane_helper_funcs);
203
204 return 0;
205 }
This page took 0.037318 seconds and 6 git commands to generate.