1bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq/*
2bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * Copyright (C) ROCKCHIP, Inc.
3bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * Author:yzq<yzq@rock-chips.com>
4bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
5bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * based on exynos_drm.c
6bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
7bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * Permission is hereby granted, free of charge, to any person obtaining a
8bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * copy of this software and associated documentation files (the "Software"),
9bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * to deal in the Software without restriction, including without limitation
10bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * and/or sell copies of the Software, and to permit persons to whom the
12bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * Software is furnished to do so, subject to the following conditions:
13bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
14bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * The above copyright notice and this permission notice (including the next
15bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * paragraph) shall be included in all copies or substantial portions of the
16bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * Software.
17bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
18bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
21bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * SOFTWARE.
25bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
26bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq */
27bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
28bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq#ifdef HAVE_CONFIG_H
29bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq#include "config.h"
30bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq#endif
31bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
32bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq#include <stdlib.h>
33bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq#include <stdio.h>
34bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq#include <string.h>
35bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq#include <errno.h>
36bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
37bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq#include <sys/mman.h>
38bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq#include <linux/stddef.h>
39bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
40bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq#include <xf86drm.h>
41bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
42bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq#include "rockchip_drm.h"
43bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq#include "rockchip_drmif.h"
44bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
45bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq/*
46bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * Create rockchip drm device object.
47bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
48bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * @fd: file descriptor to rockchip drm driver opened.
49bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
50bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * if true, return the device object else NULL.
51bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq */
52bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzqstruct rockchip_device *rockchip_device_create(int fd)
53bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq{
54bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	struct rockchip_device *dev;
55bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
56bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	dev = calloc(1, sizeof(*dev));
57bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	if (!dev) {
58bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		fprintf(stderr, "failed to create device[%s].\n",
59bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq				strerror(errno));
60bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		return NULL;
61bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	}
62bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
63bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	dev->fd = fd;
64bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
65bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	return dev;
66bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq}
67bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
68bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq/*
69bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * Destroy rockchip drm device object
70bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
71bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * @dev: rockchip drm device object.
72bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq */
73bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzqvoid rockchip_device_destroy(struct rockchip_device *dev)
74bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq{
75bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	free(dev);
76bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq}
77bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
78bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq/*
79bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * Create a rockchip buffer object to rockchip drm device.
80bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
81bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * @dev: rockchip drm device object.
82bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * @size: user-desired size.
83bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * flags: user-desired memory type.
84bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *	user can set one or more types among several types to memory
85bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *	allocation and cache attribute types. and as default,
86bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *	ROCKCHIP_BO_NONCONTIG and ROCKCHIP-BO_NONCACHABLE types would
87bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *	be used.
88bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
89bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * if true, return a rockchip buffer object else NULL.
90bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq */
91bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzqstruct rockchip_bo *rockchip_bo_create(struct rockchip_device *dev,
92bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq					size_t size, uint32_t flags)
93bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq{
94bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	struct rockchip_bo *bo;
95bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	struct drm_rockchip_gem_create req = {
96bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		.size = size,
97bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		.flags = flags,
98bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	};
99bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
100bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	if (size == 0) {
101bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		fprintf(stderr, "invalid size.\n");
102bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		return NULL;
103bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	}
104bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
105bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	bo = calloc(1, sizeof(*bo));
106bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	if (!bo) {
107bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		fprintf(stderr, "failed to create bo[%s].\n",
108bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq				strerror(errno));
109bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		goto fail;
110bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	}
111bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
112bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	bo->dev = dev;
113bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
114bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	if (drmIoctl(dev->fd, DRM_IOCTL_ROCKCHIP_GEM_CREATE, &req)){
115bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		fprintf(stderr, "failed to create gem object[%s].\n",
116bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq				strerror(errno));
117bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		goto err_free_bo;
118bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	}
119bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
120bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	bo->handle = req.handle;
121bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	bo->size = size;
122bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	bo->flags = flags;
123bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
124bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	return bo;
125bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
126bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzqerr_free_bo:
127bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	free(bo);
128bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzqfail:
129bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	return NULL;
130bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq}
131bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
132a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figastruct rockchip_bo *rockchip_bo_from_handle(struct rockchip_device *dev,
133a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa			uint32_t handle, uint32_t flags, uint32_t size)
134a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa{
135a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa	struct rockchip_bo *bo;
136a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa
137a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa	if (size == 0) {
138a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa		fprintf(stderr, "invalid size.\n");
139a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa		return NULL;
140a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa	}
141a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa
142a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa	bo = calloc(1, sizeof(*bo));
143a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa	if (!bo) {
144a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa		fprintf(stderr, "failed to create bo[%s].\n",
145a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa				strerror(errno));
146a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa		return NULL;
147a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa	}
148a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa
149a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa	bo->dev = dev;
150a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa	bo->handle = handle;
151a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa	bo->size = size;
152a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa	bo->flags = flags;
153a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa
154a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa	return bo;
155a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa}
156a5c8b07b1dad94ca227c17ebecff50aa0e89d776Tomasz Figa
157bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq/*
158bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * Destroy a rockchip buffer object.
159bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
160bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * @bo: a rockchip buffer object to be destroyed.
161bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq */
162bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzqvoid rockchip_bo_destroy(struct rockchip_bo *bo)
163bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq{
164bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	if (!bo)
165bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		return;
166bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
167bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	if (bo->vaddr)
168bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		munmap(bo->vaddr, bo->size);
169bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
170bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	if (bo->handle) {
171bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		struct drm_gem_close req = {
172bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq			.handle = bo->handle,
173bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		};
174bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
175bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req);
176bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	}
177bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
178bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	free(bo);
179bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq}
180bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
181bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
182bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq/*
183bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * Get a rockchip buffer object from a gem global object name.
184bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
185bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * @dev: a rockchip device object.
186bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * @name: a gem global object name exported by another process.
187bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
188bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * this interface is used to get a rockchip buffer object from a gem
189bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * global object name sent by another process for buffer sharing.
190bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
191bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * if true, return a rockchip buffer object else NULL.
192bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
193bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq */
194bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzqstruct rockchip_bo *rockchip_bo_from_name(struct rockchip_device *dev,
195bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq						uint32_t name)
196bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq{
197bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	struct rockchip_bo *bo;
198bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	struct drm_gem_open req = {
199bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		.name = name,
200bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	};
201bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
202bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	bo = calloc(1, sizeof(*bo));
203bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	if (!bo) {
204bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		fprintf(stderr, "failed to allocate bo[%s].\n",
205bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq				strerror(errno));
206bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		return NULL;
207bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	}
208bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
209bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	if (drmIoctl(dev->fd, DRM_IOCTL_GEM_OPEN, &req)) {
210bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		fprintf(stderr, "failed to open gem object[%s].\n",
211bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq				strerror(errno));
212bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		goto err_free_bo;
213bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	}
214bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
215bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	bo->dev = dev;
216bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	bo->name = name;
217bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	bo->handle = req.handle;
218bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
219bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	return bo;
220bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
221bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzqerr_free_bo:
222bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	free(bo);
223bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	return NULL;
224bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq}
225bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
226bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq/*
227bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * Get a gem global object name from a gem object handle.
228bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
229bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * @bo: a rockchip buffer object including gem handle.
230bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * @name: a gem global object name to be got by kernel driver.
231bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
232bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * this interface is used to get a gem global object name from a gem object
233bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * handle to a buffer that wants to share it with another process.
234bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
235bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * if true, return 0 else negative.
236bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq */
237bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzqint rockchip_bo_get_name(struct rockchip_bo *bo, uint32_t *name)
238bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq{
239bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	if (!bo->name) {
240bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		struct drm_gem_flink req = {
241bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq			.handle = bo->handle,
242bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		};
243bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		int ret;
244bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
245bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		ret = drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_FLINK, &req);
246bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		if (ret) {
247bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq			fprintf(stderr, "failed to get gem global name[%s].\n",
248bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq					strerror(errno));
249bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq			return ret;
250bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		}
251bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
252bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		bo->name = req.name;
253bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	}
254bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
255bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	*name = bo->name;
256bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
257bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	return 0;
258bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq}
259bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
260bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzquint32_t rockchip_bo_handle(struct rockchip_bo *bo)
261bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq{
262bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	return bo->handle;
263bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq}
264bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
265bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq/*
266bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * Mmap a buffer to user space.
267bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
268bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * @bo: a rockchip buffer object including a gem object handle to be mmapped
269bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *	to user space.
270bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq *
271bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq * if true, user pointer mmaped else NULL.
272bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq */
273bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzqvoid *rockchip_bo_map(struct rockchip_bo *bo)
274bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq{
275bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	if (!bo->vaddr) {
276bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		struct rockchip_device *dev = bo->dev;
277bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		struct drm_rockchip_gem_map_off req = {
278bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq			.handle = bo->handle,
279bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		};
280bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		int ret;
281bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
282bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		ret = drmIoctl(dev->fd, DRM_IOCTL_ROCKCHIP_GEM_MAP_OFFSET, &req);
283bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		if (ret) {
284bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq			fprintf(stderr, "failed to ioctl gem map offset[%s].\n",
285bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq				strerror(errno));
286bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq			return NULL;
287bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		}
288bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
289bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		bo->vaddr = mmap(0, bo->size, PROT_READ | PROT_WRITE,
290bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq			   MAP_SHARED, dev->fd, req.offset);
291bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		if (bo->vaddr == MAP_FAILED) {
292bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq			fprintf(stderr, "failed to mmap buffer[%s].\n",
293bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq				strerror(errno));
294bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq			return NULL;
295bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq		}
296bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	}
297bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq
298bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq	return bo->vaddr;
299bd00c5c41dab43ab3bd2d7f505df0e8ea3b834e8yzq}
300