aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHyungwon Hwang2014-01-10 01:44:30 -0600
committerRob Clark2014-01-12 07:23:38 -0600
commit3732ef59eb1198d6a4cb5b8bbca6b155c53529f6 (patch)
tree9d8e500111d34b4e291e4a3b4c18b3655f6a67a0
parenta254cb50414a5def5c872a765c0dd1295a550c6b (diff)
downloadexternal-libdrm-3732ef59eb1198d6a4cb5b8bbca6b155c53529f6.tar.gz
external-libdrm-3732ef59eb1198d6a4cb5b8bbca6b155c53529f6.tar.xz
external-libdrm-3732ef59eb1198d6a4cb5b8bbca6b155c53529f6.zip
tests/kmstest: support exynos
In this patch, to support exynos for KMS, Exynos KMS driver is newly added. Also, Exynos is added to the list of kmstest supported modules. Signed-off-by: Hyungwon Hwang <human.hwang@samsung.com> Signed-off-by: Rob Clark <robclark@freedesktop.org>
-rw-r--r--libkms/Makefile.am5
-rw-r--r--libkms/exynos.c207
-rw-r--r--libkms/internal.h2
-rw-r--r--libkms/linux.c4
-rw-r--r--tests/kmstest/main.c1
5 files changed, 219 insertions, 0 deletions
diff --git a/libkms/Makefile.am b/libkms/Makefile.am
index 215450ac..449a73ba 100644
--- a/libkms/Makefile.am
+++ b/libkms/Makefile.am
@@ -31,6 +31,11 @@ if HAVE_RADEON
31libkms_la_SOURCES += radeon.c 31libkms_la_SOURCES += radeon.c
32endif 32endif
33 33
34if HAVE_EXYNOS
35libkms_la_SOURCES += exynos.c
36AM_CFLAGS += -I$(top_srcdir)/exynos
37endif
38
34libkmsincludedir = ${includedir}/libkms 39libkmsincludedir = ${includedir}/libkms
35libkmsinclude_HEADERS = libkms.h 40libkmsinclude_HEADERS = libkms.h
36 41
diff --git a/libkms/exynos.c b/libkms/exynos.c
new file mode 100644
index 00000000..93e36a12
--- /dev/null
+++ b/libkms/exynos.c
@@ -0,0 +1,207 @@
1/* exynos.c
2 *
3 * Copyright 2009 Samsung Electronics Co., Ltd.
4 * Authors:
5 * SooChan Lim <sc1.lim@samsung.com>
6 * Sangjin LEE <lsj119@samsung.com>
7 *
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2 of the License, or (at your
11 * option) any later version.
12 */
13
14#define HAVE_STDINT_H
15#define _FILE_OFFSET_BITS 64
16
17#include <errno.h>
18#include <stdio.h>
19#include <stdlib.h>
20#include <string.h>
21#include "internal.h"
22
23#include <sys/mman.h>
24#include <sys/ioctl.h>
25#include "xf86drm.h"
26
27#include "exynos_drm.h"
28
29struct exynos_bo
30{
31 struct kms_bo base;
32 unsigned map_count;
33};
34
35static int
36exynos_get_prop(struct kms_driver *kms, unsigned key, unsigned *out)
37{
38 switch (key) {
39 case KMS_BO_TYPE:
40 *out = KMS_BO_TYPE_SCANOUT_X8R8G8B8 | KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8;
41 break;
42 default:
43 return -EINVAL;
44 }
45 return 0;
46}
47
48static int
49exynos_destroy(struct kms_driver *kms)
50{
51 free(kms);
52 return 0;
53}
54
55static int
56exynos_bo_create(struct kms_driver *kms,
57 const unsigned width, const unsigned height,
58 const enum kms_bo_type type, const unsigned *attr,
59 struct kms_bo **out)
60{
61 struct drm_exynos_gem_create arg;
62 unsigned size, pitch;
63 struct exynos_bo *bo;
64 int i, ret;
65
66 for (i = 0; attr[i]; i += 2) {
67 switch (attr[i]) {
68 case KMS_WIDTH:
69 case KMS_HEIGHT:
70 case KMS_BO_TYPE:
71 break;
72 default:
73 return -EINVAL;
74 }
75 }
76
77 bo = calloc(1, sizeof(*bo));
78 if (!bo)
79 return -ENOMEM;
80
81 if (type == KMS_BO_TYPE_CURSOR_64X64_A8R8G8B8) {
82 pitch = 64 * 4;
83 size = 64 * 64 * 4;
84 } else if (type == KMS_BO_TYPE_SCANOUT_X8R8G8B8) {
85 pitch = width * 4;
86 pitch = (pitch + 512 - 1) & ~(512 - 1);
87 size = pitch * ((height + 4 - 1) & ~(4 - 1));
88 } else {
89 return -EINVAL;
90 }
91
92 memset(&arg, 0, sizeof(arg));
93 arg.size = size;
94
95 ret = drmCommandWriteRead(kms->fd, DRM_EXYNOS_GEM_CREATE, &arg, sizeof(arg));
96 if (ret)
97 goto err_free;
98
99 bo->base.kms = kms;
100 bo->base.handle = arg.handle;
101 bo->base.size = size;
102 bo->base.pitch = pitch;
103
104 *out = &bo->base;
105
106 return 0;
107
108err_free:
109 free(bo);
110 return ret;
111}
112
113static int
114exynos_bo_get_prop(struct kms_bo *bo, unsigned key, unsigned *out)
115{
116 switch (key) {
117 default:
118 return -EINVAL;
119 }
120}
121
122static int
123exynos_bo_map(struct kms_bo *_bo, void **out)
124{
125 struct exynos_bo *bo = (struct exynos_bo *)_bo;
126 struct drm_exynos_gem_map_off arg;
127 void *map = NULL;
128 int ret;
129
130 if (bo->base.ptr) {
131 bo->map_count++;
132 *out = bo->base.ptr;
133 return 0;
134 }
135
136 memset(&arg, 0, sizeof(arg));
137 arg.handle = bo->base.handle;
138
139 ret = drmCommandWriteRead(bo->base.kms->fd, DRM_EXYNOS_GEM_MAP_OFFSET, &arg, sizeof(arg));
140 if (ret)
141 return ret;
142
143 map = mmap(0, bo->base.size, PROT_READ | PROT_WRITE, MAP_SHARED, bo->base.kms->fd, arg.offset);
144 if (map == MAP_FAILED)
145 return -errno;
146
147 bo->base.ptr = map;
148 bo->map_count++;
149 *out = bo->base.ptr;
150
151 return 0;
152}
153
154static int
155exynos_bo_unmap(struct kms_bo *_bo)
156{
157 struct exynos_bo *bo = (struct exynos_bo *)_bo;
158 bo->map_count--;
159 return 0;
160}
161
162static int
163exynos_bo_destroy(struct kms_bo *_bo)
164{
165 struct exynos_bo *bo = (struct exynos_bo *)_bo;
166 struct drm_gem_close arg;
167 int ret;
168
169 if (bo->base.ptr) {
170 /* XXX Sanity check map_count */
171 munmap(bo->base.ptr, bo->base.size);
172 bo->base.ptr = NULL;
173 }
174
175 memset(&arg, 0, sizeof(arg));
176 arg.handle = bo->base.handle;
177
178 ret = drmIoctl(bo->base.kms->fd, DRM_IOCTL_GEM_CLOSE, &arg);
179 if (ret)
180 return -errno;
181
182 free(bo);
183 return 0;
184}
185
186int
187exynos_create(int fd, struct kms_driver **out)
188{
189 struct kms_driver *kms;
190
191 kms = calloc(1, sizeof(*kms));
192 if (!kms)
193 return -ENOMEM;
194
195 kms->fd = fd;
196
197 kms->bo_create = exynos_bo_create;
198 kms->bo_map = exynos_bo_map;
199 kms->bo_unmap = exynos_bo_unmap;
200 kms->bo_get_prop = exynos_bo_get_prop;
201 kms->bo_destroy = exynos_bo_destroy;
202 kms->get_prop = exynos_get_prop;
203 kms->destroy = exynos_destroy;
204 *out = kms;
205
206 return 0;
207}
diff --git a/libkms/internal.h b/libkms/internal.h
index 5e2501e4..f831b57d 100644
--- a/libkms/internal.h
+++ b/libkms/internal.h
@@ -74,4 +74,6 @@ int nouveau_create(int fd, struct kms_driver **out);
74 74
75int radeon_create(int fd, struct kms_driver **out); 75int radeon_create(int fd, struct kms_driver **out);
76 76
77int exynos_create(int fd, struct kms_driver **out);
78
77#endif 79#endif
diff --git a/libkms/linux.c b/libkms/linux.c
index eec01622..9b4f29e1 100644
--- a/libkms/linux.c
+++ b/libkms/linux.c
@@ -115,6 +115,10 @@ linux_from_sysfs(int fd, struct kms_driver **out)
115 else if (!strcmp(name, "radeon")) 115 else if (!strcmp(name, "radeon"))
116 ret = radeon_create(fd, out); 116 ret = radeon_create(fd, out);
117#endif 117#endif
118#ifdef HAVE_EXYNOS
119 else if (!strcmp(name, "exynos"))
120 ret = exynos_create(fd, out);
121#endif
118 else 122 else
119 ret = -ENOSYS; 123 ret = -ENOSYS;
120 124
diff --git a/tests/kmstest/main.c b/tests/kmstest/main.c
index 5df0a383..449d75f6 100644
--- a/tests/kmstest/main.c
+++ b/tests/kmstest/main.c
@@ -61,6 +61,7 @@ char *drivers[] = {
61 "radeon", 61 "radeon",
62 "nouveau", 62 "nouveau",
63 "vmwgfx", 63 "vmwgfx",
64 "exynos",
64 NULL 65 NULL
65}; 66};
66 67