blob: 60d2001e774429088569d4b86c92398fb4ca7ec3 [file] [log] [blame]
Ao Xu6747bbd2020-09-28 20:02:09 +08001/*
2 * Copyright (C) 2020 Amlogic, Inc. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 */
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 */
34struct meson_device *meson_device_create(int fd)
35{
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;
46
47 return dev;
48}
49
50/*
51 * Destroy meson drm device object
52 *
53 * @dev: meson drm device object.
54 */
55void meson_device_destroy(struct meson_device *dev)
56{
57 free(dev);
58}
59
60/*
61 * Create a meson buffer object to meson drm device.
62 *
63 * @dev: meson drm device object.
64 * @size: buffer size.
65 * @flags: buffer allocation flag.
66 *
67 * user can set one or more flags to allocation specified buffer object
68 *
69 * if true, return a meson buffer object else NULL.
70 */
71struct meson_bo *meson_bo_create(struct meson_device *dev, size_t size, uint32_t flags)
72{
73 struct meson_bo *bo;
74 struct drm_meson_gem_create req = {
75 .size = size,
76 .flags = flags,
77 };
78
79 if (size == 0) {
80 fprintf(stderr, "invalid size.\n");
81 goto fail;
82 }
83
84 bo = calloc(sizeof(*bo), 1);
85 if (!bo) {
86 fprintf(stderr, "failed to create bo[%s].\n",
87 strerror(errno));
88 goto err_free_bo;
89 }
90
91 bo->dev = dev;
92
93 if (drmIoctl(dev->fd, DRM_IOCTL_MESON_GEM_CREATE, &req)) {
94 fprintf(stderr, "failed to create gem object[%s].\n",
95 strerror(errno));
96 goto err_free_bo;
97 }
98
99 bo->handle = req.handle;
100 bo->size = size;
101 bo->flags = flags;
102
103 return bo;
104
105err_free_bo:
106 free(bo);
107fail:
108 return NULL;
109}
110
111/*
112 * Destroy a meson buffer object.
113 * @bo: a meson buffer object to be destroyed.
114 */
115void meson_bo_destroy(struct meson_bo *bo)
116{
117 if (!bo)
118 return;
119
120 if (bo->vaddr)
121 munmap(bo->vaddr, bo->size);
122
123 if (bo->fd)
124 close(bo->fd);
125
126 if (bo->handle) {
127 struct drm_gem_close req = {
128 .handle = bo->handle,
129 };
130
131 drmIoctl(bo->dev->fd, DRM_IOCTL_GEM_CLOSE, &req);
132 }
133
134 free(bo);
135}
136
137uint32_t meson_bo_handle(struct meson_bo *bo)
138{
139 return bo->handle;
140}
141
142int meson_bo_dmabuf(struct meson_bo *bo)
143{
144 if (!bo->fd) {
145 struct drm_prime_handle req = {
146 .handle = bo->handle,
147 .flags = DRM_CLOEXEC,
148 };
149
150 int ret;
151
152 ret = drmIoctl(bo->dev->fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &req);
153 if (ret)
154 return ret;
155
156 bo->fd = req.fd;
157 }
158
159 return dup(bo->fd);
160}
161
162size_t meson_bo_size(struct meson_bo *bo)
163{
164 return bo->size;
165}