1 // SPDX-License-Identifier: GPL-2.0 OR MIT
2 /**************************************************************************
4 * Copyright 2009-2015 VMware, Inc., Palo Alto, CA., USA
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
26 **************************************************************************/
28 #include "vmwgfx_drv.h"
29 #include <drm/vmwgfx_drm.h>
30 #include "vmwgfx_kms.h"
31 #include "device_include/svga3d_caps.h"
33 struct svga_3d_compat_cap
{
34 SVGA3dCapsRecordHeader header
;
35 SVGA3dCapPair pairs
[SVGA3D_DEVCAP_MAX
];
38 int vmw_getparam_ioctl(struct drm_device
*dev
, void *data
,
39 struct drm_file
*file_priv
)
41 struct vmw_private
*dev_priv
= vmw_priv(dev
);
42 struct drm_vmw_getparam_arg
*param
=
43 (struct drm_vmw_getparam_arg
*)data
;
44 struct vmw_fpriv
*vmw_fp
= vmw_fpriv(file_priv
);
46 switch (param
->param
) {
47 case DRM_VMW_PARAM_NUM_STREAMS
:
48 param
->value
= vmw_overlay_num_overlays(dev_priv
);
50 case DRM_VMW_PARAM_NUM_FREE_STREAMS
:
51 param
->value
= vmw_overlay_num_free_overlays(dev_priv
);
53 case DRM_VMW_PARAM_3D
:
54 param
->value
= vmw_fifo_have_3d(dev_priv
) ? 1 : 0;
56 case DRM_VMW_PARAM_HW_CAPS
:
57 param
->value
= dev_priv
->capabilities
;
59 case DRM_VMW_PARAM_HW_CAPS2
:
60 param
->value
= dev_priv
->capabilities2
;
62 case DRM_VMW_PARAM_FIFO_CAPS
:
63 param
->value
= dev_priv
->fifo
.capabilities
;
65 case DRM_VMW_PARAM_MAX_FB_SIZE
:
66 param
->value
= dev_priv
->prim_bb_mem
;
68 case DRM_VMW_PARAM_FIFO_HW_VERSION
:
70 u32
*fifo_mem
= dev_priv
->mmio_virt
;
71 const struct vmw_fifo_state
*fifo
= &dev_priv
->fifo
;
73 if ((dev_priv
->capabilities
& SVGA_CAP_GBOBJECTS
)) {
74 param
->value
= SVGA3D_HWVERSION_WS8_B1
;
79 vmw_mmio_read(fifo_mem
+
80 ((fifo
->capabilities
&
81 SVGA_FIFO_CAP_3D_HWVERSION_REVISED
) ?
82 SVGA_FIFO_3D_HWVERSION_REVISED
:
83 SVGA_FIFO_3D_HWVERSION
));
86 case DRM_VMW_PARAM_MAX_SURF_MEMORY
:
87 if ((dev_priv
->capabilities
& SVGA_CAP_GBOBJECTS
) &&
89 param
->value
= dev_priv
->max_mob_pages
* PAGE_SIZE
/ 2;
91 param
->value
= dev_priv
->memory_size
;
93 case DRM_VMW_PARAM_3D_CAPS_SIZE
:
94 if ((dev_priv
->capabilities
& SVGA_CAP_GBOBJECTS
) &&
96 param
->value
= SVGA3D_DEVCAP_MAX
* sizeof(uint32_t);
97 else if (dev_priv
->capabilities
& SVGA_CAP_GBOBJECTS
)
98 param
->value
= sizeof(struct svga_3d_compat_cap
) +
101 param
->value
= (SVGA_FIFO_3D_CAPS_LAST
-
102 SVGA_FIFO_3D_CAPS
+ 1) *
105 case DRM_VMW_PARAM_MAX_MOB_MEMORY
:
106 vmw_fp
->gb_aware
= true;
107 param
->value
= dev_priv
->max_mob_pages
* PAGE_SIZE
;
109 case DRM_VMW_PARAM_MAX_MOB_SIZE
:
110 param
->value
= dev_priv
->max_mob_size
;
112 case DRM_VMW_PARAM_SCREEN_TARGET
:
114 (dev_priv
->active_display_unit
== vmw_du_screen_target
);
116 case DRM_VMW_PARAM_DX
:
117 param
->value
= dev_priv
->has_dx
;
119 case DRM_VMW_PARAM_SM4_1
:
120 param
->value
= dev_priv
->has_sm4_1
;
129 static u32
vmw_mask_multisample(unsigned int cap
, u32 fmt_value
)
132 * A version of user-space exists which use MULTISAMPLE_MASKABLESAMPLES
133 * to check the sample count supported by virtual device. Since there
134 * never was support for multisample count for backing MOB return 0.
136 if (cap
== SVGA3D_DEVCAP_MULTISAMPLE_MASKABLESAMPLES
)
142 static int vmw_fill_compat_cap(struct vmw_private
*dev_priv
, void *bounce
,
145 struct svga_3d_compat_cap
*compat_cap
=
146 (struct svga_3d_compat_cap
*) bounce
;
148 size_t pair_offset
= offsetof(struct svga_3d_compat_cap
, pairs
);
149 unsigned int max_size
;
151 if (size
< pair_offset
)
154 max_size
= (size
- pair_offset
) / sizeof(SVGA3dCapPair
);
156 if (max_size
> SVGA3D_DEVCAP_MAX
)
157 max_size
= SVGA3D_DEVCAP_MAX
;
159 compat_cap
->header
.length
=
160 (pair_offset
+ max_size
* sizeof(SVGA3dCapPair
)) / sizeof(u32
);
161 compat_cap
->header
.type
= SVGA3DCAPS_RECORD_DEVCAPS
;
163 spin_lock(&dev_priv
->cap_lock
);
164 for (i
= 0; i
< max_size
; ++i
) {
165 vmw_write(dev_priv
, SVGA_REG_DEV_CAP
, i
);
166 compat_cap
->pairs
[i
][0] = i
;
167 compat_cap
->pairs
[i
][1] = vmw_mask_multisample
168 (i
, vmw_read(dev_priv
, SVGA_REG_DEV_CAP
));
170 spin_unlock(&dev_priv
->cap_lock
);
176 int vmw_get_cap_3d_ioctl(struct drm_device
*dev
, void *data
,
177 struct drm_file
*file_priv
)
179 struct drm_vmw_get_3d_cap_arg
*arg
=
180 (struct drm_vmw_get_3d_cap_arg
*) data
;
181 struct vmw_private
*dev_priv
= vmw_priv(dev
);
184 void __user
*buffer
= (void __user
*)((unsigned long)(arg
->buffer
));
187 bool gb_objects
= !!(dev_priv
->capabilities
& SVGA_CAP_GBOBJECTS
);
188 struct vmw_fpriv
*vmw_fp
= vmw_fpriv(file_priv
);
190 if (unlikely(arg
->pad64
!= 0 || arg
->max_size
== 0)) {
191 VMW_DEBUG_USER("Illegal GET_3D_CAP argument.\n");
195 if (gb_objects
&& vmw_fp
->gb_aware
)
196 size
= SVGA3D_DEVCAP_MAX
* sizeof(uint32_t);
198 size
= sizeof(struct svga_3d_compat_cap
) + sizeof(uint32_t);
200 size
= (SVGA_FIFO_3D_CAPS_LAST
- SVGA_FIFO_3D_CAPS
+ 1) *
203 if (arg
->max_size
< size
)
204 size
= arg
->max_size
;
206 bounce
= vzalloc(size
);
207 if (unlikely(bounce
== NULL
)) {
208 DRM_ERROR("Failed to allocate bounce buffer for 3D caps.\n");
212 if (gb_objects
&& vmw_fp
->gb_aware
) {
214 uint32_t *bounce32
= (uint32_t *) bounce
;
216 num
= size
/ sizeof(uint32_t);
217 if (num
> SVGA3D_DEVCAP_MAX
)
218 num
= SVGA3D_DEVCAP_MAX
;
220 spin_lock(&dev_priv
->cap_lock
);
221 for (i
= 0; i
< num
; ++i
) {
222 vmw_write(dev_priv
, SVGA_REG_DEV_CAP
, i
);
223 *bounce32
++ = vmw_mask_multisample
224 (i
, vmw_read(dev_priv
, SVGA_REG_DEV_CAP
));
226 spin_unlock(&dev_priv
->cap_lock
);
227 } else if (gb_objects
) {
228 ret
= vmw_fill_compat_cap(dev_priv
, bounce
, size
);
229 if (unlikely(ret
!= 0))
232 fifo_mem
= dev_priv
->mmio_virt
;
233 memcpy(bounce
, &fifo_mem
[SVGA_FIFO_3D_CAPS
], size
);
236 ret
= copy_to_user(buffer
, bounce
, size
);
242 if (unlikely(ret
!= 0))
243 DRM_ERROR("Failed to report 3D caps info.\n");
248 int vmw_present_ioctl(struct drm_device
*dev
, void *data
,
249 struct drm_file
*file_priv
)
251 struct ttm_object_file
*tfile
= vmw_fpriv(file_priv
)->tfile
;
252 struct vmw_private
*dev_priv
= vmw_priv(dev
);
253 struct drm_vmw_present_arg
*arg
=
254 (struct drm_vmw_present_arg
*)data
;
255 struct vmw_surface
*surface
;
256 struct drm_vmw_rect __user
*clips_ptr
;
257 struct drm_vmw_rect
*clips
= NULL
;
258 struct drm_framebuffer
*fb
;
259 struct vmw_framebuffer
*vfb
;
260 struct vmw_resource
*res
;
264 num_clips
= arg
->num_clips
;
265 clips_ptr
= (struct drm_vmw_rect __user
*)(unsigned long)arg
->clips_ptr
;
267 if (unlikely(num_clips
== 0))
270 if (clips_ptr
== NULL
) {
271 VMW_DEBUG_USER("Variable clips_ptr must be specified.\n");
276 clips
= kcalloc(num_clips
, sizeof(*clips
), GFP_KERNEL
);
278 DRM_ERROR("Failed to allocate clip rect list.\n");
283 ret
= copy_from_user(clips
, clips_ptr
, num_clips
* sizeof(*clips
));
285 DRM_ERROR("Failed to copy clip rects from userspace.\n");
290 drm_modeset_lock_all(dev
);
292 fb
= drm_framebuffer_lookup(dev
, file_priv
, arg
->fb_id
);
294 VMW_DEBUG_USER("Invalid framebuffer id.\n");
298 vfb
= vmw_framebuffer_to_vfb(fb
);
300 ret
= ttm_read_lock(&dev_priv
->reservation_sem
, true);
301 if (unlikely(ret
!= 0))
302 goto out_no_ttm_lock
;
304 ret
= vmw_user_resource_lookup_handle(dev_priv
, tfile
, arg
->sid
,
305 user_surface_converter
,
310 surface
= vmw_res_to_srf(res
);
311 ret
= vmw_kms_present(dev_priv
, file_priv
,
312 vfb
, surface
, arg
->sid
,
313 arg
->dest_x
, arg
->dest_y
,
316 /* vmw_user_surface_lookup takes one ref so does new_fb */
317 vmw_surface_unreference(&surface
);
320 ttm_read_unlock(&dev_priv
->reservation_sem
);
322 drm_framebuffer_put(fb
);
324 drm_modeset_unlock_all(dev
);
331 int vmw_present_readback_ioctl(struct drm_device
*dev
, void *data
,
332 struct drm_file
*file_priv
)
334 struct vmw_private
*dev_priv
= vmw_priv(dev
);
335 struct drm_vmw_present_readback_arg
*arg
=
336 (struct drm_vmw_present_readback_arg
*)data
;
337 struct drm_vmw_fence_rep __user
*user_fence_rep
=
338 (struct drm_vmw_fence_rep __user
*)
339 (unsigned long)arg
->fence_rep
;
340 struct drm_vmw_rect __user
*clips_ptr
;
341 struct drm_vmw_rect
*clips
= NULL
;
342 struct drm_framebuffer
*fb
;
343 struct vmw_framebuffer
*vfb
;
347 num_clips
= arg
->num_clips
;
348 clips_ptr
= (struct drm_vmw_rect __user
*)(unsigned long)arg
->clips_ptr
;
350 if (unlikely(num_clips
== 0))
353 if (clips_ptr
== NULL
) {
354 VMW_DEBUG_USER("Argument clips_ptr must be specified.\n");
359 clips
= kcalloc(num_clips
, sizeof(*clips
), GFP_KERNEL
);
361 DRM_ERROR("Failed to allocate clip rect list.\n");
366 ret
= copy_from_user(clips
, clips_ptr
, num_clips
* sizeof(*clips
));
368 DRM_ERROR("Failed to copy clip rects from userspace.\n");
373 drm_modeset_lock_all(dev
);
375 fb
= drm_framebuffer_lookup(dev
, file_priv
, arg
->fb_id
);
377 VMW_DEBUG_USER("Invalid framebuffer id.\n");
382 vfb
= vmw_framebuffer_to_vfb(fb
);
384 VMW_DEBUG_USER("Framebuffer not buffer backed.\n");
386 goto out_no_ttm_lock
;
389 ret
= ttm_read_lock(&dev_priv
->reservation_sem
, true);
390 if (unlikely(ret
!= 0))
391 goto out_no_ttm_lock
;
393 ret
= vmw_kms_readback(dev_priv
, file_priv
,
397 ttm_read_unlock(&dev_priv
->reservation_sem
);
399 drm_framebuffer_put(fb
);
401 drm_modeset_unlock_all(dev
);
410 * vmw_fops_poll - wrapper around the drm_poll function
412 * @filp: See the linux fops poll documentation.
413 * @wait: See the linux fops poll documentation.
415 * Wrapper around the drm_poll function that makes sure the device is
416 * processing the fifo if drm_poll decides to wait.
418 __poll_t
vmw_fops_poll(struct file
*filp
, struct poll_table_struct
*wait
)
420 struct drm_file
*file_priv
= filp
->private_data
;
421 struct vmw_private
*dev_priv
=
422 vmw_priv(file_priv
->minor
->dev
);
424 vmw_fifo_ping_host(dev_priv
, SVGA_SYNC_GENERIC
);
425 return drm_poll(filp
, wait
);
430 * vmw_fops_read - wrapper around the drm_read function
432 * @filp: See the linux fops read documentation.
433 * @buffer: See the linux fops read documentation.
434 * @count: See the linux fops read documentation.
435 * offset: See the linux fops read documentation.
437 * Wrapper around the drm_read function that makes sure the device is
438 * processing the fifo if drm_read decides to wait.
440 ssize_t
vmw_fops_read(struct file
*filp
, char __user
*buffer
,
441 size_t count
, loff_t
*offset
)
443 struct drm_file
*file_priv
= filp
->private_data
;
444 struct vmw_private
*dev_priv
=
445 vmw_priv(file_priv
->minor
->dev
);
447 vmw_fifo_ping_host(dev_priv
, SVGA_SYNC_GENERIC
);
448 return drm_read(filp
, buffer
, count
, offset
);