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"
31 bool drm_shim_driver_prefers_first_render_node
= true;
38 static struct msm_bo
*
39 msm_bo(struct shim_bo
*bo
)
41 return (struct msm_bo
*)bo
;
48 static struct msm_device msm
= {
49 .next_offset
= 0x1000,
52 struct msm_device_info
{
58 static const struct msm_device_info
*device_info
;
61 msm_ioctl_noop(int fd
, unsigned long request
, void *arg
)
67 msm_ioctl_gem_new(int fd
, unsigned long request
, void *arg
)
69 struct shim_fd
*shim_fd
= drm_shim_fd_lookup(fd
);
70 struct drm_msm_gem_new
*create
= arg
;
71 struct msm_bo
*bo
= calloc(1, sizeof(*bo
));
73 drm_shim_bo_init(&bo
->base
, create
->size
);
75 assert(UINT_MAX
- msm
.next_offset
> create
->size
);
77 bo
->offset
= msm
.next_offset
;
78 msm
.next_offset
+= create
->size
;
80 create
->handle
= drm_shim_bo_get_handle(shim_fd
, &bo
->base
);
82 drm_shim_bo_put(&bo
->base
);
88 msm_ioctl_gem_info(int fd
, unsigned long request
, void *arg
)
90 struct shim_fd
*shim_fd
= drm_shim_fd_lookup(fd
);
91 struct drm_msm_gem_info
*args
= arg
;
92 struct shim_bo
*bo
= drm_shim_bo_lookup(shim_fd
, args
->handle
);
95 case MSM_INFO_GET_OFFSET
:
96 args
->value
= drm_shim_bo_get_mmap_offset(shim_fd
, bo
);
98 case MSM_INFO_GET_IOVA
:
99 args
->value
= msm_bo(bo
)->offset
;
101 case MSM_INFO_SET_NAME
:
104 fprintf(stderr
, "Unknown DRM_IOCTL_MSM_GEM_INFO %d\n", args
->info
);
115 msm_ioctl_get_param(int fd
, unsigned long request
, void *arg
)
117 struct drm_msm_param
*gp
= arg
;
120 case MSM_PARAM_GPU_ID
:
121 gp
->value
= device_info
->gpu_id
;
123 case MSM_PARAM_GMEM_SIZE
:
124 gp
->value
= device_info
->gmem_size
;
126 case MSM_PARAM_GMEM_BASE
:
127 gp
->value
= 0x100000;
129 case MSM_PARAM_CHIP_ID
:
130 gp
->value
= device_info
->chip_id
;
132 case MSM_PARAM_NR_RINGS
:
135 case MSM_PARAM_MAX_FREQ
:
138 case MSM_PARAM_TIMESTAMP
:
141 case MSM_PARAM_PP_PGTABLE
:
144 case MSM_PARAM_FAULTS
:
148 fprintf(stderr
, "Unknown DRM_IOCTL_MSM_GET_PARAM %d\n",
155 msm_ioctl_gem_madvise(int fd
, unsigned long request
, void *arg
)
157 struct drm_msm_gem_madvise
*args
= arg
;
159 args
->retained
= true;
164 static ioctl_fn_t driver_ioctls
[] = {
165 [DRM_MSM_GET_PARAM
] = msm_ioctl_get_param
,
166 [DRM_MSM_GEM_NEW
] = msm_ioctl_gem_new
,
167 [DRM_MSM_GEM_INFO
] = msm_ioctl_gem_info
,
168 [DRM_MSM_GEM_CPU_PREP
] = msm_ioctl_noop
,
169 [DRM_MSM_GEM_CPU_FINI
] = msm_ioctl_noop
,
170 [DRM_MSM_GEM_SUBMIT
] = msm_ioctl_noop
,
171 [DRM_MSM_WAIT_FENCE
] = msm_ioctl_noop
,
172 [DRM_MSM_GEM_MADVISE
] = msm_ioctl_gem_madvise
,
173 [DRM_MSM_SUBMITQUEUE_NEW
] = msm_ioctl_noop
,
174 [DRM_MSM_SUBMITQUEUE_CLOSE
] = msm_ioctl_noop
,
175 [DRM_MSM_SUBMITQUEUE_QUERY
] = msm_ioctl_noop
,
178 #define CHIPID(maj, min, rev, pat) \
179 ((maj << 24) | (min << 16) | (rev << 8) | (pat))
181 static const struct msm_device_info device_infos
[] = {
182 { /* First entry is default */
184 .chip_id
= CHIPID(6, 3, 0, 0xff),
185 .gmem_size
= 1024 * 1024,
189 .chip_id
= CHIPID(2, 0, 0, 0),
190 .gmem_size
= 256 * 1024,
194 .chip_id
= CHIPID(2, 0, 0, 1),
195 .gmem_size
= 128 * 1024,
199 .chip_id
= CHIPID(2, 2, 0, 0xff),
200 .gmem_size
= 512 * 1024,
204 .chip_id
= CHIPID(3, 0, 5, 0xff),
205 .gmem_size
= 256 * 1024,
209 .chip_id
= CHIPID(3, 0, 6, 0),
210 .gmem_size
= 128 * 1024,
214 .chip_id
= CHIPID(3, 2, 0xff, 0xff),
215 .gmem_size
= 512 * 1024,
219 .chip_id
= CHIPID(3, 3, 0, 0xff),
220 .gmem_size
= 1024 * 1024,
224 .chip_id
= CHIPID(4, 2, 0, 0xff),
225 .gmem_size
= 1536 * 1024,
229 .chip_id
= CHIPID(4, 3, 0, 0xff),
230 .gmem_size
= 1536 * 1024,
234 .chip_id
= CHIPID(5, 1, 0, 0xff),
235 .gmem_size
= 256 * 1024,
239 .chip_id
= CHIPID(5, 3, 0, 2),
240 .gmem_size
= 1024 * 1024,
244 .chip_id
= CHIPID(5, 4, 0, 2),
245 .gmem_size
= 1024 * 1024,
249 .chip_id
= CHIPID(6, 1, 8, 0xff),
250 .gmem_size
= 512 * 1024,
254 .chip_id
= CHIPID(6, 3, 0, 0xff),
255 .gmem_size
= 1024 * 1024,
261 msm_driver_get_device_info(void)
263 const char *env
= getenv("FD_GPU_ID");
266 device_info
= &device_infos
[0];
270 int gpu_id
= atoi(env
);
271 for (int i
= 0; i
< ARRAY_SIZE(device_infos
); i
++) {
272 if (device_infos
[i
].gpu_id
== gpu_id
) {
273 device_info
= &device_infos
[i
];
278 fprintf(stderr
, "FD_GPU_ID unrecognized, shim supports %d",
279 device_infos
[0].gpu_id
);
280 for (int i
= 1; i
< ARRAY_SIZE(device_infos
); i
++)
281 fprintf(stderr
, ", %d", device_infos
[i
].gpu_id
);
282 fprintf(stderr
, "\n");
287 drm_shim_driver_init(void)
289 shim_device
.bus_type
= DRM_BUS_PLATFORM
;
290 shim_device
.driver_name
= "msm";
291 shim_device
.driver_ioctls
= driver_ioctls
;
292 shim_device
.driver_ioctl_count
= ARRAY_SIZE(driver_ioctls
);
294 /* msm uses the DRM version to expose features, instead of getparam. */
295 shim_device
.version_major
= 1;
296 shim_device
.version_minor
= 5;
297 shim_device
.version_patchlevel
= 0;
299 msm_driver_get_device_info();
301 drm_shim_override_file("OF_FULLNAME=/rdb/msm\n"
302 "OF_COMPATIBLE_N=1\n"
303 "OF_COMPATIBLE_0=qcom,adreno\n",
304 "/sys/dev/char/%d:%d/device/uevent",
305 DRM_MAJOR
, render_node_minor
);