1e07b650662ea0529d99741691c47856ef1034c9cInki Dae/*
2e07b650662ea0529d99741691c47856ef1034c9cInki Dae * Copyright (C) 2012 Samsung Electronics Co., Ltd.
3e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
4e07b650662ea0529d99741691c47856ef1034c9cInki Dae * Permission is hereby granted, free of charge, to any person obtaining a
5e07b650662ea0529d99741691c47856ef1034c9cInki Dae * copy of this software and associated documentation files (the "Software"),
6e07b650662ea0529d99741691c47856ef1034c9cInki Dae * to deal in the Software without restriction, including without limitation
7e07b650662ea0529d99741691c47856ef1034c9cInki Dae * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8e07b650662ea0529d99741691c47856ef1034c9cInki Dae * and/or sell copies of the Software, and to permit persons to whom the
9e07b650662ea0529d99741691c47856ef1034c9cInki Dae * Software is furnished to do so, subject to the following conditions:
10e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
11e07b650662ea0529d99741691c47856ef1034c9cInki Dae * The above copyright notice and this permission notice (including the next
12e07b650662ea0529d99741691c47856ef1034c9cInki Dae * paragraph) shall be included in all copies or substantial portions of the
13e07b650662ea0529d99741691c47856ef1034c9cInki Dae * Software.
14e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
15e07b650662ea0529d99741691c47856ef1034c9cInki Dae * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16e07b650662ea0529d99741691c47856ef1034c9cInki Dae * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17e07b650662ea0529d99741691c47856ef1034c9cInki Dae * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18e07b650662ea0529d99741691c47856ef1034c9cInki Dae * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19e07b650662ea0529d99741691c47856ef1034c9cInki Dae * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20e07b650662ea0529d99741691c47856ef1034c9cInki Dae * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21e07b650662ea0529d99741691c47856ef1034c9cInki Dae * SOFTWARE.
22e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
23e07b650662ea0529d99741691c47856ef1034c9cInki Dae * Authors:
24e07b650662ea0529d99741691c47856ef1034c9cInki Dae *    Inki Dae <inki.dae@samsung.com>
25e07b650662ea0529d99741691c47856ef1034c9cInki Dae */
26e07b650662ea0529d99741691c47856ef1034c9cInki Dae
27e07b650662ea0529d99741691c47856ef1034c9cInki Dae#ifdef HAVE_CONFIG_H
28e07b650662ea0529d99741691c47856ef1034c9cInki Dae#include "config.h"
29e07b650662ea0529d99741691c47856ef1034c9cInki Dae#endif
30e07b650662ea0529d99741691c47856ef1034c9cInki Dae
31e07b650662ea0529d99741691c47856ef1034c9cInki Dae#include <stdlib.h>
32e07b650662ea0529d99741691c47856ef1034c9cInki Dae#include <stdio.h>
33e07b650662ea0529d99741691c47856ef1034c9cInki Dae#include <string.h>
34e07b650662ea0529d99741691c47856ef1034c9cInki Dae#include <errno.h>
35e07b650662ea0529d99741691c47856ef1034c9cInki Dae
36e07b650662ea0529d99741691c47856ef1034c9cInki Dae#include <sys/mman.h>
37e07b650662ea0529d99741691c47856ef1034c9cInki Dae#include <linux/stddef.h>
38e07b650662ea0529d99741691c47856ef1034c9cInki Dae
39e07b650662ea0529d99741691c47856ef1034c9cInki Dae#include <xf86drm.h>
40e07b650662ea0529d99741691c47856ef1034c9cInki Dae
41d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorst#include "libdrm.h"
42e07b650662ea0529d99741691c47856ef1034c9cInki Dae#include "exynos_drm.h"
43e07b650662ea0529d99741691c47856ef1034c9cInki Dae#include "exynos_drmif.h"
44e07b650662ea0529d99741691c47856ef1034c9cInki Dae
45e07b650662ea0529d99741691c47856ef1034c9cInki Dae/*
46e07b650662ea0529d99741691c47856ef1034c9cInki Dae * Create exynos drm device object.
47e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
48e07b650662ea0529d99741691c47856ef1034c9cInki Dae * @fd: file descriptor to exynos drm driver opened.
49e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
50e07b650662ea0529d99741691c47856ef1034c9cInki Dae * if true, return the device object else NULL.
51e07b650662ea0529d99741691c47856ef1034c9cInki Dae */
52d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorstdrm_public struct exynos_device * exynos_device_create(int fd)
53e07b650662ea0529d99741691c47856ef1034c9cInki Dae{
54e07b650662ea0529d99741691c47856ef1034c9cInki Dae	struct exynos_device *dev;
55e07b650662ea0529d99741691c47856ef1034c9cInki Dae
56e07b650662ea0529d99741691c47856ef1034c9cInki Dae	dev = calloc(sizeof(*dev), 1);
57e07b650662ea0529d99741691c47856ef1034c9cInki Dae	if (!dev) {
58e07b650662ea0529d99741691c47856ef1034c9cInki Dae		fprintf(stderr, "failed to create device[%s].\n",
59e07b650662ea0529d99741691c47856ef1034c9cInki Dae				strerror(errno));
60e07b650662ea0529d99741691c47856ef1034c9cInki Dae		return NULL;
61e07b650662ea0529d99741691c47856ef1034c9cInki Dae	}
62e07b650662ea0529d99741691c47856ef1034c9cInki Dae
63e07b650662ea0529d99741691c47856ef1034c9cInki Dae	dev->fd = fd;
64e07b650662ea0529d99741691c47856ef1034c9cInki Dae
65e07b650662ea0529d99741691c47856ef1034c9cInki Dae	return dev;
66e07b650662ea0529d99741691c47856ef1034c9cInki Dae}
67e07b650662ea0529d99741691c47856ef1034c9cInki Dae
68e07b650662ea0529d99741691c47856ef1034c9cInki Dae/*
69e07b650662ea0529d99741691c47856ef1034c9cInki Dae * Destroy exynos drm device object
70e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
71e07b650662ea0529d99741691c47856ef1034c9cInki Dae * @dev: exynos drm device object.
72e07b650662ea0529d99741691c47856ef1034c9cInki Dae */
73d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorstdrm_public void exynos_device_destroy(struct exynos_device *dev)
74e07b650662ea0529d99741691c47856ef1034c9cInki Dae{
75e07b650662ea0529d99741691c47856ef1034c9cInki Dae	free(dev);
76e07b650662ea0529d99741691c47856ef1034c9cInki Dae}
77e07b650662ea0529d99741691c47856ef1034c9cInki Dae
78e07b650662ea0529d99741691c47856ef1034c9cInki Dae/*
79e07b650662ea0529d99741691c47856ef1034c9cInki Dae * Create a exynos buffer object to exynos drm device.
80e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
81e07b650662ea0529d99741691c47856ef1034c9cInki Dae * @dev: exynos drm device object.
82e07b650662ea0529d99741691c47856ef1034c9cInki Dae * @size: user-desired size.
83e07b650662ea0529d99741691c47856ef1034c9cInki Dae * flags: user-desired memory type.
84e07b650662ea0529d99741691c47856ef1034c9cInki Dae *	user can set one or more types among several types to memory
85e07b650662ea0529d99741691c47856ef1034c9cInki Dae *	allocation and cache attribute types. and as default,
86e07b650662ea0529d99741691c47856ef1034c9cInki Dae *	EXYNOS_BO_NONCONTIG and EXYNOS-BO_NONCACHABLE types would
87e07b650662ea0529d99741691c47856ef1034c9cInki Dae *	be used.
88e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
89e07b650662ea0529d99741691c47856ef1034c9cInki Dae * if true, return a exynos buffer object else NULL.
90e07b650662ea0529d99741691c47856ef1034c9cInki Dae */
91d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorstdrm_public struct exynos_bo * exynos_bo_create(struct exynos_device *dev,
92d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorst					       size_t size, uint32_t flags)
93e07b650662ea0529d99741691c47856ef1034c9cInki Dae{
94e07b650662ea0529d99741691c47856ef1034c9cInki Dae	struct exynos_bo *bo;
95e07b650662ea0529d99741691c47856ef1034c9cInki Dae	struct drm_exynos_gem_create req = {
96e07b650662ea0529d99741691c47856ef1034c9cInki Dae		.size = size,
97e07b650662ea0529d99741691c47856ef1034c9cInki Dae		.flags = flags,
98e07b650662ea0529d99741691c47856ef1034c9cInki Dae	};
99e07b650662ea0529d99741691c47856ef1034c9cInki Dae
100e07b650662ea0529d99741691c47856ef1034c9cInki Dae	if (size == 0) {
101e07b650662ea0529d99741691c47856ef1034c9cInki Dae		fprintf(stderr, "invalid size.\n");
102e07b650662ea0529d99741691c47856ef1034c9cInki Dae		goto fail;
103e07b650662ea0529d99741691c47856ef1034c9cInki Dae	}
104e07b650662ea0529d99741691c47856ef1034c9cInki Dae
105e07b650662ea0529d99741691c47856ef1034c9cInki Dae	bo = calloc(sizeof(*bo), 1);
106e07b650662ea0529d99741691c47856ef1034c9cInki Dae	if (!bo) {
107e07b650662ea0529d99741691c47856ef1034c9cInki Dae		fprintf(stderr, "failed to create bo[%s].\n",
108e07b650662ea0529d99741691c47856ef1034c9cInki Dae				strerror(errno));
109e07b650662ea0529d99741691c47856ef1034c9cInki Dae		goto err_free_bo;
110e07b650662ea0529d99741691c47856ef1034c9cInki Dae	}
111e07b650662ea0529d99741691c47856ef1034c9cInki Dae
112e07b650662ea0529d99741691c47856ef1034c9cInki Dae	bo->dev = dev;
113e07b650662ea0529d99741691c47856ef1034c9cInki Dae
114e07b650662ea0529d99741691c47856ef1034c9cInki Dae	if (drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_GEM_CREATE, &req)){
115e07b650662ea0529d99741691c47856ef1034c9cInki Dae		fprintf(stderr, "failed to create gem object[%s].\n",
116e07b650662ea0529d99741691c47856ef1034c9cInki Dae				strerror(errno));
117e07b650662ea0529d99741691c47856ef1034c9cInki Dae		goto err_free_bo;
118e07b650662ea0529d99741691c47856ef1034c9cInki Dae	}
119e07b650662ea0529d99741691c47856ef1034c9cInki Dae
120e07b650662ea0529d99741691c47856ef1034c9cInki Dae	bo->handle = req.handle;
121e07b650662ea0529d99741691c47856ef1034c9cInki Dae	bo->size = size;
122e07b650662ea0529d99741691c47856ef1034c9cInki Dae	bo->flags = flags;
123e07b650662ea0529d99741691c47856ef1034c9cInki Dae
124e07b650662ea0529d99741691c47856ef1034c9cInki Dae	return bo;
125e07b650662ea0529d99741691c47856ef1034c9cInki Dae
126e07b650662ea0529d99741691c47856ef1034c9cInki Daeerr_free_bo:
127e07b650662ea0529d99741691c47856ef1034c9cInki Dae	free(bo);
128e07b650662ea0529d99741691c47856ef1034c9cInki Daefail:
129e07b650662ea0529d99741691c47856ef1034c9cInki Dae	return NULL;
130e07b650662ea0529d99741691c47856ef1034c9cInki Dae}
131e07b650662ea0529d99741691c47856ef1034c9cInki Dae
132e07b650662ea0529d99741691c47856ef1034c9cInki Dae/*
133e07b650662ea0529d99741691c47856ef1034c9cInki Dae * Get information to gem region allocated.
134e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
135e07b650662ea0529d99741691c47856ef1034c9cInki Dae * @dev: exynos drm device object.
136e07b650662ea0529d99741691c47856ef1034c9cInki Dae * @handle: gem handle to request gem info.
137e07b650662ea0529d99741691c47856ef1034c9cInki Dae * @size: size to gem object and returned by kernel side.
138e07b650662ea0529d99741691c47856ef1034c9cInki Dae * @flags: gem flags to gem object and returned by kernel side.
139e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
140e07b650662ea0529d99741691c47856ef1034c9cInki Dae * with this function call, you can get flags and size to gem handle
141e07b650662ea0529d99741691c47856ef1034c9cInki Dae * through bo object.
142e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
143e07b650662ea0529d99741691c47856ef1034c9cInki Dae * if true, return 0 else negative.
144e07b650662ea0529d99741691c47856ef1034c9cInki Dae */
145d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorstdrm_public int exynos_bo_get_info(struct exynos_device *dev, uint32_t handle,
146d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorst				  size_t *size, uint32_t *flags)
147e07b650662ea0529d99741691c47856ef1034c9cInki Dae{
148e07b650662ea0529d99741691c47856ef1034c9cInki Dae	int ret;
149e07b650662ea0529d99741691c47856ef1034c9cInki Dae	struct drm_exynos_gem_info req = {
150e07b650662ea0529d99741691c47856ef1034c9cInki Dae		.handle = handle,
151e07b650662ea0529d99741691c47856ef1034c9cInki Dae	};
152e07b650662ea0529d99741691c47856ef1034c9cInki Dae
153e07b650662ea0529d99741691c47856ef1034c9cInki Dae	ret = drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_GEM_GET, &req);
154e07b650662ea0529d99741691c47856ef1034c9cInki Dae	if (ret < 0) {
155e07b650662ea0529d99741691c47856ef1034c9cInki Dae		fprintf(stderr, "failed to get gem object information[%s].\n",
156e07b650662ea0529d99741691c47856ef1034c9cInki Dae				strerror(errno));
157e07b650662ea0529d99741691c47856ef1034c9cInki Dae		return ret;
158e07b650662ea0529d99741691c47856ef1034c9cInki Dae	}
159e07b650662ea0529d99741691c47856ef1034c9cInki Dae
160e07b650662ea0529d99741691c47856ef1034c9cInki Dae	*size = req.size;
161e07b650662ea0529d99741691c47856ef1034c9cInki Dae	*flags = req.flags;
162e07b650662ea0529d99741691c47856ef1034c9cInki Dae
163e07b650662ea0529d99741691c47856ef1034c9cInki Dae	return 0;
164e07b650662ea0529d99741691c47856ef1034c9cInki Dae}
165e07b650662ea0529d99741691c47856ef1034c9cInki Dae
166e07b650662ea0529d99741691c47856ef1034c9cInki Dae/*
167e07b650662ea0529d99741691c47856ef1034c9cInki Dae * Destroy a exynos buffer object.
168e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
169e07b650662ea0529d99741691c47856ef1034c9cInki Dae * @bo: a exynos buffer object to be destroyed.
170e07b650662ea0529d99741691c47856ef1034c9cInki Dae */
171d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorstdrm_public void exynos_bo_destroy(struct exynos_bo *bo)
172e07b650662ea0529d99741691c47856ef1034c9cInki Dae{
173e07b650662ea0529d99741691c47856ef1034c9cInki Dae	if (!bo)
174e07b650662ea0529d99741691c47856ef1034c9cInki Dae		return;
175e07b650662ea0529d99741691c47856ef1034c9cInki Dae
176e07b650662ea0529d99741691c47856ef1034c9cInki Dae	if (bo->vaddr)
177e07b650662ea0529d99741691c47856ef1034c9cInki Dae		munmap(bo->vaddr, bo->size);
178e07b650662ea0529d99741691c47856ef1034c9cInki Dae
179e07b650662ea0529d99741691c47856ef1034c9cInki Dae	if (bo->handle) {
180e07b650662ea0529d99741691c47856ef1034c9cInki Dae		struct drm_gem_close req = {
181e07b650662ea0529d99741691c47856ef1034c9cInki Dae			.handle = bo->handle,
182e07b650662ea0529d99741691c47856ef1034c9cInki Dae		};
183e07b650662ea0529d99741691c47856ef1034c9cInki Dae
184e07b650662ea0529d99741691c47856ef1034c9cInki Dae		drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req);
185e07b650662ea0529d99741691c47856ef1034c9cInki Dae	}
186e07b650662ea0529d99741691c47856ef1034c9cInki Dae
187e07b650662ea0529d99741691c47856ef1034c9cInki Dae	free(bo);
188e07b650662ea0529d99741691c47856ef1034c9cInki Dae}
189e07b650662ea0529d99741691c47856ef1034c9cInki Dae
190e07b650662ea0529d99741691c47856ef1034c9cInki Dae
191e07b650662ea0529d99741691c47856ef1034c9cInki Dae/*
192e07b650662ea0529d99741691c47856ef1034c9cInki Dae * Get a exynos buffer object from a gem global object name.
193e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
194e07b650662ea0529d99741691c47856ef1034c9cInki Dae * @dev: a exynos device object.
195e07b650662ea0529d99741691c47856ef1034c9cInki Dae * @name: a gem global object name exported by another process.
196e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
197e07b650662ea0529d99741691c47856ef1034c9cInki Dae * this interface is used to get a exynos buffer object from a gem
198e07b650662ea0529d99741691c47856ef1034c9cInki Dae * global object name sent by another process for buffer sharing.
199e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
200e07b650662ea0529d99741691c47856ef1034c9cInki Dae * if true, return a exynos buffer object else NULL.
201e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
202e07b650662ea0529d99741691c47856ef1034c9cInki Dae */
203d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorstdrm_public struct exynos_bo *
204d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorstexynos_bo_from_name(struct exynos_device *dev, uint32_t name)
205e07b650662ea0529d99741691c47856ef1034c9cInki Dae{
206e07b650662ea0529d99741691c47856ef1034c9cInki Dae	struct exynos_bo *bo;
207e07b650662ea0529d99741691c47856ef1034c9cInki Dae	struct drm_gem_open req = {
208e07b650662ea0529d99741691c47856ef1034c9cInki Dae		.name = name,
209e07b650662ea0529d99741691c47856ef1034c9cInki Dae	};
210e07b650662ea0529d99741691c47856ef1034c9cInki Dae
211e07b650662ea0529d99741691c47856ef1034c9cInki Dae	bo = calloc(sizeof(*bo), 1);
212e07b650662ea0529d99741691c47856ef1034c9cInki Dae	if (!bo) {
213e07b650662ea0529d99741691c47856ef1034c9cInki Dae		fprintf(stderr, "failed to allocate bo[%s].\n",
214e07b650662ea0529d99741691c47856ef1034c9cInki Dae				strerror(errno));
215e07b650662ea0529d99741691c47856ef1034c9cInki Dae		return NULL;
216e07b650662ea0529d99741691c47856ef1034c9cInki Dae	}
217e07b650662ea0529d99741691c47856ef1034c9cInki Dae
218e07b650662ea0529d99741691c47856ef1034c9cInki Dae	if (drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req)) {
219e07b650662ea0529d99741691c47856ef1034c9cInki Dae		fprintf(stderr, "failed to open gem object[%s].\n",
220e07b650662ea0529d99741691c47856ef1034c9cInki Dae				strerror(errno));
221e07b650662ea0529d99741691c47856ef1034c9cInki Dae		goto err_free_bo;
222e07b650662ea0529d99741691c47856ef1034c9cInki Dae	}
223e07b650662ea0529d99741691c47856ef1034c9cInki Dae
224e07b650662ea0529d99741691c47856ef1034c9cInki Dae	bo->dev = dev;
225e07b650662ea0529d99741691c47856ef1034c9cInki Dae	bo->name = name;
226e07b650662ea0529d99741691c47856ef1034c9cInki Dae	bo->handle = req.handle;
227e07b650662ea0529d99741691c47856ef1034c9cInki Dae
228e07b650662ea0529d99741691c47856ef1034c9cInki Dae	return bo;
229e07b650662ea0529d99741691c47856ef1034c9cInki Dae
230e07b650662ea0529d99741691c47856ef1034c9cInki Daeerr_free_bo:
231e07b650662ea0529d99741691c47856ef1034c9cInki Dae	free(bo);
232e07b650662ea0529d99741691c47856ef1034c9cInki Dae	return NULL;
233e07b650662ea0529d99741691c47856ef1034c9cInki Dae}
234e07b650662ea0529d99741691c47856ef1034c9cInki Dae
235e07b650662ea0529d99741691c47856ef1034c9cInki Dae/*
236e07b650662ea0529d99741691c47856ef1034c9cInki Dae * Get a gem global object name from a gem object handle.
237e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
238e07b650662ea0529d99741691c47856ef1034c9cInki Dae * @bo: a exynos buffer object including gem handle.
239e07b650662ea0529d99741691c47856ef1034c9cInki Dae * @name: a gem global object name to be got by kernel driver.
240e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
241e07b650662ea0529d99741691c47856ef1034c9cInki Dae * this interface is used to get a gem global object name from a gem object
242e07b650662ea0529d99741691c47856ef1034c9cInki Dae * handle to a buffer that wants to share it with another process.
243e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
244e07b650662ea0529d99741691c47856ef1034c9cInki Dae * if true, return 0 else negative.
245e07b650662ea0529d99741691c47856ef1034c9cInki Dae */
246d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorstdrm_public int exynos_bo_get_name(struct exynos_bo *bo, uint32_t *name)
247e07b650662ea0529d99741691c47856ef1034c9cInki Dae{
248e07b650662ea0529d99741691c47856ef1034c9cInki Dae	if (!bo->name) {
249e07b650662ea0529d99741691c47856ef1034c9cInki Dae		struct drm_gem_flink req = {
250e07b650662ea0529d99741691c47856ef1034c9cInki Dae			.handle = bo->handle,
251e07b650662ea0529d99741691c47856ef1034c9cInki Dae		};
252e07b650662ea0529d99741691c47856ef1034c9cInki Dae		int ret;
253e07b650662ea0529d99741691c47856ef1034c9cInki Dae
254e07b650662ea0529d99741691c47856ef1034c9cInki Dae		ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req);
255e07b650662ea0529d99741691c47856ef1034c9cInki Dae		if (ret) {
256e07b650662ea0529d99741691c47856ef1034c9cInki Dae			fprintf(stderr, "failed to get gem global name[%s].\n",
257e07b650662ea0529d99741691c47856ef1034c9cInki Dae					strerror(errno));
258e07b650662ea0529d99741691c47856ef1034c9cInki Dae			return ret;
259e07b650662ea0529d99741691c47856ef1034c9cInki Dae		}
260e07b650662ea0529d99741691c47856ef1034c9cInki Dae
261e07b650662ea0529d99741691c47856ef1034c9cInki Dae		bo->name = req.name;
262e07b650662ea0529d99741691c47856ef1034c9cInki Dae	}
263e07b650662ea0529d99741691c47856ef1034c9cInki Dae
264e07b650662ea0529d99741691c47856ef1034c9cInki Dae	*name = bo->name;
265e07b650662ea0529d99741691c47856ef1034c9cInki Dae
266e07b650662ea0529d99741691c47856ef1034c9cInki Dae	return 0;
267e07b650662ea0529d99741691c47856ef1034c9cInki Dae}
268e07b650662ea0529d99741691c47856ef1034c9cInki Dae
269d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorstdrm_public uint32_t exynos_bo_handle(struct exynos_bo *bo)
270e07b650662ea0529d99741691c47856ef1034c9cInki Dae{
271e07b650662ea0529d99741691c47856ef1034c9cInki Dae	return bo->handle;
272e07b650662ea0529d99741691c47856ef1034c9cInki Dae}
273e07b650662ea0529d99741691c47856ef1034c9cInki Dae
274e07b650662ea0529d99741691c47856ef1034c9cInki Dae/*
275e07b650662ea0529d99741691c47856ef1034c9cInki Dae * Mmap a buffer to user space.
276e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
277e07b650662ea0529d99741691c47856ef1034c9cInki Dae * @bo: a exynos buffer object including a gem object handle to be mmapped
278e07b650662ea0529d99741691c47856ef1034c9cInki Dae *	to user space.
279e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
280e07b650662ea0529d99741691c47856ef1034c9cInki Dae * if true, user pointer mmaped else NULL.
281e07b650662ea0529d99741691c47856ef1034c9cInki Dae */
282d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorstdrm_public void *exynos_bo_map(struct exynos_bo *bo)
283e07b650662ea0529d99741691c47856ef1034c9cInki Dae{
284e07b650662ea0529d99741691c47856ef1034c9cInki Dae	if (!bo->vaddr) {
285e07b650662ea0529d99741691c47856ef1034c9cInki Dae		struct exynos_device *dev = bo->dev;
286e07b650662ea0529d99741691c47856ef1034c9cInki Dae		struct drm_exynos_gem_mmap req = {
287e07b650662ea0529d99741691c47856ef1034c9cInki Dae			.handle = bo->handle,
288e07b650662ea0529d99741691c47856ef1034c9cInki Dae			.size	= bo->size,
289e07b650662ea0529d99741691c47856ef1034c9cInki Dae		};
290e07b650662ea0529d99741691c47856ef1034c9cInki Dae		int ret;
291e07b650662ea0529d99741691c47856ef1034c9cInki Dae
292e07b650662ea0529d99741691c47856ef1034c9cInki Dae		ret = drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_GEM_MMAP, &req);
293e07b650662ea0529d99741691c47856ef1034c9cInki Dae		if (ret) {
294e07b650662ea0529d99741691c47856ef1034c9cInki Dae			fprintf(stderr, "failed to mmap[%s].\n",
295e07b650662ea0529d99741691c47856ef1034c9cInki Dae				strerror(errno));
296e07b650662ea0529d99741691c47856ef1034c9cInki Dae			return NULL;
297e07b650662ea0529d99741691c47856ef1034c9cInki Dae		}
298e07b650662ea0529d99741691c47856ef1034c9cInki Dae
299ebe21baec5ec180068eb2ec2a97561ba7b482a38Daniel Kurtz		bo->vaddr = (void *)(uintptr_t)req.mapped;
300e07b650662ea0529d99741691c47856ef1034c9cInki Dae	}
301e07b650662ea0529d99741691c47856ef1034c9cInki Dae
302e07b650662ea0529d99741691c47856ef1034c9cInki Dae	return bo->vaddr;
303e07b650662ea0529d99741691c47856ef1034c9cInki Dae}
304e07b650662ea0529d99741691c47856ef1034c9cInki Dae
305e07b650662ea0529d99741691c47856ef1034c9cInki Dae/*
306e07b650662ea0529d99741691c47856ef1034c9cInki Dae * Export gem object to dmabuf as file descriptor.
307e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
308a13bdd5c7197c4c008c0f3976742231cf61d8ce9Daniel Kurtz * @dev: exynos device object
309a13bdd5c7197c4c008c0f3976742231cf61d8ce9Daniel Kurtz * @handle: gem handle to export as file descriptor of dmabuf
310a13bdd5c7197c4c008c0f3976742231cf61d8ce9Daniel Kurtz * @fd: file descriptor returned from kernel
311e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
312a13bdd5c7197c4c008c0f3976742231cf61d8ce9Daniel Kurtz * @return: 0 on success, -1 on error, and errno will be set
313e07b650662ea0529d99741691c47856ef1034c9cInki Dae */
314d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorstdrm_public int
315d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorstexynos_prime_handle_to_fd(struct exynos_device *dev, uint32_t handle, int *fd)
316e07b650662ea0529d99741691c47856ef1034c9cInki Dae{
317a13bdd5c7197c4c008c0f3976742231cf61d8ce9Daniel Kurtz	return drmPrimeHandleToFD(dev->fd, handle, 0, fd);
318e07b650662ea0529d99741691c47856ef1034c9cInki Dae}
319e07b650662ea0529d99741691c47856ef1034c9cInki Dae
320e07b650662ea0529d99741691c47856ef1034c9cInki Dae/*
321e07b650662ea0529d99741691c47856ef1034c9cInki Dae * Import file descriptor into gem handle.
322e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
323a13bdd5c7197c4c008c0f3976742231cf61d8ce9Daniel Kurtz * @dev: exynos device object
324a13bdd5c7197c4c008c0f3976742231cf61d8ce9Daniel Kurtz * @fd: file descriptor of dmabuf to import
325a13bdd5c7197c4c008c0f3976742231cf61d8ce9Daniel Kurtz * @handle: gem handle returned from kernel
326e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
327a13bdd5c7197c4c008c0f3976742231cf61d8ce9Daniel Kurtz * @return: 0 on success, -1 on error, and errno will be set
328e07b650662ea0529d99741691c47856ef1034c9cInki Dae */
329d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorstdrm_public int
330d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorstexynos_prime_fd_to_handle(struct exynos_device *dev, int fd, uint32_t *handle)
331e07b650662ea0529d99741691c47856ef1034c9cInki Dae{
332a13bdd5c7197c4c008c0f3976742231cf61d8ce9Daniel Kurtz	return drmPrimeFDToHandle(dev->fd, fd, handle);
333e07b650662ea0529d99741691c47856ef1034c9cInki Dae}
334e07b650662ea0529d99741691c47856ef1034c9cInki Dae
335e07b650662ea0529d99741691c47856ef1034c9cInki Dae
336e07b650662ea0529d99741691c47856ef1034c9cInki Dae
337e07b650662ea0529d99741691c47856ef1034c9cInki Dae/*
338e07b650662ea0529d99741691c47856ef1034c9cInki Dae * Request Wireless Display connection or disconnection.
339e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
340e07b650662ea0529d99741691c47856ef1034c9cInki Dae * @dev: a exynos device object.
341e07b650662ea0529d99741691c47856ef1034c9cInki Dae * @connect: indicate whether connectoin or disconnection request.
342e07b650662ea0529d99741691c47856ef1034c9cInki Dae * @ext: indicate whether edid data includes extentions data or not.
343e07b650662ea0529d99741691c47856ef1034c9cInki Dae * @edid: a pointer to edid data from Wireless Display device.
344e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
345e07b650662ea0529d99741691c47856ef1034c9cInki Dae * this interface is used to request Virtual Display driver connection or
346e07b650662ea0529d99741691c47856ef1034c9cInki Dae * disconnection. for this, user should get a edid data from the Wireless
347e07b650662ea0529d99741691c47856ef1034c9cInki Dae * Display device and then send that data to kernel driver with connection
348e07b650662ea0529d99741691c47856ef1034c9cInki Dae * request
349e07b650662ea0529d99741691c47856ef1034c9cInki Dae *
350e07b650662ea0529d99741691c47856ef1034c9cInki Dae * if true, return 0 else negative.
351e07b650662ea0529d99741691c47856ef1034c9cInki Dae */
352d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorstdrm_public int
353d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorstexynos_vidi_connection(struct exynos_device *dev, uint32_t connect,
354d9ce09de12131fa8c5ff2d7c2dbd6b61d8a5fd14Maarten Lankhorst		       uint32_t ext, void *edid)
355e07b650662ea0529d99741691c47856ef1034c9cInki Dae{
356e07b650662ea0529d99741691c47856ef1034c9cInki Dae	struct drm_exynos_vidi_connection req = {
357e07b650662ea0529d99741691c47856ef1034c9cInki Dae		.connection	= connect,
358e07b650662ea0529d99741691c47856ef1034c9cInki Dae		.extensions	= ext,
359ebe21baec5ec180068eb2ec2a97561ba7b482a38Daniel Kurtz		.edid		= (uint64_t)(uintptr_t)edid,
360e07b650662ea0529d99741691c47856ef1034c9cInki Dae	};
361e07b650662ea0529d99741691c47856ef1034c9cInki Dae	int ret;
362e07b650662ea0529d99741691c47856ef1034c9cInki Dae
363e07b650662ea0529d99741691c47856ef1034c9cInki Dae	ret = drmIoctl(dev->fd, DRM_IOCTL_EXYNOS_VIDI_CONNECTION, &req);
364e07b650662ea0529d99741691c47856ef1034c9cInki Dae	if (ret) {
365e07b650662ea0529d99741691c47856ef1034c9cInki Dae		fprintf(stderr, "failed to request vidi connection[%s].\n",
366e07b650662ea0529d99741691c47856ef1034c9cInki Dae				strerror(errno));
367e07b650662ea0529d99741691c47856ef1034c9cInki Dae		return ret;
368e07b650662ea0529d99741691c47856ef1034c9cInki Dae	}
369e07b650662ea0529d99741691c47856ef1034c9cInki Dae
370e07b650662ea0529d99741691c47856ef1034c9cInki Dae	return 0;
371e07b650662ea0529d99741691c47856ef1034c9cInki Dae}
372