drm/exynos: remove exynos_drm_crtc_plane_* wrappers
[deliverable/linux.git] / drivers / gpu / drm / exynos / exynos_drm_plane.c
CommitLineData
864ee9e6
JS
1/*
2 * Copyright (C) 2011 Samsung Electronics Co.Ltd
3 * Authors: Joonyoung Shim <jy0922.shim@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version.
9 *
10 */
11
760285e7 12#include <drm/drmP.h>
864ee9e6 13
760285e7 14#include <drm/exynos_drm.h>
864ee9e6 15#include "exynos_drm_drv.h"
080be03d 16#include "exynos_drm_crtc.h"
4070d212
JS
17#include "exynos_drm_fb.h"
18#include "exynos_drm_gem.h"
e30655d0 19#include "exynos_drm_plane.h"
864ee9e6 20
fdc575e7
JS
21#define to_exynos_plane(x) container_of(x, struct exynos_plane, base)
22
864ee9e6
JS
23struct exynos_plane {
24 struct drm_plane base;
25 struct exynos_drm_overlay overlay;
26 bool enabled;
27};
28
ba3849d5
EK
29static const uint32_t formats[] = {
30 DRM_FORMAT_XRGB8888,
6b1c762d
SWK
31 DRM_FORMAT_ARGB8888,
32 DRM_FORMAT_NV12,
6b1c762d 33 DRM_FORMAT_NV12MT,
ba3849d5
EK
34};
35
2ab97921
JS
36/*
37 * This function is to get X or Y size shown via screen. This needs length and
38 * start position of CRTC.
39 *
40 * <--- length --->
41 * CRTC ----------------
42 * ^ start ^ end
43 *
60a705a9 44 * There are six cases from a to f.
2ab97921
JS
45 *
46 * <----- SCREEN ----->
47 * 0 last
48 * ----------|------------------|----------
49 * CRTCs
50 * a -------
51 * b -------
52 * c --------------------------
53 * d --------
54 * e -------
55 * f -------
56 */
57static int exynos_plane_get_size(int start, unsigned length, unsigned last)
58{
59 int end = start + length;
60 int size = 0;
61
62 if (start <= 0) {
63 if (end > 0)
64 size = min_t(unsigned, end, last);
65 } else if (start <= last) {
66 size = min_t(unsigned, last - start, length);
67 }
68
69 return size;
70}
71
4070d212
JS
72int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
73 struct drm_framebuffer *fb, int crtc_x, int crtc_y,
74 unsigned int crtc_w, unsigned int crtc_h,
75 uint32_t src_x, uint32_t src_y,
76 uint32_t src_w, uint32_t src_h)
77{
78 struct exynos_plane *exynos_plane = to_exynos_plane(plane);
1e3b423d 79 struct exynos_drm_manager *manager = to_exynos_crtc(crtc)->manager;
4070d212
JS
80 struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
81 unsigned int actual_w;
82 unsigned int actual_h;
83 int nr;
84 int i;
85
01ed8126 86 nr = exynos_drm_fb_get_buf_cnt(fb);
4070d212
JS
87 for (i = 0; i < nr; i++) {
88 struct exynos_drm_gem_buf *buffer = exynos_drm_fb_buffer(fb, i);
89
90 if (!buffer) {
133dcdeb 91 DRM_DEBUG_KMS("buffer is null\n");
4070d212
JS
92 return -EFAULT;
93 }
94
95 overlay->dma_addr[i] = buffer->dma_addr;
4070d212 96
ddd8e959
YC
97 DRM_DEBUG_KMS("buffer: %d, dma_addr = 0x%lx\n",
98 i, (unsigned long)overlay->dma_addr[i]);
4070d212
JS
99 }
100
2ab97921
JS
101 actual_w = exynos_plane_get_size(crtc_x, crtc_w, crtc->mode.hdisplay);
102 actual_h = exynos_plane_get_size(crtc_y, crtc_h, crtc->mode.vdisplay);
103
104 if (crtc_x < 0) {
105 if (actual_w)
106 src_x -= crtc_x;
2ab97921
JS
107 crtc_x = 0;
108 }
109
110 if (crtc_y < 0) {
111 if (actual_h)
112 src_y -= crtc_y;
2ab97921
JS
113 crtc_y = 0;
114 }
4070d212
JS
115
116 /* set drm framebuffer data. */
117 overlay->fb_x = src_x;
118 overlay->fb_y = src_y;
119 overlay->fb_width = fb->width;
120 overlay->fb_height = fb->height;
121 overlay->src_width = src_w;
122 overlay->src_height = src_h;
123 overlay->bpp = fb->bits_per_pixel;
124 overlay->pitch = fb->pitches[0];
125 overlay->pixel_format = fb->pixel_format;
126
127 /* set overlay range to be displayed. */
128 overlay->crtc_x = crtc_x;
129 overlay->crtc_y = crtc_y;
130 overlay->crtc_width = actual_w;
131 overlay->crtc_height = actual_h;
132
133 /* set drm mode data. */
134 overlay->mode_width = crtc->mode.hdisplay;
135 overlay->mode_height = crtc->mode.vdisplay;
136 overlay->refresh = crtc->mode.vrefresh;
137 overlay->scan_flag = crtc->mode.flags;
138
139 DRM_DEBUG_KMS("overlay : offset_x/y(%d,%d), width/height(%d,%d)",
140 overlay->crtc_x, overlay->crtc_y,
141 overlay->crtc_width, overlay->crtc_height);
142
72ed6ccd
AH
143 plane->crtc = crtc;
144
1e3b423d
GP
145 if (manager->ops->win_mode_set)
146 manager->ops->win_mode_set(manager, overlay);
4070d212
JS
147
148 return 0;
149}
150
151void exynos_plane_commit(struct drm_plane *plane)
152{
153 struct exynos_plane *exynos_plane = to_exynos_plane(plane);
154 struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
1e3b423d 155 struct exynos_drm_manager *manager = to_exynos_crtc(plane->crtc)->manager;
4070d212 156
1e3b423d
GP
157 if (manager->ops->win_commit)
158 manager->ops->win_commit(manager, overlay->zpos);
cf5188ac
JS
159}
160
161void exynos_plane_dpms(struct drm_plane *plane, int mode)
162{
163 struct exynos_plane *exynos_plane = to_exynos_plane(plane);
164 struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
1e3b423d 165 struct exynos_drm_manager *manager;
cf5188ac 166
cf5188ac
JS
167 if (mode == DRM_MODE_DPMS_ON) {
168 if (exynos_plane->enabled)
169 return;
170
1e3b423d
GP
171 manager = to_exynos_crtc(plane->crtc)->manager;
172 if (manager->ops->win_enable)
173 manager->ops->win_enable(manager, overlay->zpos);
174
cf5188ac
JS
175 exynos_plane->enabled = true;
176 } else {
177 if (!exynos_plane->enabled)
178 return;
179
1e3b423d
GP
180 manager = to_exynos_crtc(plane->crtc)->manager;
181 if (manager->ops->win_disable)
182 manager->ops->win_disable(manager, overlay->zpos);
183
cf5188ac
JS
184 exynos_plane->enabled = false;
185 }
4070d212
JS
186}
187
864ee9e6
JS
188static int
189exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
190 struct drm_framebuffer *fb, int crtc_x, int crtc_y,
191 unsigned int crtc_w, unsigned int crtc_h,
192 uint32_t src_x, uint32_t src_y,
193 uint32_t src_w, uint32_t src_h)
194{
864ee9e6
JS
195 int ret;
196
4070d212
JS
197 ret = exynos_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y,
198 crtc_w, crtc_h, src_x >> 16, src_y >> 16,
199 src_w >> 16, src_h >> 16);
864ee9e6
JS
200 if (ret < 0)
201 return ret;
202
4070d212 203 exynos_plane_commit(plane);
cf5188ac 204 exynos_plane_dpms(plane, DRM_MODE_DPMS_ON);
864ee9e6
JS
205
206 return 0;
207}
208
209static int exynos_disable_plane(struct drm_plane *plane)
210{
cf5188ac 211 exynos_plane_dpms(plane, DRM_MODE_DPMS_OFF);
864ee9e6
JS
212
213 return 0;
214}
215
216static void exynos_plane_destroy(struct drm_plane *plane)
217{
fdc575e7 218 struct exynos_plane *exynos_plane = to_exynos_plane(plane);
864ee9e6 219
864ee9e6
JS
220 exynos_disable_plane(plane);
221 drm_plane_cleanup(plane);
222 kfree(exynos_plane);
223}
224
00ae67cf
JS
225static int exynos_plane_set_property(struct drm_plane *plane,
226 struct drm_property *property,
227 uint64_t val)
228{
229 struct drm_device *dev = plane->dev;
230 struct exynos_plane *exynos_plane = to_exynos_plane(plane);
231 struct exynos_drm_private *dev_priv = dev->dev_private;
232
00ae67cf
JS
233 if (property == dev_priv->plane_zpos_property) {
234 exynos_plane->overlay.zpos = val;
235 return 0;
236 }
237
238 return -EINVAL;
239}
240
864ee9e6
JS
241static struct drm_plane_funcs exynos_plane_funcs = {
242 .update_plane = exynos_update_plane,
243 .disable_plane = exynos_disable_plane,
244 .destroy = exynos_plane_destroy,
00ae67cf 245 .set_property = exynos_plane_set_property,
864ee9e6
JS
246};
247
00ae67cf
JS
248static void exynos_plane_attach_zpos_property(struct drm_plane *plane)
249{
250 struct drm_device *dev = plane->dev;
251 struct exynos_drm_private *dev_priv = dev->dev_private;
252 struct drm_property *prop;
253
00ae67cf
JS
254 prop = dev_priv->plane_zpos_property;
255 if (!prop) {
256 prop = drm_property_create_range(dev, 0, "zpos", 0,
257 MAX_PLANE - 1);
258 if (!prop)
259 return;
260
261 dev_priv->plane_zpos_property = prop;
262 }
263
264 drm_object_attach_property(&plane->base, prop, 0);
265}
266
b5d2eb3b 267struct drm_plane *exynos_plane_init(struct drm_device *dev,
72ed6ccd
AH
268 unsigned long possible_crtcs,
269 enum drm_plane_type type)
864ee9e6
JS
270{
271 struct exynos_plane *exynos_plane;
b5d2eb3b 272 int err;
864ee9e6
JS
273
274 exynos_plane = kzalloc(sizeof(struct exynos_plane), GFP_KERNEL);
38bb5253 275 if (!exynos_plane)
72ed6ccd 276 return ERR_PTR(-ENOMEM);
864ee9e6 277
72ed6ccd
AH
278 err = drm_universal_plane_init(dev, &exynos_plane->base, possible_crtcs,
279 &exynos_plane_funcs, formats,
280 ARRAY_SIZE(formats), type);
b5d2eb3b
JS
281 if (err) {
282 DRM_ERROR("failed to initialize plane\n");
283 kfree(exynos_plane);
72ed6ccd 284 return ERR_PTR(err);
b5d2eb3b
JS
285 }
286
72ed6ccd 287 if (type == DRM_PLANE_TYPE_PRIMARY)
00ae67cf
JS
288 exynos_plane->overlay.zpos = DEFAULT_ZPOS;
289 else
290 exynos_plane_attach_zpos_property(&exynos_plane->base);
864ee9e6 291
00ae67cf 292 return &exynos_plane->base;
864ee9e6 293}
This page took 0.187798 seconds and 5 git commands to generate.