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