• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2012, 2013 Thierry Reding
3  * Copyright © 2013 Erik Faye-Lund
4  * Copyright © 2014-2021 NVIDIA Corporation
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a
7  * copy of this software and associated documentation files (the "Software"),
8  * to deal in the Software without restriction, including without limitation
9  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10  * and/or sell copies of the Software, and to permit persons to whom the
11  * Software is furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
19  * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22  * OTHER DEALINGS IN THE SOFTWARE.
23  */
24 
25 #ifdef HAVE_CONFIG_H
26 #  include "config.h"
27 #endif
28 
29 #include <errno.h>
30 #include <string.h>
31 
32 #include <sys/ioctl.h>
33 
34 #include "private.h"
35 
36 drm_public int
drm_tegra_channel_open(struct drm_tegra * drm,enum drm_tegra_class client,struct drm_tegra_channel ** channelp)37 drm_tegra_channel_open(struct drm_tegra *drm,
38                        enum drm_tegra_class client,
39                        struct drm_tegra_channel **channelp)
40 {
41     struct drm_tegra_channel_open args;
42     struct drm_tegra_channel *channel;
43     enum host1x_class class;
44     int err;
45 
46     switch (client) {
47     case DRM_TEGRA_HOST1X:
48         class = HOST1X_CLASS_HOST1X;
49         break;
50 
51     case DRM_TEGRA_GR2D:
52         class = HOST1X_CLASS_GR2D;
53         break;
54 
55     case DRM_TEGRA_GR3D:
56         class = HOST1X_CLASS_GR3D;
57         break;
58 
59     case DRM_TEGRA_VIC:
60         class = HOST1X_CLASS_VIC;
61         break;
62 
63     default:
64         return -EINVAL;
65     }
66 
67     channel = calloc(1, sizeof(*channel));
68     if (!channel)
69         return -ENOMEM;
70 
71     channel->drm = drm;
72 
73     memset(&args, 0, sizeof(args));
74     args.host1x_class = class;
75 
76     err = ioctl(drm->fd, DRM_IOCTL_TEGRA_CHANNEL_OPEN, &args);
77     if (err < 0) {
78         free(channel);
79         return -errno;
80     }
81 
82     channel->context = args.context;
83     channel->version = args.version;
84     channel->capabilities = args.capabilities;
85     channel->class = class;
86 
87     switch (channel->version) {
88     case 0x20:
89     case 0x30:
90     case 0x35:
91     case 0x40:
92     case 0x21:
93         channel->cond_shift = 8;
94         break;
95 
96     case 0x18:
97     case 0x19:
98         channel->cond_shift = 10;
99         break;
100 
101     default:
102         return -ENOTSUP;
103     }
104 
105     *channelp = channel;
106 
107     return 0;
108 }
109 
drm_tegra_channel_close(struct drm_tegra_channel * channel)110 drm_public int drm_tegra_channel_close(struct drm_tegra_channel *channel)
111 {
112     struct drm_tegra_channel_close args;
113     struct drm_tegra *drm;
114     int err;
115 
116     if (!channel)
117         return -EINVAL;
118 
119     drm = channel->drm;
120 
121     memset(&args, 0, sizeof(args));
122     args.context = channel->context;
123 
124     err = ioctl(drm->fd, DRM_IOCTL_TEGRA_CHANNEL_CLOSE, &args);
125     if (err < 0)
126         return -errno;
127 
128     free(channel);
129 
130     return 0;
131 }
132 
133 drm_public unsigned int
drm_tegra_channel_get_version(struct drm_tegra_channel * channel)134 drm_tegra_channel_get_version(struct drm_tegra_channel *channel)
135 {
136     return channel->version;
137 }
138 
139 drm_public int
drm_tegra_channel_map(struct drm_tegra_channel * channel,struct drm_tegra_bo * bo,uint32_t flags,struct drm_tegra_mapping ** mapp)140 drm_tegra_channel_map(struct drm_tegra_channel *channel,
141                       struct drm_tegra_bo *bo, uint32_t flags,
142                       struct drm_tegra_mapping **mapp)
143 {
144     struct drm_tegra *drm = channel->drm;
145     struct drm_tegra_channel_map args;
146     struct drm_tegra_mapping *map;
147     int err;
148 
149     if (!drm || !bo || !mapp)
150         return -EINVAL;
151 
152     map = calloc(1, sizeof(*map));
153     if (!map)
154         return -ENOMEM;
155 
156     memset(&args, 0, sizeof(args));
157     args.context = channel->context;
158     args.handle = bo->handle;
159     args.flags = flags;
160 
161     err = ioctl(drm->fd, DRM_IOCTL_TEGRA_CHANNEL_MAP, &args);
162     if (err < 0) {
163         free(map);
164         return -errno;
165     }
166 
167     map->channel = channel;
168     map->id = args.mapping;
169     *mapp = map;
170 
171     return 0;
172 }
173 
174 drm_public int
drm_tegra_channel_unmap(struct drm_tegra_mapping * map)175 drm_tegra_channel_unmap(struct drm_tegra_mapping *map)
176 {
177     struct drm_tegra_channel *channel = map->channel;
178     struct drm_tegra *drm = channel->drm;
179     struct drm_tegra_channel_unmap args;
180     int err;
181 
182     if (!channel || !map)
183         return -EINVAL;
184 
185     memset(&args, 0, sizeof(args));
186     args.context = channel->context;
187     args.mapping = map->id;
188 
189     err = ioctl(drm->fd, DRM_IOCTL_TEGRA_CHANNEL_UNMAP, &args);
190     if (err < 0)
191         return -errno;
192 
193     free(map);
194     return 0;
195 }
196