blob: 91b4de2c99e6c2f083d914da87dbe25109abe20a [file] [log] [blame]
limin.tian79bf2b12023-02-24 10:28:26 +00001 /*
2 * Copyright (c) 2019 Amlogic, Inc. All rights reserved.
Ao Xu6747bbd2020-09-28 20:02:09 +08003 *
limin.tian79bf2b12023-02-24 10:28:26 +00004 * This source code is subject to the terms and conditions defined in the
5 * file 'LICENSE' which is part of this source code package.
6 *
7 * Description:
Ao Xu6747bbd2020-09-28 20:02:09 +08008 */
9
10#ifdef HAVE_CONFIG_H
11#include "config.h"
12#endif
13
14#include <stdlib.h>
15#include <linux/stddef.h>
16#include <linux/types.h>
17#include <errno.h>
18#include <sys/mman.h>
19#include <fcntl.h>
20#include <unistd.h>
21#include <pthread.h>
22
23#include <xf86drm.h>
24
25#include "meson_drm.h"
26#include "meson_drmif.h"
27
28/*
29 * Create meson drm device object.
30 * @fd: file descriptor to meson drm driver opened.
31 *
32 * if true, returen the device object else NULL.
33 */
wenlong.zhang4c011d42022-06-09 10:59:38 +080034struct meson_device *meson_device_create(int fd, int render_fd)
Ao Xu6747bbd2020-09-28 20:02:09 +080035{
36 struct meson_device *dev;
37
38 dev = calloc(sizeof(*dev), 1);
39 if (!dev) {
40 fprintf(stderr, "failed to create device[%s].\n",
41 strerror(errno));
42 return NULL;
43 }
44
45 dev->fd = fd;
wenlong.zhang4c011d42022-06-09 10:59:38 +080046 dev->render_fd = render_fd;
Ao Xu6747bbd2020-09-28 20:02:09 +080047
48 return dev;
49}
50
51/*
52 * Destroy meson drm device object
53 *
54 * @dev: meson drm device object.
55 */
56void meson_device_destroy(struct meson_device *dev)
57{
58 free(dev);
59}
60
61/*
62 * Create a meson buffer object to meson drm device.
63 *
64 * @dev: meson drm device object.
65 * @size: buffer size.
66 * @flags: buffer allocation flag.
67 *
68 * user can set one or more flags to allocation specified buffer object
69 *
70 * if true, return a meson buffer object else NULL.
71 */
wenlong.zhang4c011d42022-06-09 10:59:38 +080072struct meson_bo *meson_bo_create(struct meson_device *dev, size_t size,
73 uint32_t flags, int alloc_only)
Ao Xu6747bbd2020-09-28 20:02:09 +080074{
wenlong.zhang4c011d42022-06-09 10:59:38 +080075 int fd;
Ao Xu6747bbd2020-09-28 20:02:09 +080076 struct meson_bo *bo;
77 struct drm_meson_gem_create req = {
78 .size = size,
79 .flags = flags,
80 };
81
82 if (size == 0) {
83 fprintf(stderr, "invalid size.\n");
84 goto fail;
85 }
86
87 bo = calloc(sizeof(*bo), 1);
88 if (!bo) {
89 fprintf(stderr, "failed to create bo[%s].\n",
90 strerror(errno));
91 goto err_free_bo;
92 }
93
94 bo->dev = dev;
wenlong.zhang4c011d42022-06-09 10:59:38 +080095 fd = alloc_only ? dev->render_fd : dev->fd;
Ao Xu6747bbd2020-09-28 20:02:09 +080096
wenlong.zhang4c011d42022-06-09 10:59:38 +080097 if (drmIoctl(fd, DRM_IOCTL_MESON_GEM_CREATE, &req)) {
Ao Xu6747bbd2020-09-28 20:02:09 +080098 fprintf(stderr, "failed to create gem object[%s].\n",
99 strerror(errno));
100 goto err_free_bo;
101 }
102
103 bo->handle = req.handle;
104 bo->size = size;
105 bo->flags = flags;
106
107 return bo;
108
109err_free_bo:
110 free(bo);
111fail:
112 return NULL;
113}
114
115/*
116 * Destroy a meson buffer object.
117 * @bo: a meson buffer object to be destroyed.
118 */
119void meson_bo_destroy(struct meson_bo *bo)
120{
121 if (!bo)
122 return;
123
124 if (bo->vaddr)
125 munmap(bo->vaddr, bo->size);
126
127 if (bo->fd)
128 close(bo->fd);
129
130 if (bo->handle) {
131 struct drm_gem_close req = {
132 .handle = bo->handle,
133 };
134
135 drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req);
136 }
137
138 free(bo);
139}
140
141uint32_t meson_bo_handle(struct meson_bo *bo)
142{
143 return bo->handle;
144}
145
wenlong.zhang4c011d42022-06-09 10:59:38 +0800146int meson_bo_dmabuf(struct meson_bo *bo, int alloc_only)
Ao Xu6747bbd2020-09-28 20:02:09 +0800147{
wenlong.zhang4c011d42022-06-09 10:59:38 +0800148 int fd;
149
150 fd = alloc_only ? bo->dev->render_fd : bo->dev->fd;
Ao Xu6747bbd2020-09-28 20:02:09 +0800151 if (!bo->fd) {
152 struct drm_prime_handle req = {
153 .handle = bo->handle,
Ao Xu7e75e5f2020-11-04 14:05:24 +0800154 .flags = DRM_CLOEXEC | DRM_RDWR,
Ao Xu6747bbd2020-09-28 20:02:09 +0800155 };
156
157 int ret;
158
wenlong.zhang4c011d42022-06-09 10:59:38 +0800159 ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &req);
Ao Xu6747bbd2020-09-28 20:02:09 +0800160 if (ret)
161 return ret;
162
163 bo->fd = req.fd;
164 }
165
Ao Xu771b5ad2020-10-26 15:59:21 +0800166 return bo->fd;
Ao Xu6747bbd2020-09-28 20:02:09 +0800167}
168
169size_t meson_bo_size(struct meson_bo *bo)
170{
171 return bo->size;
172}
Ao Xu70554242020-10-15 15:19:48 +0800173
174struct meson_bo *meson_bo_import(struct meson_device *dev, int fd, size_t size, uint32_t flags)
175{
176 int ret;
177 struct meson_bo *bo = NULL;
178
179 struct drm_prime_handle req = {
180 .fd = fd,
181 };
182
183 bo = calloc(sizeof(*bo), 1);
184 if (!bo) {
185 fprintf(stderr, "failed to create bo[%s].\n",
186 strerror(errno));
187 goto fail;
188 }
189
190 ret = drmIoctl(dev->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &req);
191 if (ret)
192 goto err_free_bo;
193
194 bo->dev = dev;
195 bo->size = size;
196 bo->flags = flags;
197 bo->handle = req.handle;
198
199 return bo;
200
201err_free_bo:
202 free(bo);
203fail:
204 return NULL;
205}