aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoonyoung Shim <jy0922.shim@samsung.com>2011-12-08 03:54:07 -0500
committerInki Dae <inki.dae@samsung.com>2011-12-21 01:14:17 -0500
commit864ee9e6f643b479e0469c9865cae238590d5f6e (patch)
treedcb8ad130f42bac96fe3f03a234ffbcbe0c58bd2
parentcb91f6a078097cdfe23bc1bd997e4310b06b87a3 (diff)
drm/exynos: Add plane support with fimd
The exynos fimd supports 5 window overlays. Only one window overlay of fimd is used by the crtc, so we need plane feature to use the rest window overlays. This creates one ioctl exynos specific - DRM_EXYNOS_PLANE_SET_ZPOS, it is the ioctl to decide for user to assign which window overlay. Signed-off-by: Joonyoung Shim <jy0922.shim@samsung.com> Signed-off-by: Inki Dae <inki.dae@samsung.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
-rw-r--r--drivers/gpu/drm/exynos/Makefile3
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_crtc.c1
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.c9
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_drv.h8
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_encoder.c26
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_encoder.h2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fimd.c33
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.c163
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_plane.h14
-rw-r--r--include/drm/exynos_drm.h10
10 files changed, 254 insertions, 15 deletions
diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile
index 0496d3ff268..c99127214f8 100644
--- a/drivers/gpu/drm/exynos/Makefile
+++ b/drivers/gpu/drm/exynos/Makefile
@@ -5,7 +5,8 @@
5ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/exynos 5ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/exynos
6exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o exynos_drm_connector.o \ 6exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o exynos_drm_connector.o \
7 exynos_drm_crtc.o exynos_drm_fbdev.o exynos_drm_fb.o \ 7 exynos_drm_crtc.o exynos_drm_fbdev.o exynos_drm_fb.o \
8 exynos_drm_buf.o exynos_drm_gem.o exynos_drm_core.o 8 exynos_drm_buf.o exynos_drm_gem.o exynos_drm_core.o \
9 exynos_drm_plane.o
9 10
10obj-$(CONFIG_DRM_EXYNOS) += exynosdrm.o 11obj-$(CONFIG_DRM_EXYNOS) += exynosdrm.o
11obj-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o 12obj-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o
diff --git a/drivers/gpu/drm/exynos/exynos_drm_crtc.c b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
index a435c339033..e1ce9fd5a16 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_crtc.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_crtc.c
@@ -380,6 +380,7 @@ int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr)
380 380
381 exynos_crtc->pipe = nr; 381 exynos_crtc->pipe = nr;
382 exynos_crtc->dpms = DRM_MODE_DPMS_OFF; 382 exynos_crtc->dpms = DRM_MODE_DPMS_OFF;
383 exynos_crtc->overlay.zpos = DEFAULT_ZPOS;
383 crtc = &exynos_crtc->drm_crtc; 384 crtc = &exynos_crtc->drm_crtc;
384 385
385 private->crtc[nr] = crtc; 386 private->crtc[nr] = crtc;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.c b/drivers/gpu/drm/exynos/exynos_drm_drv.c
index b86a04bd939..050684ceab9 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.c
@@ -36,6 +36,7 @@
36#include "exynos_drm_fbdev.h" 36#include "exynos_drm_fbdev.h"
37#include "exynos_drm_fb.h" 37#include "exynos_drm_fb.h"
38#include "exynos_drm_gem.h" 38#include "exynos_drm_gem.h"
39#include "exynos_drm_plane.h"
39 40
40#define DRIVER_NAME "exynos-drm" 41#define DRIVER_NAME "exynos-drm"
41#define DRIVER_DESC "Samsung SoC DRM" 42#define DRIVER_DESC "Samsung SoC DRM"
@@ -77,6 +78,12 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
77 goto err_crtc; 78 goto err_crtc;
78 } 79 }
79 80
81 for (nr = 0; nr < MAX_PLANE; nr++) {
82 ret = exynos_plane_init(dev, nr);
83 if (ret)
84 goto err_crtc;
85 }
86
80 ret = drm_vblank_init(dev, MAX_CRTC); 87 ret = drm_vblank_init(dev, MAX_CRTC);
81 if (ret) 88 if (ret)
82 goto err_crtc; 89 goto err_crtc;
@@ -163,6 +170,8 @@ static struct drm_ioctl_desc exynos_ioctls[] = {
163 DRM_AUTH), 170 DRM_AUTH),
164 DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MMAP, 171 DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MMAP,
165 exynos_drm_gem_mmap_ioctl, DRM_UNLOCKED | DRM_AUTH), 172 exynos_drm_gem_mmap_ioctl, DRM_UNLOCKED | DRM_AUTH),
173 DRM_IOCTL_DEF_DRV(EXYNOS_PLANE_SET_ZPOS, exynos_plane_set_zpos_ioctl,
174 DRM_UNLOCKED | DRM_AUTH),
166}; 175};
167 176
168static const struct file_operations exynos_drm_driver_fops = { 177static const struct file_operations exynos_drm_driver_fops = {
diff --git a/drivers/gpu/drm/exynos/exynos_drm_drv.h b/drivers/gpu/drm/exynos/exynos_drm_drv.h
index 8018798710d..8e8d8f0f8f3 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_drv.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_drv.h
@@ -33,6 +33,8 @@
33#include "drm.h" 33#include "drm.h"
34 34
35#define MAX_CRTC 2 35#define MAX_CRTC 2
36#define MAX_PLANE 5
37#define DEFAULT_ZPOS -1
36 38
37struct drm_device; 39struct drm_device;
38struct exynos_drm_overlay; 40struct exynos_drm_overlay;
@@ -57,8 +59,8 @@ enum exynos_drm_output_type {
57struct exynos_drm_overlay_ops { 59struct exynos_drm_overlay_ops {
58 void (*mode_set)(struct device *subdrv_dev, 60 void (*mode_set)(struct device *subdrv_dev,
59 struct exynos_drm_overlay *overlay); 61 struct exynos_drm_overlay *overlay);
60 void (*commit)(struct device *subdrv_dev); 62 void (*commit)(struct device *subdrv_dev, int zpos);
61 void (*disable)(struct device *subdrv_dev); 63 void (*disable)(struct device *subdrv_dev, int zpos);
62}; 64};
63 65
64/* 66/*
@@ -83,6 +85,7 @@ struct exynos_drm_overlay_ops {
83 * @dma_addr: bus(accessed by dma) address to the memory region allocated 85 * @dma_addr: bus(accessed by dma) address to the memory region allocated
84 * for a overlay. 86 * for a overlay.
85 * @vaddr: virtual memory addresss to this overlay. 87 * @vaddr: virtual memory addresss to this overlay.
88 * @zpos: order of overlay layer(z position).
86 * @default_win: a window to be enabled. 89 * @default_win: a window to be enabled.
87 * @color_key: color key on or off. 90 * @color_key: color key on or off.
88 * @index_color: if using color key feature then this value would be used 91 * @index_color: if using color key feature then this value would be used
@@ -111,6 +114,7 @@ struct exynos_drm_overlay {
111 unsigned int pitch; 114 unsigned int pitch;
112 dma_addr_t dma_addr; 115 dma_addr_t dma_addr;
113 void __iomem *vaddr; 116 void __iomem *vaddr;
117 int zpos;
114 118
115 bool default_win; 119 bool default_win;
116 bool color_key; 120 bool color_key;
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.c b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
index 4ff4a217c1d..86b93dde219 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.c
@@ -294,12 +294,27 @@ void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data)
294 manager_ops->disable_vblank(manager->dev); 294 manager_ops->disable_vblank(manager->dev);
295} 295}
296 296
297void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data) 297void exynos_drm_encoder_crtc_plane_commit(struct drm_encoder *encoder,
298 void *data)
298{ 299{
299 struct exynos_drm_manager *manager = 300 struct exynos_drm_manager *manager =
300 to_exynos_encoder(encoder)->manager; 301 to_exynos_encoder(encoder)->manager;
301 struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; 302 struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
303 int zpos = DEFAULT_ZPOS;
304
305 if (data)
306 zpos = *(int *)data;
307
308 if (overlay_ops && overlay_ops->commit)
309 overlay_ops->commit(manager->dev, zpos);
310}
311
312void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data)
313{
314 struct exynos_drm_manager *manager =
315 to_exynos_encoder(encoder)->manager;
302 int crtc = *(int *)data; 316 int crtc = *(int *)data;
317 int zpos = DEFAULT_ZPOS;
303 318
304 DRM_DEBUG_KMS("%s\n", __FILE__); 319 DRM_DEBUG_KMS("%s\n", __FILE__);
305 320
@@ -309,8 +324,7 @@ void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data)
309 */ 324 */
310 manager->pipe = crtc; 325 manager->pipe = crtc;
311 326
312 if (overlay_ops && overlay_ops->commit) 327 exynos_drm_encoder_crtc_plane_commit(encoder, &zpos);
313 overlay_ops->commit(manager->dev);
314} 328}
315 329
316void exynos_drm_encoder_dpms_from_crtc(struct drm_encoder *encoder, void *data) 330void exynos_drm_encoder_dpms_from_crtc(struct drm_encoder *encoder, void *data)
@@ -375,11 +389,15 @@ void exynos_drm_encoder_crtc_disable(struct drm_encoder *encoder, void *data)
375 struct exynos_drm_manager *manager = 389 struct exynos_drm_manager *manager =
376 to_exynos_encoder(encoder)->manager; 390 to_exynos_encoder(encoder)->manager;
377 struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops; 391 struct exynos_drm_overlay_ops *overlay_ops = manager->overlay_ops;
392 int zpos = DEFAULT_ZPOS;
378 393
379 DRM_DEBUG_KMS("\n"); 394 DRM_DEBUG_KMS("\n");
380 395
396 if (data)
397 zpos = *(int *)data;
398
381 if (overlay_ops && overlay_ops->disable) 399 if (overlay_ops && overlay_ops->disable)
382 overlay_ops->disable(manager->dev); 400 overlay_ops->disable(manager->dev, zpos);
383} 401}
384 402
385MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>"); 403MODULE_AUTHOR("Inki Dae <inki.dae@samsung.com>");
diff --git a/drivers/gpu/drm/exynos/exynos_drm_encoder.h b/drivers/gpu/drm/exynos/exynos_drm_encoder.h
index 72f15b021c4..97b087a51cb 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_encoder.h
+++ b/drivers/gpu/drm/exynos/exynos_drm_encoder.h
@@ -39,6 +39,8 @@ void exynos_drm_fn_encoder(struct drm_crtc *crtc, void *data,
39 void (*fn)(struct drm_encoder *, void *)); 39 void (*fn)(struct drm_encoder *, void *));
40void exynos_drm_enable_vblank(struct drm_encoder *encoder, void *data); 40void exynos_drm_enable_vblank(struct drm_encoder *encoder, void *data);
41void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data); 41void exynos_drm_disable_vblank(struct drm_encoder *encoder, void *data);
42void exynos_drm_encoder_crtc_plane_commit(struct drm_encoder *encoder,
43 void *data);
42void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data); 44void exynos_drm_encoder_crtc_commit(struct drm_encoder *encoder, void *data);
43void exynos_drm_encoder_dpms_from_crtc(struct drm_encoder *encoder, 45void exynos_drm_encoder_dpms_from_crtc(struct drm_encoder *encoder,
44 void *data); 46 void *data);
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fimd.c b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
index 0b76bc058bc..fe4172e48ad 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fimd.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fimd.c
@@ -161,12 +161,15 @@ static void fimd_apply(struct device *subdrv_dev)
161 struct exynos_drm_manager_ops *mgr_ops = mgr->ops; 161 struct exynos_drm_manager_ops *mgr_ops = mgr->ops;
162 struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops; 162 struct exynos_drm_overlay_ops *ovl_ops = mgr->overlay_ops;
163 struct fimd_win_data *win_data; 163 struct fimd_win_data *win_data;
164 int i;
164 165
165 DRM_DEBUG_KMS("%s\n", __FILE__); 166 DRM_DEBUG_KMS("%s\n", __FILE__);
166 167
167 win_data = &ctx->win_data[ctx->default_win]; 168 for (i = 0; i < WINDOWS_NR; i++) {
168 if (win_data->enabled && (ovl_ops && ovl_ops->commit)) 169 win_data = &ctx->win_data[i];
169 ovl_ops->commit(subdrv_dev); 170 if (win_data->enabled && (ovl_ops && ovl_ops->commit))
171 ovl_ops->commit(subdrv_dev, i);
172 }
170 173
171 if (mgr_ops && mgr_ops->commit) 174 if (mgr_ops && mgr_ops->commit)
172 mgr_ops->commit(subdrv_dev); 175 mgr_ops->commit(subdrv_dev);
@@ -277,6 +280,7 @@ static void fimd_win_mode_set(struct device *dev,
277{ 280{
278 struct fimd_context *ctx = get_fimd_context(dev); 281 struct fimd_context *ctx = get_fimd_context(dev);
279 struct fimd_win_data *win_data; 282 struct fimd_win_data *win_data;
283 int win;
280 unsigned long offset; 284 unsigned long offset;
281 285
282 DRM_DEBUG_KMS("%s\n", __FILE__); 286 DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -286,12 +290,19 @@ static void fimd_win_mode_set(struct device *dev,
286 return; 290 return;
287 } 291 }
288 292
293 win = overlay->zpos;
294 if (win == DEFAULT_ZPOS)
295 win = ctx->default_win;
296
297 if (win < 0 || win > WINDOWS_NR)
298 return;
299
289 offset = overlay->fb_x * (overlay->bpp >> 3); 300 offset = overlay->fb_x * (overlay->bpp >> 3);
290 offset += overlay->fb_y * overlay->pitch; 301 offset += overlay->fb_y * overlay->pitch;
291 302
292 DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, overlay->pitch); 303 DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, overlay->pitch);
293 304
294 win_data = &ctx->win_data[ctx->default_win]; 305 win_data = &ctx->win_data[win];
295 306
296 win_data->offset_x = overlay->crtc_x; 307 win_data->offset_x = overlay->crtc_x;
297 win_data->offset_y = overlay->crtc_y; 308 win_data->offset_y = overlay->crtc_y;
@@ -394,15 +405,18 @@ static void fimd_win_set_colkey(struct device *dev, unsigned int win)
394 writel(keycon1, ctx->regs + WKEYCON1_BASE(win)); 405 writel(keycon1, ctx->regs + WKEYCON1_BASE(win));
395} 406}
396 407
397static void fimd_win_commit(struct device *dev) 408static void fimd_win_commit(struct device *dev, int zpos)
398{ 409{
399 struct fimd_context *ctx = get_fimd_context(dev); 410 struct fimd_context *ctx = get_fimd_context(dev);
400 struct fimd_win_data *win_data; 411 struct fimd_win_data *win_data;
401 int win = ctx->default_win; 412 int win = zpos;
402 unsigned long val, alpha, size; 413 unsigned long val, alpha, size;
403 414
404 DRM_DEBUG_KMS("%s\n", __FILE__); 415 DRM_DEBUG_KMS("%s\n", __FILE__);
405 416
417 if (win == DEFAULT_ZPOS)
418 win = ctx->default_win;
419
406 if (win < 0 || win > WINDOWS_NR) 420 if (win < 0 || win > WINDOWS_NR)
407 return; 421 return;
408 422
@@ -499,15 +513,18 @@ static void fimd_win_commit(struct device *dev)
499 win_data->enabled = true; 513 win_data->enabled = true;
500} 514}
501 515
502static void fimd_win_disable(struct device *dev) 516static void fimd_win_disable(struct device *dev, int zpos)
503{ 517{
504 struct fimd_context *ctx = get_fimd_context(dev); 518 struct fimd_context *ctx = get_fimd_context(dev);
505 struct fimd_win_data *win_data; 519 struct fimd_win_data *win_data;
506 int win = ctx->default_win; 520 int win = zpos;
507 u32 val; 521 u32 val;
508 522
509 DRM_DEBUG_KMS("%s\n", __FILE__); 523 DRM_DEBUG_KMS("%s\n", __FILE__);
510 524
525 if (win == DEFAULT_ZPOS)
526 win = ctx->default_win;
527
511 if (win < 0 || win > WINDOWS_NR) 528 if (win < 0 || win > WINDOWS_NR)
512 return; 529 return;
513 530
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.c b/drivers/gpu/drm/exynos/exynos_drm_plane.c
new file mode 100644
index 00000000000..c785e34ccff
--- /dev/null
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.c
@@ -0,0 +1,163 @@
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
12#include "drmP.h"
13
14#include "exynos_drm.h"
15#include "exynos_drm_crtc.h"
16#include "exynos_drm_drv.h"
17#include "exynos_drm_encoder.h"
18
19struct exynos_plane {
20 struct drm_plane base;
21 struct exynos_drm_overlay overlay;
22 bool enabled;
23};
24
25static int
26exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
27 struct drm_framebuffer *fb, int crtc_x, int crtc_y,
28 unsigned int crtc_w, unsigned int crtc_h,
29 uint32_t src_x, uint32_t src_y,
30 uint32_t src_w, uint32_t src_h)
31{
32 struct exynos_plane *exynos_plane =
33 container_of(plane, struct exynos_plane, base);
34 struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
35 struct exynos_drm_crtc_pos pos;
36 unsigned int x = src_x >> 16;
37 unsigned int y = src_y >> 16;
38 int ret;
39
40 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
41
42 memset(&pos, 0, sizeof(struct exynos_drm_crtc_pos));
43 pos.crtc_x = crtc_x;
44 pos.crtc_y = crtc_y;
45 pos.crtc_w = crtc_w;
46 pos.crtc_h = crtc_h;
47
48 pos.fb_x = x;
49 pos.fb_y = y;
50
51 /* TODO: scale feature */
52 ret = exynos_drm_overlay_update(overlay, fb, &crtc->mode, &pos);
53 if (ret < 0)
54 return ret;
55
56 exynos_drm_fn_encoder(crtc, overlay,
57 exynos_drm_encoder_crtc_mode_set);
58 exynos_drm_fn_encoder(crtc, &overlay->zpos,
59 exynos_drm_encoder_crtc_plane_commit);
60
61 exynos_plane->enabled = true;
62
63 return 0;
64}
65
66static int exynos_disable_plane(struct drm_plane *plane)
67{
68 struct exynos_plane *exynos_plane =
69 container_of(plane, struct exynos_plane, base);
70 struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
71
72 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
73
74 if (!exynos_plane->enabled)
75 return 0;
76
77 exynos_drm_fn_encoder(plane->crtc, &overlay->zpos,
78 exynos_drm_encoder_crtc_disable);
79
80 exynos_plane->enabled = false;
81 exynos_plane->overlay.zpos = DEFAULT_ZPOS;
82
83 return 0;
84}
85
86static void exynos_plane_destroy(struct drm_plane *plane)
87{
88 struct exynos_plane *exynos_plane =
89 container_of(plane, struct exynos_plane, base);
90
91 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
92
93 exynos_disable_plane(plane);
94 drm_plane_cleanup(plane);
95 kfree(exynos_plane);
96}
97
98static struct drm_plane_funcs exynos_plane_funcs = {
99 .update_plane = exynos_update_plane,
100 .disable_plane = exynos_disable_plane,
101 .destroy = exynos_plane_destroy,
102};
103
104int exynos_plane_init(struct drm_device *dev, unsigned int nr)
105{
106 struct exynos_plane *exynos_plane;
107 uint32_t possible_crtcs;
108
109 exynos_plane = kzalloc(sizeof(struct exynos_plane), GFP_KERNEL);
110 if (!exynos_plane)
111 return -ENOMEM;
112
113 /* all CRTCs are available */
114 possible_crtcs = (1 << MAX_CRTC) - 1;
115
116 exynos_plane->overlay.zpos = DEFAULT_ZPOS;
117
118 /* TODO: format */
119 return drm_plane_init(dev, &exynos_plane->base, possible_crtcs,
120 &exynos_plane_funcs, NULL, 0);
121}
122
123int exynos_plane_set_zpos_ioctl(struct drm_device *dev, void *data,
124 struct drm_file *file_priv)
125{
126 struct drm_exynos_plane_set_zpos *zpos_req = data;
127 struct drm_mode_object *obj;
128 struct drm_plane *plane;
129 struct exynos_plane *exynos_plane;
130 int ret = 0;
131
132 DRM_DEBUG_KMS("[%d] %s\n", __LINE__, __func__);
133
134 if (!drm_core_check_feature(dev, DRIVER_MODESET))
135 return -EINVAL;
136
137 if (zpos_req->zpos < 0 || zpos_req->zpos >= MAX_PLANE) {
138 if (zpos_req->zpos != DEFAULT_ZPOS) {
139 DRM_ERROR("zpos not within limits\n");
140 return -EINVAL;
141 }
142 }
143
144 mutex_lock(&dev->mode_config.mutex);
145
146 obj = drm_mode_object_find(dev, zpos_req->plane_id,
147 DRM_MODE_OBJECT_PLANE);
148 if (!obj) {
149 DRM_DEBUG_KMS("Unknown plane ID %d\n",
150 zpos_req->plane_id);
151 ret = -EINVAL;
152 goto out;
153 }
154
155 plane = obj_to_plane(obj);
156 exynos_plane = container_of(plane, struct exynos_plane, base);
157
158 exynos_plane->overlay.zpos = zpos_req->zpos;
159
160out:
161 mutex_unlock(&dev->mode_config.mutex);
162 return ret;
163}
diff --git a/drivers/gpu/drm/exynos/exynos_drm_plane.h b/drivers/gpu/drm/exynos/exynos_drm_plane.h
new file mode 100644
index 00000000000..16b71f8217e
--- /dev/null
+++ b/drivers/gpu/drm/exynos/exynos_drm_plane.h
@@ -0,0 +1,14 @@
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
12int exynos_plane_init(struct drm_device *dev, unsigned int nr);
13int exynos_plane_set_zpos_ioctl(struct drm_device *dev, void *data,
14 struct drm_file *file_priv);
diff --git a/include/drm/exynos_drm.h b/include/drm/exynos_drm.h
index 12050434d57..7a2262a7689 100644
--- a/include/drm/exynos_drm.h
+++ b/include/drm/exynos_drm.h
@@ -74,9 +74,16 @@ struct drm_exynos_gem_mmap {
74 uint64_t mapped; 74 uint64_t mapped;
75}; 75};
76 76
77struct drm_exynos_plane_set_zpos {
78 __u32 plane_id;
79 __s32 zpos;
80};
81
77#define DRM_EXYNOS_GEM_CREATE 0x00 82#define DRM_EXYNOS_GEM_CREATE 0x00
78#define DRM_EXYNOS_GEM_MAP_OFFSET 0x01 83#define DRM_EXYNOS_GEM_MAP_OFFSET 0x01
79#define DRM_EXYNOS_GEM_MMAP 0x02 84#define DRM_EXYNOS_GEM_MMAP 0x02
85/* Reserved 0x03 ~ 0x05 for exynos specific gem ioctl */
86#define DRM_EXYNOS_PLANE_SET_ZPOS 0x06
80 87
81#define DRM_IOCTL_EXYNOS_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + \ 88#define DRM_IOCTL_EXYNOS_GEM_CREATE DRM_IOWR(DRM_COMMAND_BASE + \
82 DRM_EXYNOS_GEM_CREATE, struct drm_exynos_gem_create) 89 DRM_EXYNOS_GEM_CREATE, struct drm_exynos_gem_create)
@@ -87,6 +94,9 @@ struct drm_exynos_gem_mmap {
87#define DRM_IOCTL_EXYNOS_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + \ 94#define DRM_IOCTL_EXYNOS_GEM_MMAP DRM_IOWR(DRM_COMMAND_BASE + \
88 DRM_EXYNOS_GEM_MMAP, struct drm_exynos_gem_mmap) 95 DRM_EXYNOS_GEM_MMAP, struct drm_exynos_gem_mmap)
89 96
97#define DRM_IOCTL_EXYNOS_PLANE_SET_ZPOS DRM_IOWR(DRM_COMMAND_BASE + \
98 DRM_EXYNOS_PLANE_SET_ZPOS, struct drm_exynos_plane_set_zpos)
99
90/** 100/**
91 * Platform Specific Structure for DRM based FIMD. 101 * Platform Specific Structure for DRM based FIMD.
92 * 102 *