2 * Copyright © 2019 Google LLC
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
27 #include <sys/ioctl.h>
28 #include "drm-uapi/msm_drm.h"
29 #include "drm-shim/drm_shim.h"
36 static struct msm_bo
*
37 msm_bo(struct shim_bo
*bo
)
39 return (struct msm_bo
*)bo
;
46 static struct msm_device msm
= {
47 .next_offset
= 0x1000,
50 struct msm_device_info
{
56 static const struct msm_device_info
*device_info
;
59 msm_ioctl_noop(int fd
, unsigned long request
, void *arg
)
65 msm_ioctl_gem_new(int fd
, unsigned long request
, void *arg
)
67 struct shim_fd
*shim_fd
= drm_shim_fd_lookup(fd
);
68 struct drm_msm_gem_new
*create
= arg
;
69 struct msm_bo
*bo
= calloc(1, sizeof(*bo
));
71 drm_shim_bo_init(&bo
->base
, create
->size
);
73 assert(UINT_MAX
- msm
.next_offset
> create
->size
);
75 bo
->offset
= msm
.next_offset
;
76 msm
.next_offset
+= create
->size
;
78 create
->handle
= drm_shim_bo_get_handle(shim_fd
, &bo
->base
);
80 drm_shim_bo_put(&bo
->base
);
86 msm_ioctl_gem_info(int fd
, unsigned long request
, void *arg
)
88 struct shim_fd
*shim_fd
= drm_shim_fd_lookup(fd
);
89 struct drm_msm_gem_info
*args
= arg
;
90 struct shim_bo
*bo
= drm_shim_bo_lookup(shim_fd
, args
->handle
);
93 case MSM_INFO_GET_OFFSET
:
94 args
->value
= drm_shim_bo_get_mmap_offset(shim_fd
, bo
);
96 case MSM_INFO_GET_IOVA
:
97 args
->value
= msm_bo(bo
)->offset
;
99 case MSM_INFO_SET_NAME
:
102 fprintf(stderr
, "Unknown DRM_IOCTL_MSM_GEM_INFO %d\n", args
->info
);
113 msm_ioctl_get_param(int fd
, unsigned long request
, void *arg
)
115 struct drm_msm_param
*gp
= arg
;
118 case MSM_PARAM_GPU_ID
:
119 gp
->value
= device_info
->gpu_id
;
121 case MSM_PARAM_GMEM_SIZE
:
122 gp
->value
= device_info
->gmem_size
;
124 case MSM_PARAM_GMEM_BASE
:
125 gp
->value
= 0x100000;
127 case MSM_PARAM_CHIP_ID
:
128 gp
->value
= device_info
->chip_id
;
130 case MSM_PARAM_NR_RINGS
:
133 case MSM_PARAM_MAX_FREQ
:
136 case MSM_PARAM_TIMESTAMP
:
139 case MSM_PARAM_PP_PGTABLE
:
142 case MSM_PARAM_FAULTS
:
146 fprintf(stderr
, "Unknown DRM_IOCTL_MSM_GET_PARAM %d\n",
153 msm_ioctl_gem_madvise(int fd
, unsigned long request
, void *arg
)
155 struct drm_msm_gem_madvise
*args
= arg
;
157 args
->retained
= true;
162 static ioctl_fn_t driver_ioctls
[] = {
163 [DRM_MSM_GET_PARAM
] = msm_ioctl_get_param
,
164 [DRM_MSM_GEM_NEW
] = msm_ioctl_gem_new
,
165 [DRM_MSM_GEM_INFO
] = msm_ioctl_gem_info
,
166 [DRM_MSM_GEM_CPU_PREP
] = msm_ioctl_noop
,
167 [DRM_MSM_GEM_CPU_FINI
] = msm_ioctl_noop
,
168 [DRM_MSM_GEM_SUBMIT
] = msm_ioctl_noop
,
169 [DRM_MSM_WAIT_FENCE
] = msm_ioctl_noop
,
170 [DRM_MSM_GEM_MADVISE
] = msm_ioctl_gem_madvise
,
171 [DRM_MSM_SUBMITQUEUE_NEW
] = msm_ioctl_noop
,
172 [DRM_MSM_SUBMITQUEUE_CLOSE
] = msm_ioctl_noop
,
173 [DRM_MSM_SUBMITQUEUE_QUERY
] = msm_ioctl_noop
,
176 #define CHIPID(maj, min, rev, pat) \
177 ((maj << 24) | (min << 16) | (rev << 8) | (pat))
179 static const struct msm_device_info device_infos
[] = {
180 { /* First entry is default */
182 .chip_id
= CHIPID(6, 3, 0, 0xff),
183 .gmem_size
= 1024 * 1024,
187 .chip_id
= CHIPID(2, 0, 0, 0),
188 .gmem_size
= 256 * 1024,
192 .chip_id
= CHIPID(2, 0, 0, 1),
193 .gmem_size
= 128 * 1024,
197 .chip_id
= CHIPID(2, 2, 0, 0xff),
198 .gmem_size
= 512 * 1024,
202 .chip_id
= CHIPID(3, 0, 5, 0xff),
203 .gmem_size
= 256 * 1024,
207 .chip_id
= CHIPID(3, 0, 6, 0),
208 .gmem_size
= 128 * 1024,
212 .chip_id
= CHIPID(3, 2, 0xff, 0xff),
213 .gmem_size
= 512 * 1024,
217 .chip_id
= CHIPID(3, 3, 0, 0xff),
218 .gmem_size
= 1024 * 1024,
222 .chip_id
= CHIPID(4, 2, 0, 0xff),
223 .gmem_size
= 1536 * 1024,
227 .chip_id
= CHIPID(4, 3, 0, 0xff),
228 .gmem_size
= 1536 * 1024,
232 .chip_id
= CHIPID(5, 1, 0, 0xff),
233 .gmem_size
= 256 * 1024,
237 .chip_id
= CHIPID(5, 3, 0, 2),
238 .gmem_size
= 1024 * 1024,
242 .chip_id
= CHIPID(5, 4, 0, 2),
243 .gmem_size
= 1024 * 1024,
247 .chip_id
= CHIPID(6, 1, 8, 0xff),
248 .gmem_size
= 512 * 1024,
252 .chip_id
= CHIPID(6, 3, 0, 0xff),
253 .gmem_size
= 1024 * 1024,
259 msm_driver_get_device_info(void)
261 const char *env
= getenv("FD_GPU_ID");
264 device_info
= &device_infos
[0];
268 int gpu_id
= atoi(env
);
269 for (int i
= 0; i
< ARRAY_SIZE(device_infos
); i
++) {
270 if (device_infos
[i
].gpu_id
== gpu_id
) {
271 device_info
= &device_infos
[i
];
276 fprintf(stderr
, "FD_GPU_ID unrecognized, shim supports %d",
277 device_infos
[0].gpu_id
);
278 for (int i
= 1; i
< ARRAY_SIZE(device_infos
); i
++)
279 fprintf(stderr
, ", %d", device_infos
[i
].gpu_id
);
280 fprintf(stderr
, "\n");
285 drm_shim_driver_init(void)
287 shim_device
.bus_type
= DRM_BUS_PLATFORM
;
288 shim_device
.driver_name
= "msm";
289 shim_device
.driver_ioctls
= driver_ioctls
;
290 shim_device
.driver_ioctl_count
= ARRAY_SIZE(driver_ioctls
);
292 /* msm uses the DRM version to expose features, instead of getparam. */
293 shim_device
.version_major
= 1;
294 shim_device
.version_minor
= 5;
295 shim_device
.version_patchlevel
= 0;
297 msm_driver_get_device_info();
299 drm_shim_override_file("OF_FULLNAME=/rdb/msm\n"
300 "OF_COMPATIBLE_N=1\n"
301 "OF_COMPATIBLE_0=qcom,adreno\n",
302 "/sys/dev/char/%d:%d/device/uevent",
303 DRM_MAJOR
, render_node_minor
);