Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

drm/vmwgfx: Implement virtual kms

By default vmwgfx doesn't support vblanking or crc generation which
makes it impossible to use various IGT tests to validate vmwgfx.
Implement virtual kernel mode setting, which is mainly related to
simulated vblank support.

Code is very similar to amd's vkms and the vkms module itself, except
that it's integrated with vmwgfx three different output technologies -
legacy, screen object and screen targets.

Make IGT's kms_vblank pass on vmwgfx and allows a lot of other IGT
tests to run with vmwgfx.

Support for vkms needs to be manually enabled by adding:
guestinfo.vmwgfx.vkms_enable = "TRUE"
somewhere in the vmx file, otherwise it's off by default.

Signed-off-by: Zack Rusin <zack.rusin@broadcom.com>
Acked-by: Martin Krastev <martin.krastev@broadcom.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20240412025511.78553-2-zack.rusin@broadcom.com

+302 -64
+1 -1
drivers/gpu/drm/vmwgfx/Makefile
··· 10 10 vmwgfx_simple_resource.o vmwgfx_va.o vmwgfx_blit.o \ 11 11 vmwgfx_validation.o vmwgfx_page_dirty.o vmwgfx_streamoutput.o \ 12 12 vmwgfx_devcaps.o ttm_object.o vmwgfx_system_manager.o \ 13 - vmwgfx_gem.o 13 + vmwgfx_gem.o vmwgfx_vkms.o 14 14 15 15 obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o
+3
drivers/gpu/drm/vmwgfx/vmwgfx_drv.c
··· 32 32 #include "vmwgfx_binding.h" 33 33 #include "vmwgfx_devcaps.h" 34 34 #include "vmwgfx_mksstat.h" 35 + #include "vmwgfx_vkms.h" 35 36 #include "ttm_object.h" 36 37 37 38 #include <drm/drm_aperture.h> ··· 910 909 drm_err_once(&dev_priv->drm, 911 910 "Please switch to a supported graphics device to avoid problems."); 912 911 } 912 + 913 + vmw_vkms_init(dev_priv); 913 914 914 915 ret = vmw_dma_select_mode(dev_priv); 915 916 if (unlikely(ret != 0)) {
+2
drivers/gpu/drm/vmwgfx/vmwgfx_drv.h
··· 615 615 616 616 uint32 *devcaps; 617 617 618 + bool vkms_enabled; 619 + 618 620 /* 619 621 * mksGuestStat instance-descriptor and pid arrays 620 622 */
+8 -7
drivers/gpu/drm/vmwgfx/vmwgfx_kms.c
··· 27 27 #include "vmwgfx_kms.h" 28 28 29 29 #include "vmwgfx_bo.h" 30 + #include "vmwgfx_vkms.h" 30 31 #include "vmw_surface_cache.h" 31 32 32 33 #include <drm/drm_atomic.h> ··· 38 37 #include <drm/drm_sysfs.h> 39 38 #include <drm/drm_edid.h> 40 39 40 + void vmw_du_init(struct vmw_display_unit *du) 41 + { 42 + hrtimer_init(&du->vkms.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); 43 + du->vkms.timer.function = &vmw_vkms_vblank_simulate; 44 + } 45 + 41 46 void vmw_du_cleanup(struct vmw_display_unit *du) 42 47 { 43 48 struct vmw_private *dev_priv = vmw_priv(du->primary.dev); 49 + hrtimer_cancel(&du->vkms.timer); 44 50 drm_plane_cleanup(&du->primary); 45 51 if (vmw_cmd_supported(dev_priv)) 46 52 drm_plane_cleanup(&du->cursor.base); ··· 964 956 struct drm_atomic_state *state) 965 957 { 966 958 } 967 - 968 - 969 - void vmw_du_crtc_atomic_flush(struct drm_crtc *crtc, 970 - struct drm_atomic_state *state) 971 - { 972 - } 973 - 974 959 975 960 /** 976 961 * vmw_du_crtc_duplicate_state - duplicate crtc state
+7 -2
drivers/gpu/drm/vmwgfx/vmwgfx_kms.h
··· 376 376 bool is_implicit; 377 377 int set_gui_x; 378 378 int set_gui_y; 379 + 380 + struct { 381 + struct hrtimer timer; 382 + ktime_t period_ns; 383 + struct drm_pending_vblank_event *event; 384 + } vkms; 379 385 }; 380 386 381 387 #define vmw_crtc_to_du(x) \ ··· 393 387 /* 394 388 * Shared display unit functions - vmwgfx_kms.c 395 389 */ 390 + void vmw_du_init(struct vmw_display_unit *du); 396 391 void vmw_du_cleanup(struct vmw_display_unit *du); 397 392 void vmw_du_crtc_save(struct drm_crtc *crtc); 398 393 void vmw_du_crtc_restore(struct drm_crtc *crtc); ··· 479 472 int vmw_du_crtc_atomic_check(struct drm_crtc *crtc, 480 473 struct drm_atomic_state *state); 481 474 void vmw_du_crtc_atomic_begin(struct drm_crtc *crtc, 482 - struct drm_atomic_state *state); 483 - void vmw_du_crtc_atomic_flush(struct drm_crtc *crtc, 484 475 struct drm_atomic_state *state); 485 476 void vmw_du_crtc_reset(struct drm_crtc *crtc); 486 477 struct drm_crtc_state *vmw_du_crtc_duplicate_state(struct drm_crtc *crtc);
+9 -30
drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c
··· 27 27 28 28 #include "vmwgfx_bo.h" 29 29 #include "vmwgfx_kms.h" 30 + #include "vmwgfx_vkms.h" 30 31 31 32 #include <drm/drm_atomic.h> 32 33 #include <drm/drm_atomic_helper.h> ··· 242 241 { 243 242 } 244 243 245 - /** 246 - * vmw_ldu_crtc_atomic_enable - Noop 247 - * 248 - * @crtc: CRTC associated with the new screen 249 - * @state: Unused 250 - * 251 - * This is called after a mode set has been completed. Here's 252 - * usually a good place to call vmw_ldu_add_active/vmw_ldu_del_active 253 - * but since for LDU the display plane is closely tied to the 254 - * CRTC, it makes more sense to do those at plane update time. 255 - */ 256 - static void vmw_ldu_crtc_atomic_enable(struct drm_crtc *crtc, 257 - struct drm_atomic_state *state) 258 - { 259 - } 260 - 261 - /** 262 - * vmw_ldu_crtc_atomic_disable - Turns off CRTC 263 - * 264 - * @crtc: CRTC to be turned off 265 - * @state: Unused 266 - */ 267 - static void vmw_ldu_crtc_atomic_disable(struct drm_crtc *crtc, 268 - struct drm_atomic_state *state) 269 - { 270 - } 271 - 272 244 static const struct drm_crtc_funcs vmw_legacy_crtc_funcs = { 273 245 .gamma_set = vmw_du_crtc_gamma_set, 274 246 .destroy = vmw_ldu_crtc_destroy, ··· 250 276 .atomic_destroy_state = vmw_du_crtc_destroy_state, 251 277 .set_config = drm_atomic_helper_set_config, 252 278 .page_flip = drm_atomic_helper_page_flip, 279 + .enable_vblank = vmw_vkms_enable_vblank, 280 + .disable_vblank = vmw_vkms_disable_vblank, 281 + .get_vblank_timestamp = vmw_vkms_get_vblank_timestamp, 253 282 }; 254 283 255 284 ··· 395 418 .mode_set_nofb = vmw_ldu_crtc_mode_set_nofb, 396 419 .atomic_check = vmw_du_crtc_atomic_check, 397 420 .atomic_begin = vmw_du_crtc_atomic_begin, 398 - .atomic_flush = vmw_du_crtc_atomic_flush, 399 - .atomic_enable = vmw_ldu_crtc_atomic_enable, 400 - .atomic_disable = vmw_ldu_crtc_atomic_disable, 421 + .atomic_flush = vmw_vkms_crtc_atomic_flush, 422 + .atomic_enable = vmw_vkms_crtc_atomic_enable, 423 + .atomic_disable = vmw_vkms_crtc_atomic_disable, 401 424 }; 402 425 403 426 ··· 517 540 (&connector->base, 518 541 dev_priv->implicit_placement_property, 519 542 1); 543 + 544 + vmw_du_init(&ldu->base); 520 545 521 546 return 0; 522 547
+13 -15
drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c
··· 27 27 28 28 #include "vmwgfx_bo.h" 29 29 #include "vmwgfx_kms.h" 30 + #include "vmwgfx_vkms.h" 30 31 31 32 #include <drm/drm_atomic.h> 32 33 #include <drm/drm_atomic_helper.h> 33 34 #include <drm/drm_damage_helper.h> 34 35 #include <drm/drm_fourcc.h> 36 + #include <drm/drm_vblank.h> 35 37 36 38 #define vmw_crtc_to_sou(x) \ 37 39 container_of(x, struct vmw_screen_object_unit, base.crtc) ··· 270 268 } 271 269 272 270 /** 273 - * vmw_sou_crtc_atomic_enable - Noop 274 - * 275 - * @crtc: CRTC associated with the new screen 276 - * @state: Unused 277 - * 278 - * This is called after a mode set has been completed. 279 - */ 280 - static void vmw_sou_crtc_atomic_enable(struct drm_crtc *crtc, 281 - struct drm_atomic_state *state) 282 - { 283 - } 284 - 285 - /** 286 271 * vmw_sou_crtc_atomic_disable - Turns off CRTC 287 272 * 288 273 * @crtc: CRTC to be turned off ··· 291 302 sou = vmw_crtc_to_sou(crtc); 292 303 dev_priv = vmw_priv(crtc->dev); 293 304 305 + if (dev_priv->vkms_enabled) 306 + drm_crtc_vblank_off(crtc); 307 + 294 308 if (sou->defined) { 295 309 ret = vmw_sou_fifo_destroy(dev_priv, sou); 296 310 if (ret) ··· 309 317 .atomic_destroy_state = vmw_du_crtc_destroy_state, 310 318 .set_config = drm_atomic_helper_set_config, 311 319 .page_flip = drm_atomic_helper_page_flip, 320 + .enable_vblank = vmw_vkms_enable_vblank, 321 + .disable_vblank = vmw_vkms_disable_vblank, 322 + .get_vblank_timestamp = vmw_vkms_get_vblank_timestamp, 312 323 }; 313 324 314 325 /* ··· 789 794 .mode_set_nofb = vmw_sou_crtc_mode_set_nofb, 790 795 .atomic_check = vmw_du_crtc_atomic_check, 791 796 .atomic_begin = vmw_du_crtc_atomic_begin, 792 - .atomic_flush = vmw_du_crtc_atomic_flush, 793 - .atomic_enable = vmw_sou_crtc_atomic_enable, 797 + .atomic_flush = vmw_vkms_crtc_atomic_flush, 798 + .atomic_enable = vmw_vkms_crtc_atomic_enable, 794 799 .atomic_disable = vmw_sou_crtc_atomic_disable, 795 800 }; 796 801 ··· 900 905 dev->mode_config.suggested_x_property, 0); 901 906 drm_object_attach_property(&connector->base, 902 907 dev->mode_config.suggested_y_property, 0); 908 + 909 + vmw_du_init(&sou->base); 910 + 903 911 return 0; 904 912 905 913 err_free_unregister:
+13 -9
drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c
··· 27 27 28 28 #include "vmwgfx_bo.h" 29 29 #include "vmwgfx_kms.h" 30 + #include "vmwgfx_vkms.h" 30 31 #include "vmw_surface_cache.h" 31 32 32 33 #include <drm/drm_atomic.h> 33 34 #include <drm/drm_atomic_helper.h> 34 35 #include <drm/drm_damage_helper.h> 35 36 #include <drm/drm_fourcc.h> 37 + #include <drm/drm_vblank.h> 36 38 37 39 #define vmw_crtc_to_stdu(x) \ 38 40 container_of(x, struct vmw_screen_target_display_unit, base.crtc) ··· 414 412 { 415 413 } 416 414 417 - static void vmw_stdu_crtc_atomic_enable(struct drm_crtc *crtc, 418 - struct drm_atomic_state *state) 419 - { 420 - } 421 - 422 415 static void vmw_stdu_crtc_atomic_disable(struct drm_crtc *crtc, 423 416 struct drm_atomic_state *state) 424 417 { 425 418 struct vmw_private *dev_priv; 426 419 struct vmw_screen_target_display_unit *stdu; 427 420 int ret; 428 - 429 421 430 422 if (!crtc) { 431 423 DRM_ERROR("CRTC is NULL\n"); ··· 428 432 429 433 stdu = vmw_crtc_to_stdu(crtc); 430 434 dev_priv = vmw_priv(crtc->dev); 435 + 436 + if (dev_priv->vkms_enabled) 437 + drm_crtc_vblank_off(crtc); 431 438 432 439 if (stdu->defined) { 433 440 ret = vmw_stdu_bind_st(dev_priv, stdu, NULL); ··· 769 770 return ret; 770 771 } 771 772 772 - 773 773 /* 774 774 * Screen Target CRTC dispatch table 775 775 */ ··· 780 782 .atomic_destroy_state = vmw_du_crtc_destroy_state, 781 783 .set_config = drm_atomic_helper_set_config, 782 784 .page_flip = drm_atomic_helper_page_flip, 785 + .enable_vblank = vmw_vkms_enable_vblank, 786 + .disable_vblank = vmw_vkms_disable_vblank, 787 + .get_vblank_timestamp = vmw_vkms_get_vblank_timestamp, 783 788 }; 784 789 785 790 ··· 1458 1457 .mode_set_nofb = vmw_stdu_crtc_mode_set_nofb, 1459 1458 .atomic_check = vmw_du_crtc_atomic_check, 1460 1459 .atomic_begin = vmw_du_crtc_atomic_begin, 1461 - .atomic_flush = vmw_du_crtc_atomic_flush, 1462 - .atomic_enable = vmw_stdu_crtc_atomic_enable, 1460 + .atomic_flush = vmw_vkms_crtc_atomic_flush, 1461 + .atomic_enable = vmw_vkms_crtc_atomic_enable, 1463 1462 .atomic_disable = vmw_stdu_crtc_atomic_disable, 1464 1463 }; 1465 1464 ··· 1576 1575 dev->mode_config.suggested_x_property, 0); 1577 1576 drm_object_attach_property(&connector->base, 1578 1577 dev->mode_config.suggested_y_property, 0); 1578 + 1579 + vmw_du_init(&stdu->base); 1580 + 1579 1581 return 0; 1580 1582 1581 1583 err_free_unregister:
+193
drivers/gpu/drm/vmwgfx/vmwgfx_vkms.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 OR MIT 2 + /************************************************************************** 3 + * 4 + * Copyright (c) 2024 Broadcom. All Rights Reserved. The term 5 + * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 6 + * 7 + * Permission is hereby granted, free of charge, to any person obtaining a 8 + * copy of this software and associated documentation files (the 9 + * "Software"), to deal in the Software without restriction, including 10 + * without limitation the rights to use, copy, modify, merge, publish, 11 + * distribute, sub license, and/or sell copies of the Software, and to 12 + * permit persons to whom the Software is furnished to do so, subject to 13 + * the following conditions: 14 + * 15 + * The above copyright notice and this permission notice (including the 16 + * next paragraph) shall be included in all copies or substantial portions 17 + * of the Software. 18 + * 19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 22 + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 23 + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 24 + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 25 + * USE OR OTHER DEALINGS IN THE SOFTWARE. 26 + * 27 + **************************************************************************/ 28 + 29 + #include "vmwgfx_vkms.h" 30 + 31 + #include "vmwgfx_drv.h" 32 + #include "vmwgfx_kms.h" 33 + #include "vmwgfx_vkms.h" 34 + 35 + #include <drm/drm_crtc.h> 36 + #include <drm/drm_print.h> 37 + #include <drm/drm_vblank.h> 38 + 39 + #define GUESTINFO_VBLANK "guestinfo.vmwgfx.vkms_enable" 40 + 41 + enum hrtimer_restart 42 + vmw_vkms_vblank_simulate(struct hrtimer *timer) 43 + { 44 + struct vmw_display_unit *du = container_of(timer, struct vmw_display_unit, vkms.timer); 45 + struct drm_crtc *crtc = &du->crtc; 46 + u64 ret_overrun; 47 + bool ret; 48 + 49 + ret_overrun = hrtimer_forward_now(&du->vkms.timer, 50 + du->vkms.period_ns); 51 + if (ret_overrun != 1) 52 + DRM_WARN("%s: vblank timer overrun\n", __func__); 53 + 54 + ret = drm_crtc_handle_vblank(crtc); 55 + /* Don't queue timer again when vblank is disabled. */ 56 + if (!ret) 57 + return HRTIMER_NORESTART; 58 + 59 + return HRTIMER_RESTART; 60 + } 61 + 62 + void 63 + vmw_vkms_init(struct vmw_private *vmw) 64 + { 65 + char buffer[64]; 66 + const size_t max_buf_len = sizeof(buffer) - 1; 67 + size_t buf_len = max_buf_len; 68 + int ret; 69 + 70 + vmw->vkms_enabled = false; 71 + 72 + ret = vmw_host_get_guestinfo(GUESTINFO_VBLANK, buffer, &buf_len); 73 + if (ret || buf_len > max_buf_len) 74 + return; 75 + buffer[buf_len] = '\0'; 76 + 77 + ret = kstrtobool(buffer, &vmw->vkms_enabled); 78 + if (!ret && vmw->vkms_enabled) { 79 + ret = drm_vblank_init(&vmw->drm, VMWGFX_NUM_DISPLAY_UNITS); 80 + vmw->vkms_enabled = (ret == 0); 81 + drm_info(&vmw->drm, "vkms_enabled = %d\n", vmw->vkms_enabled); 82 + } 83 + } 84 + 85 + bool 86 + vmw_vkms_get_vblank_timestamp(struct drm_crtc *crtc, 87 + int *max_error, 88 + ktime_t *vblank_time, 89 + bool in_vblank_irq) 90 + { 91 + struct drm_device *dev = crtc->dev; 92 + struct vmw_private *vmw = vmw_priv(dev); 93 + unsigned int pipe = crtc->index; 94 + struct vmw_display_unit *du = vmw_crtc_to_du(crtc); 95 + struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; 96 + 97 + if (!vmw->vkms_enabled) 98 + return false; 99 + 100 + if (!READ_ONCE(vblank->enabled)) { 101 + *vblank_time = ktime_get(); 102 + return true; 103 + } 104 + 105 + *vblank_time = READ_ONCE(du->vkms.timer.node.expires); 106 + 107 + if (WARN_ON(*vblank_time == vblank->time)) 108 + return true; 109 + 110 + /* 111 + * To prevent races we roll the hrtimer forward before we do any 112 + * interrupt processing - this is how real hw works (the interrupt is 113 + * only generated after all the vblank registers are updated) and what 114 + * the vblank core expects. Therefore we need to always correct the 115 + * timestampe by one frame. 116 + */ 117 + *vblank_time -= du->vkms.period_ns; 118 + 119 + return true; 120 + } 121 + 122 + int 123 + vmw_vkms_enable_vblank(struct drm_crtc *crtc) 124 + { 125 + struct drm_device *dev = crtc->dev; 126 + struct vmw_private *vmw = vmw_priv(dev); 127 + unsigned int pipe = drm_crtc_index(crtc); 128 + struct drm_vblank_crtc *vblank = &dev->vblank[pipe]; 129 + struct vmw_display_unit *du = vmw_crtc_to_du(crtc); 130 + 131 + if (!vmw->vkms_enabled) 132 + return -EINVAL; 133 + 134 + drm_calc_timestamping_constants(crtc, &crtc->mode); 135 + 136 + du->vkms.period_ns = ktime_set(0, vblank->framedur_ns); 137 + hrtimer_start(&du->vkms.timer, du->vkms.period_ns, HRTIMER_MODE_REL); 138 + 139 + return 0; 140 + } 141 + 142 + void 143 + vmw_vkms_disable_vblank(struct drm_crtc *crtc) 144 + { 145 + struct vmw_display_unit *du = vmw_crtc_to_du(crtc); 146 + struct vmw_private *vmw = vmw_priv(crtc->dev); 147 + 148 + if (!vmw->vkms_enabled) 149 + return; 150 + 151 + hrtimer_try_to_cancel(&du->vkms.timer); 152 + } 153 + 154 + void 155 + vmw_vkms_crtc_atomic_flush(struct drm_crtc *crtc, 156 + struct drm_atomic_state *state) 157 + { 158 + unsigned long flags; 159 + struct vmw_private *vmw = vmw_priv(crtc->dev); 160 + 161 + if (vmw->vkms_enabled && crtc->state->event) { 162 + spin_lock_irqsave(&crtc->dev->event_lock, flags); 163 + 164 + if (drm_crtc_vblank_get(crtc) != 0) 165 + drm_crtc_send_vblank_event(crtc, crtc->state->event); 166 + else 167 + drm_crtc_arm_vblank_event(crtc, crtc->state->event); 168 + 169 + spin_unlock_irqrestore(&crtc->dev->event_lock, flags); 170 + 171 + crtc->state->event = NULL; 172 + } 173 + } 174 + 175 + void 176 + vmw_vkms_crtc_atomic_enable(struct drm_crtc *crtc, 177 + struct drm_atomic_state *state) 178 + { 179 + struct vmw_private *vmw = vmw_priv(crtc->dev); 180 + 181 + if (vmw->vkms_enabled) 182 + drm_crtc_vblank_on(crtc); 183 + } 184 + 185 + void 186 + vmw_vkms_crtc_atomic_disable(struct drm_crtc *crtc, 187 + struct drm_atomic_state *state) 188 + { 189 + struct vmw_private *vmw = vmw_priv(crtc->dev); 190 + 191 + if (vmw->vkms_enabled) 192 + drm_crtc_vblank_off(crtc); 193 + }
+53
drivers/gpu/drm/vmwgfx/vmwgfx_vkms.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 OR MIT */ 2 + /************************************************************************** 3 + * 4 + * Copyright (c) 2024 Broadcom. All Rights Reserved. The term 5 + * “Broadcom” refers to Broadcom Inc. and/or its subsidiaries. 6 + * 7 + * Permission is hereby granted, free of charge, to any person obtaining a 8 + * copy of this software and associated documentation files (the 9 + * "Software"), to deal in the Software without restriction, including 10 + * without limitation the rights to use, copy, modify, merge, publish, 11 + * distribute, sub license, and/or sell copies of the Software, and to 12 + * permit persons to whom the Software is furnished to do so, subject to 13 + * the following conditions: 14 + * 15 + * The above copyright notice and this permission notice (including the 16 + * next paragraph) shall be included in all copies or substantial portions 17 + * of the Software. 18 + * 19 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 22 + * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 23 + * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 24 + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 25 + * USE OR OTHER DEALINGS IN THE SOFTWARE. 26 + * 27 + **************************************************************************/ 28 + 29 + #ifndef VMWGFX_VKMS_H_ 30 + #define VMWGFX_VKMS_H_ 31 + 32 + #include <linux/hrtimer_types.h> 33 + #include <linux/types.h> 34 + 35 + struct vmw_private; 36 + struct drm_crtc; 37 + struct drm_atomic_state; 38 + 39 + void vmw_vkms_init(struct vmw_private *vmw); 40 + bool vmw_vkms_get_vblank_timestamp(struct drm_crtc *crtc, 41 + int *max_error, 42 + ktime_t *vblank_time, 43 + bool in_vblank_irq); 44 + int vmw_vkms_enable_vblank(struct drm_crtc *crtc); 45 + void vmw_vkms_disable_vblank(struct drm_crtc *crtc); 46 + void vmw_vkms_crtc_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state); 47 + enum hrtimer_restart vmw_vkms_vblank_simulate(struct hrtimer *timer); 48 + void vmw_vkms_crtc_atomic_enable(struct drm_crtc *crtc, 49 + struct drm_atomic_state *state); 50 + void vmw_vkms_crtc_atomic_disable(struct drm_crtc *crtc, 51 + struct drm_atomic_state *state); 52 + 53 + #endif