blob: 50dd59e5591f5befebff069440ce81b8393c9356 [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 }
Ao Xu6747bbd2020-09-28 20:02:09 +080044 dev->fd = fd;
chen.wang1bace1312023-01-18 16:13:54 +080045 dev->render_fd = render_fd;
Ao Xu6747bbd2020-09-28 20:02:09 +080046 return dev;
47}
48
49/*
50 * Destroy meson drm device object
51 *
52 * @dev: meson drm device object.
53 */
54void meson_device_destroy(struct meson_device *dev)
55{
56 free(dev);
57}
58
59/*
60 * Create a meson buffer object to meson drm device.
61 *
62 * @dev: meson drm device object.
63 * @size: buffer size.
64 * @flags: buffer allocation flag.
65 *
66 * user can set one or more flags to allocation specified buffer object
67 *
68 * if true, return a meson buffer object else NULL.
69 */
wenlong.zhang4c011d42022-06-09 10:59:38 +080070struct meson_bo *meson_bo_create(struct meson_device *dev, size_t size,
71 uint32_t flags, int alloc_only)
Ao Xu6747bbd2020-09-28 20:02:09 +080072{
wenlong.zhang4c011d42022-06-09 10:59:38 +080073 int fd;
Ao Xu6747bbd2020-09-28 20:02:09 +080074 struct meson_bo *bo;
75 struct drm_meson_gem_create req = {
76 .size = size,
77 .flags = flags,
78 };
79
80 if (size == 0) {
81 fprintf(stderr, "invalid size.\n");
82 goto fail;
83 }
Ao Xu6747bbd2020-09-28 20:02:09 +080084 bo = calloc(sizeof(*bo), 1);
chen.wang1bace1312023-01-18 16:13:54 +080085 printf("meson_bo_create:%p\n",bo);
Ao Xu6747bbd2020-09-28 20:02:09 +080086 if (!bo) {
87 fprintf(stderr, "failed to create bo[%s].\n",
88 strerror(errno));
89 goto err_free_bo;
90 }
91
92 bo->dev = dev;
chen.wang1bace1312023-01-18 16:13:54 +080093 fd = alloc_only ? dev->render_fd : dev->fd;
Ao Xu6747bbd2020-09-28 20:02:09 +080094
wenlong.zhang4c011d42022-06-09 10:59:38 +080095 if (drmIoctl(fd, DRM_IOCTL_MESON_GEM_CREATE, &req)) {
Ao Xu6747bbd2020-09-28 20:02:09 +080096 fprintf(stderr, "failed to create gem object[%s].\n",
97 strerror(errno));
98 goto err_free_bo;
99 }
100
101 bo->handle = req.handle;
102 bo->size = size;
103 bo->flags = flags;
Ao Xu6747bbd2020-09-28 20:02:09 +0800104 return bo;
105
106err_free_bo:
107 free(bo);
108fail:
109 return NULL;
110}
111
112/*
113 * Destroy a meson buffer object.
114 * @bo: a meson buffer object to be destroyed.
115 */
116void meson_bo_destroy(struct meson_bo *bo)
117{
chen.wang1bace1312023-01-18 16:13:54 +0800118 printf("meson_bo_destroy:%p\n",bo);
Ao Xu6747bbd2020-09-28 20:02:09 +0800119 if (!bo)
120 return;
Ao Xu6747bbd2020-09-28 20:02:09 +0800121 if (bo->vaddr)
122 munmap(bo->vaddr, bo->size);
Ao Xu6747bbd2020-09-28 20:02:09 +0800123 if (bo->fd)
124 close(bo->fd);
Ao Xu6747bbd2020-09-28 20:02:09 +0800125 if (bo->handle) {
126 struct drm_gem_close req = {
127 .handle = bo->handle,
128 };
Ao Xu6747bbd2020-09-28 20:02:09 +0800129 drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req);
130 }
Ao Xu6747bbd2020-09-28 20:02:09 +0800131 free(bo);
132}
133
134uint32_t meson_bo_handle(struct meson_bo *bo)
135{
136 return bo->handle;
137}
138
wenlong.zhang4c011d42022-06-09 10:59:38 +0800139int meson_bo_dmabuf(struct meson_bo *bo, int alloc_only)
Ao Xu6747bbd2020-09-28 20:02:09 +0800140{
chen.wang1bace1312023-01-18 16:13:54 +0800141 int fd;
142 fd = alloc_only ? bo->dev->render_fd : bo->dev->fd;
Ao Xu6747bbd2020-09-28 20:02:09 +0800143 if (!bo->fd) {
144 struct drm_prime_handle req = {
145 .handle = bo->handle,
Ao Xu7e75e5f2020-11-04 14:05:24 +0800146 .flags = DRM_CLOEXEC | DRM_RDWR,
Ao Xu6747bbd2020-09-28 20:02:09 +0800147 };
148
149 int ret;
150
wenlong.zhang4c011d42022-06-09 10:59:38 +0800151 ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &req);
Ao Xu6747bbd2020-09-28 20:02:09 +0800152 if (ret)
153 return ret;
154
155 bo->fd = req.fd;
156 }
157
Ao Xu771b5ad2020-10-26 15:59:21 +0800158 return bo->fd;
Ao Xu6747bbd2020-09-28 20:02:09 +0800159}
160
161size_t meson_bo_size(struct meson_bo *bo)
162{
163 return bo->size;
164}
Ao Xu70554242020-10-15 15:19:48 +0800165
166struct meson_bo *meson_bo_import(struct meson_device *dev, int fd, size_t size, uint32_t flags)
167{
168 int ret;
169 struct meson_bo *bo = NULL;
170
171 struct drm_prime_handle req = {
172 .fd = fd,
173 };
174
175 bo = calloc(sizeof(*bo), 1);
176 if (!bo) {
177 fprintf(stderr, "failed to create bo[%s].\n",
178 strerror(errno));
179 goto fail;
180 }
181
182 ret = drmIoctl(dev->fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &req);
183 if (ret)
184 goto err_free_bo;
185
186 bo->dev = dev;
187 bo->size = size;
188 bo->flags = flags;
189 bo->handle = req.handle;
190
191 return bo;
192
193err_free_bo:
194 free(bo);
195fail:
196 return NULL;
197}