1fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz/************************************************************************** 2fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * 3fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * Copyright © 2009 VMware, Inc., Palo Alto, CA., USA 4fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * All Rights Reserved. 5fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * 6fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * Permission is hereby granted, free of charge, to any person obtaining a 7fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * copy of this software and associated documentation files (the 8fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * "Software"), to deal in the Software without restriction, including 9fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * without limitation the rights to use, copy, modify, merge, publish, 10fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * distribute, sub license, and/or sell copies of the Software, and to 11fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * permit persons to whom the Software is furnished to do so, subject to 12fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * the following conditions: 13fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * 14fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * The above copyright notice and this permission notice (including the 15fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * next paragraph) shall be included in all copies or substantial portions 16fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * of the Software. 17fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * 18fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 21fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, 22fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 23fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 24fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * USE OR OTHER DEALINGS IN THE SOFTWARE. 25fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * 26fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz **************************************************************************/ 27e0cd3608135b2ed8eddbe3fdf048d22e0593d836Paul Gortmaker#include <linux/module.h> 28fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 29fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#include "drmP.h" 30fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#include "vmwgfx_drv.h" 31fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#include "ttm/ttm_placement.h" 32fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#include "ttm/ttm_bo_driver.h" 33fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#include "ttm/ttm_object.h" 34fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#include "ttm/ttm_module.h" 35fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 36fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#define VMWGFX_DRIVER_NAME "vmwgfx" 37fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#define VMWGFX_DRIVER_DESC "Linux drm driver for VMware graphics devices" 38fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#define VMWGFX_CHIP_SVGAII 0 39fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#define VMW_FB_RESERVATION 0 40fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 41eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz#define VMW_MIN_INITIAL_WIDTH 800 42eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz#define VMW_MIN_INITIAL_HEIGHT 600 43eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz 44eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz 45fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz/** 46fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * Fully encoded drm commands. Might move to vmw_drm.h 47fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz */ 48fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 49fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#define DRM_IOCTL_VMW_GET_PARAM \ 50fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_GET_PARAM, \ 51fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_vmw_getparam_arg) 52fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#define DRM_IOCTL_VMW_ALLOC_DMABUF \ 53fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_ALLOC_DMABUF, \ 54fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz union drm_vmw_alloc_dmabuf_arg) 55fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#define DRM_IOCTL_VMW_UNREF_DMABUF \ 56fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UNREF_DMABUF, \ 57fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_vmw_unref_dmabuf_arg) 58fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#define DRM_IOCTL_VMW_CURSOR_BYPASS \ 59fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_CURSOR_BYPASS, \ 60fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_vmw_cursor_bypass_arg) 61fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 62fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#define DRM_IOCTL_VMW_CONTROL_STREAM \ 63fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_CONTROL_STREAM, \ 64fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_vmw_control_stream_arg) 65fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#define DRM_IOCTL_VMW_CLAIM_STREAM \ 66fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_IOR(DRM_COMMAND_BASE + DRM_VMW_CLAIM_STREAM, \ 67fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_vmw_stream_arg) 68fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#define DRM_IOCTL_VMW_UNREF_STREAM \ 69fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UNREF_STREAM, \ 70fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_vmw_stream_arg) 71fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 72fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#define DRM_IOCTL_VMW_CREATE_CONTEXT \ 73fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_IOR(DRM_COMMAND_BASE + DRM_VMW_CREATE_CONTEXT, \ 74fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_vmw_context_arg) 75fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#define DRM_IOCTL_VMW_UNREF_CONTEXT \ 76fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UNREF_CONTEXT, \ 77fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_vmw_context_arg) 78fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#define DRM_IOCTL_VMW_CREATE_SURFACE \ 79fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_CREATE_SURFACE, \ 80fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz union drm_vmw_surface_create_arg) 81fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#define DRM_IOCTL_VMW_UNREF_SURFACE \ 82fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UNREF_SURFACE, \ 83fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_vmw_surface_arg) 84fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#define DRM_IOCTL_VMW_REF_SURFACE \ 85fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_REF_SURFACE, \ 86fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz union drm_vmw_surface_reference_arg) 87fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#define DRM_IOCTL_VMW_EXECBUF \ 88fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_EXECBUF, \ 89fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_vmw_execbuf_arg) 90ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom#define DRM_IOCTL_VMW_GET_3D_CAP \ 91ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_GET_3D_CAP, \ 92ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom struct drm_vmw_get_3d_cap_arg) 93fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#define DRM_IOCTL_VMW_FENCE_WAIT \ 94fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_FENCE_WAIT, \ 95fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_vmw_fence_wait_arg) 96ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom#define DRM_IOCTL_VMW_FENCE_SIGNALED \ 97ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom DRM_IOWR(DRM_COMMAND_BASE + DRM_VMW_FENCE_SIGNALED, \ 98ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom struct drm_vmw_fence_signaled_arg) 99ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom#define DRM_IOCTL_VMW_FENCE_UNREF \ 100ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_FENCE_UNREF, \ 101ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom struct drm_vmw_fence_arg) 10257c5ee79acba9582762c09c269e0e2ae1adf1b31Thomas Hellstrom#define DRM_IOCTL_VMW_FENCE_EVENT \ 10357c5ee79acba9582762c09c269e0e2ae1adf1b31Thomas Hellstrom DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_FENCE_EVENT, \ 10457c5ee79acba9582762c09c269e0e2ae1adf1b31Thomas Hellstrom struct drm_vmw_fence_event_arg) 1052fcd5a73bfd5341876f9ea6b5adcc1dd814226d4Jakob Bornecrantz#define DRM_IOCTL_VMW_PRESENT \ 1062fcd5a73bfd5341876f9ea6b5adcc1dd814226d4Jakob Bornecrantz DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_PRESENT, \ 1072fcd5a73bfd5341876f9ea6b5adcc1dd814226d4Jakob Bornecrantz struct drm_vmw_present_arg) 1082fcd5a73bfd5341876f9ea6b5adcc1dd814226d4Jakob Bornecrantz#define DRM_IOCTL_VMW_PRESENT_READBACK \ 1092fcd5a73bfd5341876f9ea6b5adcc1dd814226d4Jakob Bornecrantz DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_PRESENT_READBACK, \ 1102fcd5a73bfd5341876f9ea6b5adcc1dd814226d4Jakob Bornecrantz struct drm_vmw_present_readback_arg) 111cd2b89e7e8c036903e7fa0c3dceca25e755fe78dThomas Hellstrom#define DRM_IOCTL_VMW_UPDATE_LAYOUT \ 112cd2b89e7e8c036903e7fa0c3dceca25e755fe78dThomas Hellstrom DRM_IOW(DRM_COMMAND_BASE + DRM_VMW_UPDATE_LAYOUT, \ 113cd2b89e7e8c036903e7fa0c3dceca25e755fe78dThomas Hellstrom struct drm_vmw_update_layout_arg) 114fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 115fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz/** 116fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * The core DRM version of this macro doesn't account for 117fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * DRM_COMMAND_BASE. 118fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz */ 119fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 120fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz#define VMW_IOCTL_DEF(ioctl, func, flags) \ 1211b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie [DRM_IOCTL_NR(DRM_IOCTL_##ioctl) - DRM_COMMAND_BASE] = {DRM_##ioctl, flags, func, DRM_IOCTL_##ioctl} 122fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 123fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz/** 124fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * Ioctl definitions. 125fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz */ 126fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 127fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic struct drm_ioctl_desc vmw_ioctls[] = { 1281b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie VMW_IOCTL_DEF(VMW_GET_PARAM, vmw_getparam_ioctl, 129e1f7800315d78686481b27b113a3317ac687b6bfThomas Hellstrom DRM_AUTH | DRM_UNLOCKED), 1301b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie VMW_IOCTL_DEF(VMW_ALLOC_DMABUF, vmw_dmabuf_alloc_ioctl, 131e1f7800315d78686481b27b113a3317ac687b6bfThomas Hellstrom DRM_AUTH | DRM_UNLOCKED), 1321b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie VMW_IOCTL_DEF(VMW_UNREF_DMABUF, vmw_dmabuf_unref_ioctl, 133e1f7800315d78686481b27b113a3317ac687b6bfThomas Hellstrom DRM_AUTH | DRM_UNLOCKED), 1341b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie VMW_IOCTL_DEF(VMW_CURSOR_BYPASS, 135e1f7800315d78686481b27b113a3317ac687b6bfThomas Hellstrom vmw_kms_cursor_bypass_ioctl, 136e1f7800315d78686481b27b113a3317ac687b6bfThomas Hellstrom DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), 137fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 1381b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie VMW_IOCTL_DEF(VMW_CONTROL_STREAM, vmw_overlay_ioctl, 139e1f7800315d78686481b27b113a3317ac687b6bfThomas Hellstrom DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), 1401b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie VMW_IOCTL_DEF(VMW_CLAIM_STREAM, vmw_stream_claim_ioctl, 141e1f7800315d78686481b27b113a3317ac687b6bfThomas Hellstrom DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), 1421b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie VMW_IOCTL_DEF(VMW_UNREF_STREAM, vmw_stream_unref_ioctl, 143e1f7800315d78686481b27b113a3317ac687b6bfThomas Hellstrom DRM_MASTER | DRM_CONTROL_ALLOW | DRM_UNLOCKED), 144fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 1451b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie VMW_IOCTL_DEF(VMW_CREATE_CONTEXT, vmw_context_define_ioctl, 146e1f7800315d78686481b27b113a3317ac687b6bfThomas Hellstrom DRM_AUTH | DRM_UNLOCKED), 1471b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie VMW_IOCTL_DEF(VMW_UNREF_CONTEXT, vmw_context_destroy_ioctl, 148e1f7800315d78686481b27b113a3317ac687b6bfThomas Hellstrom DRM_AUTH | DRM_UNLOCKED), 1491b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie VMW_IOCTL_DEF(VMW_CREATE_SURFACE, vmw_surface_define_ioctl, 150e1f7800315d78686481b27b113a3317ac687b6bfThomas Hellstrom DRM_AUTH | DRM_UNLOCKED), 1511b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie VMW_IOCTL_DEF(VMW_UNREF_SURFACE, vmw_surface_destroy_ioctl, 152e1f7800315d78686481b27b113a3317ac687b6bfThomas Hellstrom DRM_AUTH | DRM_UNLOCKED), 1531b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie VMW_IOCTL_DEF(VMW_REF_SURFACE, vmw_surface_reference_ioctl, 154e1f7800315d78686481b27b113a3317ac687b6bfThomas Hellstrom DRM_AUTH | DRM_UNLOCKED), 1551b2f1489633888d4a06028315dc19d65768a1c05Dave Airlie VMW_IOCTL_DEF(VMW_EXECBUF, vmw_execbuf_ioctl, 156e1f7800315d78686481b27b113a3317ac687b6bfThomas Hellstrom DRM_AUTH | DRM_UNLOCKED), 157ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom VMW_IOCTL_DEF(VMW_FENCE_WAIT, vmw_fence_obj_wait_ioctl, 158ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom DRM_AUTH | DRM_UNLOCKED), 159ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom VMW_IOCTL_DEF(VMW_FENCE_SIGNALED, 160ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom vmw_fence_obj_signaled_ioctl, 161ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom DRM_AUTH | DRM_UNLOCKED), 162ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom VMW_IOCTL_DEF(VMW_FENCE_UNREF, vmw_fence_obj_unref_ioctl, 163d8bd19d2aff95e52c7f356cc2fc722584a656065Jakob Bornecrantz DRM_AUTH | DRM_UNLOCKED), 16457c5ee79acba9582762c09c269e0e2ae1adf1b31Thomas Hellstrom VMW_IOCTL_DEF(VMW_FENCE_EVENT, 16557c5ee79acba9582762c09c269e0e2ae1adf1b31Thomas Hellstrom vmw_fence_event_ioctl, 16657c5ee79acba9582762c09c269e0e2ae1adf1b31Thomas Hellstrom DRM_AUTH | DRM_UNLOCKED), 167f63f6a59d3905ac73aeeb617b27ac31516549ed9Thomas Hellstrom VMW_IOCTL_DEF(VMW_GET_3D_CAP, vmw_get_cap_3d_ioctl, 168f63f6a59d3905ac73aeeb617b27ac31516549ed9Thomas Hellstrom DRM_AUTH | DRM_UNLOCKED), 1692fcd5a73bfd5341876f9ea6b5adcc1dd814226d4Jakob Bornecrantz 1702fcd5a73bfd5341876f9ea6b5adcc1dd814226d4Jakob Bornecrantz /* these allow direct access to the framebuffers mark as master only */ 1712fcd5a73bfd5341876f9ea6b5adcc1dd814226d4Jakob Bornecrantz VMW_IOCTL_DEF(VMW_PRESENT, vmw_present_ioctl, 1722fcd5a73bfd5341876f9ea6b5adcc1dd814226d4Jakob Bornecrantz DRM_MASTER | DRM_AUTH | DRM_UNLOCKED), 1732fcd5a73bfd5341876f9ea6b5adcc1dd814226d4Jakob Bornecrantz VMW_IOCTL_DEF(VMW_PRESENT_READBACK, 1742fcd5a73bfd5341876f9ea6b5adcc1dd814226d4Jakob Bornecrantz vmw_present_readback_ioctl, 1752fcd5a73bfd5341876f9ea6b5adcc1dd814226d4Jakob Bornecrantz DRM_MASTER | DRM_AUTH | DRM_UNLOCKED), 176cd2b89e7e8c036903e7fa0c3dceca25e755fe78dThomas Hellstrom VMW_IOCTL_DEF(VMW_UPDATE_LAYOUT, 177cd2b89e7e8c036903e7fa0c3dceca25e755fe78dThomas Hellstrom vmw_kms_update_layout_ioctl, 178cd2b89e7e8c036903e7fa0c3dceca25e755fe78dThomas Hellstrom DRM_MASTER | DRM_UNLOCKED), 179fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz}; 180fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 181fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic struct pci_device_id vmw_pci_id_list[] = { 182fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz {0x15ad, 0x0405, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VMWGFX_CHIP_SVGAII}, 183fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz {0, 0, 0} 184fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz}; 185fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 18630c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstromstatic int enable_fbdev; 187fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 188fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_probe(struct pci_dev *, const struct pci_device_id *); 189fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic void vmw_master_init(struct vmw_master *); 190d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstromstatic int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, 191d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom void *ptr); 192fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 19330c78bb838b26ec7997515844c0c734e454b3cbaThomas HellstromMODULE_PARM_DESC(enable_fbdev, "Enable vmwgfx fbdev"); 19430c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrommodule_param_named(enable_fbdev, enable_fbdev, int, 0600); 19530c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom 196fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic void vmw_print_capabilities(uint32_t capabilities) 197fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 198fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO("Capabilities:\n"); 199fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (capabilities & SVGA_CAP_RECT_COPY) 200fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO(" Rect copy.\n"); 201fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (capabilities & SVGA_CAP_CURSOR) 202fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO(" Cursor.\n"); 203fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (capabilities & SVGA_CAP_CURSOR_BYPASS) 204fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO(" Cursor bypass.\n"); 205fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (capabilities & SVGA_CAP_CURSOR_BYPASS_2) 206fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO(" Cursor bypass 2.\n"); 207fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (capabilities & SVGA_CAP_8BIT_EMULATION) 208fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO(" 8bit emulation.\n"); 209fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (capabilities & SVGA_CAP_ALPHA_CURSOR) 210fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO(" Alpha cursor.\n"); 211fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (capabilities & SVGA_CAP_3D) 212fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO(" 3D.\n"); 213fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (capabilities & SVGA_CAP_EXTENDED_FIFO) 214fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO(" Extended Fifo.\n"); 215fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (capabilities & SVGA_CAP_MULTIMON) 216fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO(" Multimon.\n"); 217fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (capabilities & SVGA_CAP_PITCHLOCK) 218fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO(" Pitchlock.\n"); 219fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (capabilities & SVGA_CAP_IRQMASK) 220fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO(" Irq mask.\n"); 221fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) 222fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO(" Display Topology.\n"); 223fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (capabilities & SVGA_CAP_GMR) 224fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO(" GMR.\n"); 225fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (capabilities & SVGA_CAP_TRACES) 226fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO(" Traces.\n"); 227dcca28627df25292139afbce287045ddd3dc909eThomas Hellstrom if (capabilities & SVGA_CAP_GMR2) 228dcca28627df25292139afbce287045ddd3dc909eThomas Hellstrom DRM_INFO(" GMR2.\n"); 229dcca28627df25292139afbce287045ddd3dc909eThomas Hellstrom if (capabilities & SVGA_CAP_SCREEN_OBJECT_2) 230dcca28627df25292139afbce287045ddd3dc909eThomas Hellstrom DRM_INFO(" Screen Object 2.\n"); 231fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 232fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 233e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 234e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom/** 235e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * vmw_execbuf_prepare_dummy_query - Initialize a query result structure at 236e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * the start of a buffer object. 237e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 238e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * @dev_priv: The device private structure. 239e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 240e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * This function will idle the buffer using an uninterruptible wait, then 241e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * map the first page and initialize a pending occlusion query result structure, 242e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * Finally it will unmap the buffer. 243e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 244e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * TODO: Since we're only mapping a single page, we should optimize the map 245e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * to use kmap_atomic / iomap_atomic. 246e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom */ 247e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstromstatic void vmw_dummy_query_bo_prepare(struct vmw_private *dev_priv) 248e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom{ 249e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom struct ttm_bo_kmap_obj map; 250e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom volatile SVGA3dQueryResult *result; 251e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom bool dummy; 252e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom int ret; 253e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom struct ttm_bo_device *bdev = &dev_priv->bdev; 254e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom struct ttm_buffer_object *bo = dev_priv->dummy_query_bo; 255e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 256e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom ttm_bo_reserve(bo, false, false, false, 0); 257e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom spin_lock(&bdev->fence_lock); 2581717c0e23f411147490c7a3312b894f0ea9a5fb1Dave Airlie ret = ttm_bo_wait(bo, false, false, false); 259e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom spin_unlock(&bdev->fence_lock); 260e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom if (unlikely(ret != 0)) 261e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom (void) vmw_fallback_wait(dev_priv, false, true, 0, false, 262e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 10*HZ); 263e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 264e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom ret = ttm_bo_kmap(bo, 0, 1, &map); 265e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom if (likely(ret == 0)) { 266e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom result = ttm_kmap_obj_virtual(&map, &dummy); 267e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom result->totalSize = sizeof(*result); 268e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom result->state = SVGA3D_QUERYSTATE_PENDING; 269e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom result->result32 = 0xff; 270e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom ttm_bo_kunmap(&map); 271e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom } else 272e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom DRM_ERROR("Dummy query buffer map failed.\n"); 273e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom ttm_bo_unreserve(bo); 274e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom} 275e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 276e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 277e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom/** 278e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * vmw_dummy_query_bo_create - create a bo to hold a dummy query result 279e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 280e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * @dev_priv: A device private structure. 281e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 282e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * This function creates a small buffer object that holds the query 283e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * result for dummy queries emitted as query barriers. 284e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * No interruptible waits are done within this function. 285e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * 286e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * Returns an error if bo creation fails. 287e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom */ 288e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstromstatic int vmw_dummy_query_bo_create(struct vmw_private *dev_priv) 289e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom{ 290e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom return ttm_bo_create(&dev_priv->bdev, 291e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom PAGE_SIZE, 292e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom ttm_bo_type_device, 293e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom &vmw_vram_sys_placement, 294e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 0, 0, false, NULL, 295e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom &dev_priv->dummy_query_bo); 296e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom} 297e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 298e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 299fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_request_device(struct vmw_private *dev_priv) 300fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 301fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz int ret; 302fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 303fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ret = vmw_fifo_init(dev_priv, &dev_priv->fifo); 304fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(ret != 0)) { 305fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_ERROR("Unable to initialize FIFO.\n"); 306fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return ret; 307fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 308ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom vmw_fence_fifo_up(dev_priv->fman); 309e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom ret = vmw_dummy_query_bo_create(dev_priv); 310e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom if (unlikely(ret != 0)) 311e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom goto out_no_query_bo; 312e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom vmw_dummy_query_bo_prepare(dev_priv); 313fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 314fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return 0; 315e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 316e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstromout_no_query_bo: 317e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom vmw_fence_fifo_down(dev_priv->fman); 318e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom vmw_fifo_release(dev_priv, &dev_priv->fifo); 319e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom return ret; 320fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 321fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 322fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic void vmw_release_device(struct vmw_private *dev_priv) 323fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 324e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom /* 325e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * Previous destructions should've released 326e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom * the pinned bo. 327e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom */ 328e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 329e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom BUG_ON(dev_priv->pinned_bo != NULL); 330e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 331e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom ttm_bo_unref(&dev_priv->dummy_query_bo); 332ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom vmw_fence_fifo_down(dev_priv->fman); 333fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz vmw_fifo_release(dev_priv, &dev_priv->fifo); 33430c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom} 33530c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom 33605730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom/** 33705730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom * Increase the 3d resource refcount. 33805730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom * If the count was prevously zero, initialize the fifo, switching to svga 33905730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom * mode. Note that the master holds a ref as well, and may request an 34005730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom * explicit switch to svga mode if fb is not running, using @unhide_svga. 34105730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom */ 34205730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstromint vmw_3d_resource_inc(struct vmw_private *dev_priv, 34305730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom bool unhide_svga) 34430c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom{ 34530c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom int ret = 0; 34630c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom 34730c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom mutex_lock(&dev_priv->release_mutex); 34830c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom if (unlikely(dev_priv->num_3d_resources++ == 0)) { 34930c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom ret = vmw_request_device(dev_priv); 35030c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom if (unlikely(ret != 0)) 35130c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom --dev_priv->num_3d_resources; 35205730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom } else if (unhide_svga) { 35305730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom mutex_lock(&dev_priv->hw_mutex); 35405730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom vmw_write(dev_priv, SVGA_REG_ENABLE, 35505730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom vmw_read(dev_priv, SVGA_REG_ENABLE) & 35605730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom ~SVGA_REG_ENABLE_HIDE); 35705730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom mutex_unlock(&dev_priv->hw_mutex); 35830c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom } 35905730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom 36030c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom mutex_unlock(&dev_priv->release_mutex); 36130c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom return ret; 362fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 363fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 36405730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom/** 36505730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom * Decrease the 3d resource refcount. 36605730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom * If the count reaches zero, disable the fifo, switching to vga mode. 36705730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom * Note that the master holds a refcount as well, and may request an 36805730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom * explicit switch to vga mode when it releases its refcount to account 36905730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom * for the situation of an X server vt switch to VGA with 3d resources 37005730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom * active. 37105730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom */ 37205730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstromvoid vmw_3d_resource_dec(struct vmw_private *dev_priv, 37305730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom bool hide_svga) 37430c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom{ 37530c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom int32_t n3d; 37630c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom 37730c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom mutex_lock(&dev_priv->release_mutex); 37830c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom if (unlikely(--dev_priv->num_3d_resources == 0)) 37930c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom vmw_release_device(dev_priv); 38005730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom else if (hide_svga) { 38105730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom mutex_lock(&dev_priv->hw_mutex); 38205730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom vmw_write(dev_priv, SVGA_REG_ENABLE, 38305730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom vmw_read(dev_priv, SVGA_REG_ENABLE) | 38405730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom SVGA_REG_ENABLE_HIDE); 38505730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom mutex_unlock(&dev_priv->hw_mutex); 38605730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom } 38705730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom 38830c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom n3d = (int32_t) dev_priv->num_3d_resources; 38930c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom mutex_unlock(&dev_priv->release_mutex); 39030c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom 39130c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom BUG_ON(n3d < 0); 39230c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom} 39330c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom 394eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz/** 395eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz * Sets the initial_[width|height] fields on the given vmw_private. 396eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz * 397eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz * It does so by reading SVGA_REG_[WIDTH|HEIGHT] regs and then 39867d4a87b0a6bf7225aacc2c14e3542ec2f6b803fThomas Hellstrom * clamping the value to fb_max_[width|height] fields and the 39967d4a87b0a6bf7225aacc2c14e3542ec2f6b803fThomas Hellstrom * VMW_MIN_INITIAL_[WIDTH|HEIGHT]. 40067d4a87b0a6bf7225aacc2c14e3542ec2f6b803fThomas Hellstrom * If the values appear to be invalid, set them to 401eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz * VMW_MIN_INITIAL_[WIDTH|HEIGHT]. 402eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz */ 403eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantzstatic void vmw_get_initial_size(struct vmw_private *dev_priv) 404eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz{ 405eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz uint32_t width; 406eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz uint32_t height; 407eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz 408eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz width = vmw_read(dev_priv, SVGA_REG_WIDTH); 409eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz height = vmw_read(dev_priv, SVGA_REG_HEIGHT); 410eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz 411eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz width = max_t(uint32_t, width, VMW_MIN_INITIAL_WIDTH); 412eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz height = max_t(uint32_t, height, VMW_MIN_INITIAL_HEIGHT); 41367d4a87b0a6bf7225aacc2c14e3542ec2f6b803fThomas Hellstrom 41467d4a87b0a6bf7225aacc2c14e3542ec2f6b803fThomas Hellstrom if (width > dev_priv->fb_max_width || 41567d4a87b0a6bf7225aacc2c14e3542ec2f6b803fThomas Hellstrom height > dev_priv->fb_max_height) { 41667d4a87b0a6bf7225aacc2c14e3542ec2f6b803fThomas Hellstrom 41767d4a87b0a6bf7225aacc2c14e3542ec2f6b803fThomas Hellstrom /* 41867d4a87b0a6bf7225aacc2c14e3542ec2f6b803fThomas Hellstrom * This is a host error and shouldn't occur. 41967d4a87b0a6bf7225aacc2c14e3542ec2f6b803fThomas Hellstrom */ 42067d4a87b0a6bf7225aacc2c14e3542ec2f6b803fThomas Hellstrom 42167d4a87b0a6bf7225aacc2c14e3542ec2f6b803fThomas Hellstrom width = VMW_MIN_INITIAL_WIDTH; 42267d4a87b0a6bf7225aacc2c14e3542ec2f6b803fThomas Hellstrom height = VMW_MIN_INITIAL_HEIGHT; 42367d4a87b0a6bf7225aacc2c14e3542ec2f6b803fThomas Hellstrom } 424eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz 425eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz dev_priv->initial_width = width; 426eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz dev_priv->initial_height = height; 427eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz} 428eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz 429fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_driver_load(struct drm_device *dev, unsigned long chipset) 430fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 431fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_private *dev_priv; 432fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz int ret; 433c188660f6dbb0df9febe1b841a16c66c28353c15Peter Hanzel uint32_t svga_id; 434fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 435fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); 436fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(dev_priv == NULL)) { 437fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_ERROR("Failed allocating a device private struct.\n"); 438fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return -ENOMEM; 439fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 440fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz memset(dev_priv, 0, sizeof(*dev_priv)); 441fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 442466e69b8b03b8c1987367912782bc12988ad8794Dave Airlie pci_set_master(dev->pdev); 443466e69b8b03b8c1987367912782bc12988ad8794Dave Airlie 444fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->dev = dev; 445fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->vmw_chipset = chipset; 4466bcd8d3c782b7b2c98c8f414a6bb43cf6b84e53cThomas Hellstrom dev_priv->last_read_seqno = (uint32_t) -100; 447fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz mutex_init(&dev_priv->hw_mutex); 448fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz mutex_init(&dev_priv->cmdbuf_mutex); 44930c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom mutex_init(&dev_priv->release_mutex); 450fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz rwlock_init(&dev_priv->resource_lock); 451fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz idr_init(&dev_priv->context_idr); 452fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz idr_init(&dev_priv->surface_idr); 453fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz idr_init(&dev_priv->stream_idr); 454fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz mutex_init(&dev_priv->init_mutex); 455fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz init_waitqueue_head(&dev_priv->fence_queue); 456fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz init_waitqueue_head(&dev_priv->fifo_queue); 4574f73a96bd76914009682432842ac04a32ab9115bThomas Hellstrom dev_priv->fence_queue_waiters = 0; 458fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz atomic_set(&dev_priv->fifo_queue_waiters, 0); 4595bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom INIT_LIST_HEAD(&dev_priv->surface_lru); 4605bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom dev_priv->used_memory_size = 0; 461fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 462fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->io_start = pci_resource_start(dev->pdev, 0); 463fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->vram_start = pci_resource_start(dev->pdev, 1); 464fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->mmio_start = pci_resource_start(dev->pdev, 2); 465fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 46630c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom dev_priv->enable_fb = enable_fbdev; 46730c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom 468fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz mutex_lock(&dev_priv->hw_mutex); 469c188660f6dbb0df9febe1b841a16c66c28353c15Peter Hanzel 470c188660f6dbb0df9febe1b841a16c66c28353c15Peter Hanzel vmw_write(dev_priv, SVGA_REG_ID, SVGA_ID_2); 471c188660f6dbb0df9febe1b841a16c66c28353c15Peter Hanzel svga_id = vmw_read(dev_priv, SVGA_REG_ID); 472c188660f6dbb0df9febe1b841a16c66c28353c15Peter Hanzel if (svga_id != SVGA_ID_2) { 473c188660f6dbb0df9febe1b841a16c66c28353c15Peter Hanzel ret = -ENOSYS; 474496259048e6c75a212fa1c5bb863cfd6b008903cMasanari Iida DRM_ERROR("Unsupported SVGA ID 0x%x\n", svga_id); 475c188660f6dbb0df9febe1b841a16c66c28353c15Peter Hanzel mutex_unlock(&dev_priv->hw_mutex); 476c188660f6dbb0df9febe1b841a16c66c28353c15Peter Hanzel goto out_err0; 477c188660f6dbb0df9febe1b841a16c66c28353c15Peter Hanzel } 478c188660f6dbb0df9febe1b841a16c66c28353c15Peter Hanzel 479fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->capabilities = vmw_read(dev_priv, SVGA_REG_CAPABILITIES); 480fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 4815bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom dev_priv->vram_size = vmw_read(dev_priv, SVGA_REG_VRAM_SIZE); 4825bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom dev_priv->mmio_size = vmw_read(dev_priv, SVGA_REG_MEM_SIZE); 4835bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom dev_priv->fb_max_width = vmw_read(dev_priv, SVGA_REG_MAX_WIDTH); 4845bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom dev_priv->fb_max_height = vmw_read(dev_priv, SVGA_REG_MAX_HEIGHT); 485eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz 486eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz vmw_get_initial_size(dev_priv); 487eb4f923b1ceac8a618469c51ff249bd89bc0dfa4Jakob Bornecrantz 488fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (dev_priv->capabilities & SVGA_CAP_GMR) { 489fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->max_gmr_descriptors = 490fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz vmw_read(dev_priv, 491fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz SVGA_REG_GMR_MAX_DESCRIPTOR_LENGTH); 492fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->max_gmr_ids = 493fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz vmw_read(dev_priv, SVGA_REG_GMR_MAX_IDS); 494fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 495fb17f18993071cc230ec8ddb6dd3dd9932d2dba2Thomas Hellstrom if (dev_priv->capabilities & SVGA_CAP_GMR2) { 496fb17f18993071cc230ec8ddb6dd3dd9932d2dba2Thomas Hellstrom dev_priv->max_gmr_pages = 497fb17f18993071cc230ec8ddb6dd3dd9932d2dba2Thomas Hellstrom vmw_read(dev_priv, SVGA_REG_GMRS_MAX_PAGES); 498fb17f18993071cc230ec8ddb6dd3dd9932d2dba2Thomas Hellstrom dev_priv->memory_size = 499fb17f18993071cc230ec8ddb6dd3dd9932d2dba2Thomas Hellstrom vmw_read(dev_priv, SVGA_REG_MEMORY_SIZE); 5005bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom dev_priv->memory_size -= dev_priv->vram_size; 5015bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom } else { 5025bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom /* 5035bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom * An arbitrary limit of 512MiB on surface 5045bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom * memory. But all HWV8 hardware supports GMR2. 5055bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom */ 5065bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom dev_priv->memory_size = 512*1024*1024; 507fb17f18993071cc230ec8ddb6dd3dd9932d2dba2Thomas Hellstrom } 508fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 509fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz mutex_unlock(&dev_priv->hw_mutex); 510fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 511fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz vmw_print_capabilities(dev_priv->capabilities); 512fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 513fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (dev_priv->capabilities & SVGA_CAP_GMR) { 514fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO("Max GMR ids is %u\n", 515fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz (unsigned)dev_priv->max_gmr_ids); 516fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO("Max GMR descriptors is %u\n", 517fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz (unsigned)dev_priv->max_gmr_descriptors); 518fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 519fb17f18993071cc230ec8ddb6dd3dd9932d2dba2Thomas Hellstrom if (dev_priv->capabilities & SVGA_CAP_GMR2) { 520fb17f18993071cc230ec8ddb6dd3dd9932d2dba2Thomas Hellstrom DRM_INFO("Max number of GMR pages is %u\n", 521fb17f18993071cc230ec8ddb6dd3dd9932d2dba2Thomas Hellstrom (unsigned)dev_priv->max_gmr_pages); 5225bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom DRM_INFO("Max dedicated hypervisor surface memory is %u kiB\n", 5235bb39e818169783ee17ddbbefbd7bd16a4383fecThomas Hellstrom (unsigned)dev_priv->memory_size / 1024); 524fb17f18993071cc230ec8ddb6dd3dd9932d2dba2Thomas Hellstrom } 525fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO("VRAM at 0x%08x size is %u kiB\n", 526fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->vram_start, dev_priv->vram_size / 1024); 527fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO("MMIO at 0x%08x size is %u kiB\n", 528fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->mmio_start, dev_priv->mmio_size / 1024); 529fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 530fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ret = vmw_ttm_global_init(dev_priv); 531fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(ret != 0)) 532fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz goto out_err0; 533fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 534fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 535fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz vmw_master_init(&dev_priv->fbdev_master); 536fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); 537fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->active_master = &dev_priv->fbdev_master; 538fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 539a2c06ee2fe5b48a71e697bae00c6e7195fc016b6Dave Airlie 540fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ret = ttm_bo_device_init(&dev_priv->bdev, 541fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->bo_global_ref.ref.object, 542fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz &vmw_bo_driver, VMWGFX_FILE_PAGE_OFFSET, 543fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz false); 544fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(ret != 0)) { 545fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_ERROR("Failed initializing TTM buffer object driver.\n"); 546fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz goto out_err1; 547fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 548fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 549fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ret = ttm_bo_init_mm(&dev_priv->bdev, TTM_PL_VRAM, 550fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz (dev_priv->vram_size >> PAGE_SHIFT)); 551fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(ret != 0)) { 552fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_ERROR("Failed initializing memory manager for VRAM.\n"); 553fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz goto out_err2; 554fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 555fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 556135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom dev_priv->has_gmr = true; 557135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom if (ttm_bo_init_mm(&dev_priv->bdev, VMW_PL_GMR, 558135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom dev_priv->max_gmr_ids) != 0) { 559135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom DRM_INFO("No GMR memory available. " 560135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom "Graphics memory resources are very limited.\n"); 561135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom dev_priv->has_gmr = false; 562135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom } 563135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom 564fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->mmio_mtrr = drm_mtrr_add(dev_priv->mmio_start, 565fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->mmio_size, DRM_MTRR_WC); 566fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 567fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->mmio_virt = ioremap_wc(dev_priv->mmio_start, 568fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->mmio_size); 569fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 570fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(dev_priv->mmio_virt == NULL)) { 571fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ret = -ENOMEM; 572fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_ERROR("Failed mapping MMIO.\n"); 573fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz goto out_err3; 574fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 575fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 576d7e1958dbe4a7b81d4cab5fab545a068501b967eJakob Bornecrantz /* Need mmio memory to check for fifo pitchlock cap. */ 577d7e1958dbe4a7b81d4cab5fab545a068501b967eJakob Bornecrantz if (!(dev_priv->capabilities & SVGA_CAP_DISPLAY_TOPOLOGY) && 578d7e1958dbe4a7b81d4cab5fab545a068501b967eJakob Bornecrantz !(dev_priv->capabilities & SVGA_CAP_PITCHLOCK) && 579d7e1958dbe4a7b81d4cab5fab545a068501b967eJakob Bornecrantz !vmw_fifo_have_pitchlock(dev_priv)) { 580d7e1958dbe4a7b81d4cab5fab545a068501b967eJakob Bornecrantz ret = -ENOSYS; 581d7e1958dbe4a7b81d4cab5fab545a068501b967eJakob Bornecrantz DRM_ERROR("Hardware has no pitchlock\n"); 582d7e1958dbe4a7b81d4cab5fab545a068501b967eJakob Bornecrantz goto out_err4; 583d7e1958dbe4a7b81d4cab5fab545a068501b967eJakob Bornecrantz } 584d7e1958dbe4a7b81d4cab5fab545a068501b967eJakob Bornecrantz 585fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->tdev = ttm_object_device_init 586fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz (dev_priv->mem_global_ref.object, 12); 587fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 588fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(dev_priv->tdev == NULL)) { 589fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_ERROR("Unable to initialize TTM object management.\n"); 590fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ret = -ENOMEM; 591fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz goto out_err4; 592fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 593fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 594fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev->dev_private = dev_priv; 595fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 596fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ret = pci_request_regions(dev->pdev, "vmwgfx probe"); 597fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->stealth = (ret != 0); 598fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (dev_priv->stealth) { 599fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz /** 600fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * Request at least the mmio PCI resource. 601fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz */ 602fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 603fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_INFO("It appears like vesafb is loaded. " 604f2d12b8e2c05e86b1a2070efcc07f1b8a79afb4cThomas Hellstrom "Ignore above error if any.\n"); 605fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ret = pci_request_region(dev->pdev, 2, "vmwgfx stealth probe"); 606fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(ret != 0)) { 607fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_ERROR("Failed reserving the SVGA MMIO resource.\n"); 608fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz goto out_no_device; 609fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 610fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 611ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom 612ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom dev_priv->fman = vmw_fence_manager_init(dev_priv); 613ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom if (unlikely(dev_priv->fman == NULL)) 614ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom goto out_no_fman; 61556d1c78df52323cdcd937505dccaa5d665dfab97Jakob Bornecrantz 61656d1c78df52323cdcd937505dccaa5d665dfab97Jakob Bornecrantz /* Need to start the fifo to check if we can do screen objects */ 61756d1c78df52323cdcd937505dccaa5d665dfab97Jakob Bornecrantz ret = vmw_3d_resource_inc(dev_priv, true); 61856d1c78df52323cdcd937505dccaa5d665dfab97Jakob Bornecrantz if (unlikely(ret != 0)) 61956d1c78df52323cdcd937505dccaa5d665dfab97Jakob Bornecrantz goto out_no_fifo; 62056d1c78df52323cdcd937505dccaa5d665dfab97Jakob Bornecrantz vmw_kms_save_vga(dev_priv); 62156d1c78df52323cdcd937505dccaa5d665dfab97Jakob Bornecrantz 62256d1c78df52323cdcd937505dccaa5d665dfab97Jakob Bornecrantz /* Start kms and overlay systems, needs fifo. */ 6237a1c2f6c8d8485af5ac6c2a313f6a7162207a4afThomas Hellstrom ret = vmw_kms_init(dev_priv); 6247a1c2f6c8d8485af5ac6c2a313f6a7162207a4afThomas Hellstrom if (unlikely(ret != 0)) 6257a1c2f6c8d8485af5ac6c2a313f6a7162207a4afThomas Hellstrom goto out_no_kms; 626f2d12b8e2c05e86b1a2070efcc07f1b8a79afb4cThomas Hellstrom vmw_overlay_init(dev_priv); 62756d1c78df52323cdcd937505dccaa5d665dfab97Jakob Bornecrantz 62801e81419ce66c312db6855b5cb26cd50eb9a9b8bJakob Bornecrantz /* 3D Depends on Screen Objects being used. */ 6296ea77d1384ed0c2d040a1934ecc3fd7187580931Thomas Hellstrom DRM_INFO("Detected %sdevice 3D availability.\n", 6306ea77d1384ed0c2d040a1934ecc3fd7187580931Thomas Hellstrom vmw_fifo_have_3d(dev_priv) ? 6316ea77d1384ed0c2d040a1934ecc3fd7187580931Thomas Hellstrom "" : "no "); 63201e81419ce66c312db6855b5cb26cd50eb9a9b8bJakob Bornecrantz 63356d1c78df52323cdcd937505dccaa5d665dfab97Jakob Bornecrantz /* We might be done with the fifo now */ 63430c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom if (dev_priv->enable_fb) { 63530c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom vmw_fb_init(dev_priv); 63630c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom } else { 63756d1c78df52323cdcd937505dccaa5d665dfab97Jakob Bornecrantz vmw_kms_restore_vga(dev_priv); 63856d1c78df52323cdcd937505dccaa5d665dfab97Jakob Bornecrantz vmw_3d_resource_dec(dev_priv, true); 63930c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom } 640fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 6417a1c2f6c8d8485af5ac6c2a313f6a7162207a4afThomas Hellstrom if (dev_priv->capabilities & SVGA_CAP_IRQMASK) { 6427a1c2f6c8d8485af5ac6c2a313f6a7162207a4afThomas Hellstrom ret = drm_irq_install(dev); 6437a1c2f6c8d8485af5ac6c2a313f6a7162207a4afThomas Hellstrom if (unlikely(ret != 0)) { 6447a1c2f6c8d8485af5ac6c2a313f6a7162207a4afThomas Hellstrom DRM_ERROR("Failed installing irq: %d\n", ret); 6457a1c2f6c8d8485af5ac6c2a313f6a7162207a4afThomas Hellstrom goto out_no_irq; 6467a1c2f6c8d8485af5ac6c2a313f6a7162207a4afThomas Hellstrom } 6477a1c2f6c8d8485af5ac6c2a313f6a7162207a4afThomas Hellstrom } 6487a1c2f6c8d8485af5ac6c2a313f6a7162207a4afThomas Hellstrom 649d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom dev_priv->pm_nb.notifier_call = vmwgfx_pm_notifier; 650d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom register_pm_notifier(&dev_priv->pm_nb); 651d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom 652fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return 0; 653fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 6547a1c2f6c8d8485af5ac6c2a313f6a7162207a4afThomas Hellstromout_no_irq: 65556d1c78df52323cdcd937505dccaa5d665dfab97Jakob Bornecrantz if (dev_priv->enable_fb) 6567a1c2f6c8d8485af5ac6c2a313f6a7162207a4afThomas Hellstrom vmw_fb_close(dev_priv); 65756d1c78df52323cdcd937505dccaa5d665dfab97Jakob Bornecrantz vmw_overlay_close(dev_priv); 65856d1c78df52323cdcd937505dccaa5d665dfab97Jakob Bornecrantz vmw_kms_close(dev_priv); 65956d1c78df52323cdcd937505dccaa5d665dfab97Jakob Bornecrantzout_no_kms: 66056d1c78df52323cdcd937505dccaa5d665dfab97Jakob Bornecrantz /* We still have a 3D resource reference held */ 66156d1c78df52323cdcd937505dccaa5d665dfab97Jakob Bornecrantz if (dev_priv->enable_fb) { 6627a1c2f6c8d8485af5ac6c2a313f6a7162207a4afThomas Hellstrom vmw_kms_restore_vga(dev_priv); 66305730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom vmw_3d_resource_dec(dev_priv, false); 6647a1c2f6c8d8485af5ac6c2a313f6a7162207a4afThomas Hellstrom } 66530c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstromout_no_fifo: 666ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom vmw_fence_manager_takedown(dev_priv->fman); 667ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstromout_no_fman: 66830c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom if (dev_priv->stealth) 66930c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom pci_release_region(dev->pdev, 2); 67030c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom else 67130c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom pci_release_regions(dev->pdev); 672fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzout_no_device: 673fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ttm_object_device_release(&dev_priv->tdev); 674fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzout_err4: 675fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz iounmap(dev_priv->mmio_virt); 676fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzout_err3: 677fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, 678fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->mmio_size, DRM_MTRR_WC); 679135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom if (dev_priv->has_gmr) 680135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom (void) ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR); 681fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM); 682fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzout_err2: 683fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz (void)ttm_bo_device_release(&dev_priv->bdev); 684fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzout_err1: 685fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz vmw_ttm_global_release(dev_priv); 686fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzout_err0: 687fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz idr_destroy(&dev_priv->surface_idr); 688fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz idr_destroy(&dev_priv->context_idr); 689fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz idr_destroy(&dev_priv->stream_idr); 690fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz kfree(dev_priv); 691fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return ret; 692fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 693fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 694fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_driver_unload(struct drm_device *dev) 695fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 696fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_private *dev_priv = vmw_priv(dev); 697fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 698d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom unregister_pm_notifier(&dev_priv->pm_nb); 699d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom 700be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom if (dev_priv->ctx.cmd_bounce) 701be38ab6ea7b0de0542a0ff78690d63bb22f66a4dThomas Hellstrom vfree(dev_priv->ctx.cmd_bounce); 7027a1c2f6c8d8485af5ac6c2a313f6a7162207a4afThomas Hellstrom if (dev_priv->capabilities & SVGA_CAP_IRQMASK) 7037a1c2f6c8d8485af5ac6c2a313f6a7162207a4afThomas Hellstrom drm_irq_uninstall(dev_priv->dev); 70430c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom if (dev_priv->enable_fb) { 70530c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom vmw_fb_close(dev_priv); 70630c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom vmw_kms_restore_vga(dev_priv); 70705730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom vmw_3d_resource_dec(dev_priv, false); 70830c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom } 709f2d12b8e2c05e86b1a2070efcc07f1b8a79afb4cThomas Hellstrom vmw_kms_close(dev_priv); 710f2d12b8e2c05e86b1a2070efcc07f1b8a79afb4cThomas Hellstrom vmw_overlay_close(dev_priv); 711ae2a104058e217548215bfe6c6c8a98752139c29Thomas Hellstrom vmw_fence_manager_takedown(dev_priv->fman); 712f2d12b8e2c05e86b1a2070efcc07f1b8a79afb4cThomas Hellstrom if (dev_priv->stealth) 713fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz pci_release_region(dev->pdev, 2); 714f2d12b8e2c05e86b1a2070efcc07f1b8a79afb4cThomas Hellstrom else 715f2d12b8e2c05e86b1a2070efcc07f1b8a79afb4cThomas Hellstrom pci_release_regions(dev->pdev); 716f2d12b8e2c05e86b1a2070efcc07f1b8a79afb4cThomas Hellstrom 717fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ttm_object_device_release(&dev_priv->tdev); 718fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz iounmap(dev_priv->mmio_virt); 719fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz drm_mtrr_del(dev_priv->mmio_mtrr, dev_priv->mmio_start, 720fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->mmio_size, DRM_MTRR_WC); 721135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom if (dev_priv->has_gmr) 722135cba0dc399fdd47bd3ae305c1db75fcd77243fThomas Hellstrom (void)ttm_bo_clean_mm(&dev_priv->bdev, VMW_PL_GMR); 723fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz (void)ttm_bo_clean_mm(&dev_priv->bdev, TTM_PL_VRAM); 724fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz (void)ttm_bo_device_release(&dev_priv->bdev); 725fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz vmw_ttm_global_release(dev_priv); 726fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz idr_destroy(&dev_priv->surface_idr); 727fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz idr_destroy(&dev_priv->context_idr); 728fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz idr_destroy(&dev_priv->stream_idr); 729fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 730fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz kfree(dev_priv); 731fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 732fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return 0; 733fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 734fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 7356b82ef50d8617f3fcd51dda9d89d973fe3bc65b8Thomas Hellstromstatic void vmw_preclose(struct drm_device *dev, 7366b82ef50d8617f3fcd51dda9d89d973fe3bc65b8Thomas Hellstrom struct drm_file *file_priv) 7376b82ef50d8617f3fcd51dda9d89d973fe3bc65b8Thomas Hellstrom{ 7386b82ef50d8617f3fcd51dda9d89d973fe3bc65b8Thomas Hellstrom struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); 7396b82ef50d8617f3fcd51dda9d89d973fe3bc65b8Thomas Hellstrom struct vmw_private *dev_priv = vmw_priv(dev); 7406b82ef50d8617f3fcd51dda9d89d973fe3bc65b8Thomas Hellstrom 7416b82ef50d8617f3fcd51dda9d89d973fe3bc65b8Thomas Hellstrom vmw_event_fence_fpriv_gone(dev_priv->fman, &vmw_fp->fence_events); 7426b82ef50d8617f3fcd51dda9d89d973fe3bc65b8Thomas Hellstrom} 7436b82ef50d8617f3fcd51dda9d89d973fe3bc65b8Thomas Hellstrom 744fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic void vmw_postclose(struct drm_device *dev, 745fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_file *file_priv) 746fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 747fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_fpriv *vmw_fp; 748fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 749fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz vmw_fp = vmw_fpriv(file_priv); 750fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ttm_object_file_release(&vmw_fp->tfile); 751fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (vmw_fp->locked_master) 752fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz drm_master_put(&vmw_fp->locked_master); 753fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz kfree(vmw_fp); 754fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 755fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 756fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_driver_open(struct drm_device *dev, struct drm_file *file_priv) 757fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 758fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_private *dev_priv = vmw_priv(dev); 759fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_fpriv *vmw_fp; 760fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz int ret = -ENOMEM; 761fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 762fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz vmw_fp = kzalloc(sizeof(*vmw_fp), GFP_KERNEL); 763fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(vmw_fp == NULL)) 764fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return ret; 765fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 7666b82ef50d8617f3fcd51dda9d89d973fe3bc65b8Thomas Hellstrom INIT_LIST_HEAD(&vmw_fp->fence_events); 767fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz vmw_fp->tfile = ttm_object_file_init(dev_priv->tdev, 10); 768fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(vmw_fp->tfile == NULL)) 769fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz goto out_no_tfile; 770fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 771fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz file_priv->driver_priv = vmw_fp; 772fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 773fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(dev_priv->bdev.dev_mapping == NULL)) 774fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->bdev.dev_mapping = 775fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz file_priv->filp->f_path.dentry->d_inode->i_mapping; 776fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 777fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return 0; 778fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 779fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzout_no_tfile: 780fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz kfree(vmw_fp); 781fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return ret; 782fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 783fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 784fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic long vmw_unlocked_ioctl(struct file *filp, unsigned int cmd, 785fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz unsigned long arg) 786fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 787fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_file *file_priv = filp->private_data; 788fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_device *dev = file_priv->minor->dev; 789fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz unsigned int nr = DRM_IOCTL_NR(cmd); 790fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 791fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz /* 792e1f7800315d78686481b27b113a3317ac687b6bfThomas Hellstrom * Do extra checking on driver private ioctls. 793fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz */ 794fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 795fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) 796fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz && (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls)) { 797fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_ioctl_desc *ioctl = 798fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz &vmw_ioctls[nr - DRM_COMMAND_BASE]; 799fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 8002854eedae2ff35d95e8923bebdb942bbd537c54fThomas Hellstrom if (unlikely(ioctl->cmd_drv != cmd)) { 801fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_ERROR("Invalid command format, ioctl %d\n", 802fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz nr - DRM_COMMAND_BASE); 803fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return -EINVAL; 804fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 805fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 806fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 807e1f7800315d78686481b27b113a3317ac687b6bfThomas Hellstrom return drm_ioctl(filp, cmd, arg); 808fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 809fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 810fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_firstopen(struct drm_device *dev) 811fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 812fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_private *dev_priv = vmw_priv(dev); 813fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->is_opened = true; 814fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 815fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return 0; 816fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 817fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 818fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic void vmw_lastclose(struct drm_device *dev) 819fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 820fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_private *dev_priv = vmw_priv(dev); 821fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_crtc *crtc; 822fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_mode_set set; 823fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz int ret; 824fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 825fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz /** 826fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * Do nothing on the lastclose call from drm_unload. 827fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz */ 828fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 829fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (!dev_priv->is_opened) 830fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return; 831fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 832fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->is_opened = false; 833fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz set.x = 0; 834fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz set.y = 0; 835fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz set.fb = NULL; 836fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz set.mode = NULL; 837fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz set.connectors = NULL; 838fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz set.num_connectors = 0; 839fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 840fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { 841fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz set.crtc = crtc; 842fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ret = crtc->funcs->set_config(&set); 843fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz WARN_ON(ret != 0); 844fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 845fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 846fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 847fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 848fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic void vmw_master_init(struct vmw_master *vmaster) 849fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 850fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ttm_lock_init(&vmaster->lock); 8513a939a5ece3030e60c966a885c8e9bd329c4faf7Thomas Hellstrom INIT_LIST_HEAD(&vmaster->fb_surf); 8523a939a5ece3030e60c966a885c8e9bd329c4faf7Thomas Hellstrom mutex_init(&vmaster->fb_surf_mutex); 853fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 854fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 855fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_master_create(struct drm_device *dev, 856fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_master *master) 857fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 858fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_master *vmaster; 859fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 860fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz vmaster = kzalloc(sizeof(*vmaster), GFP_KERNEL); 861fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(vmaster == NULL)) 862fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return -ENOMEM; 863fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 8643a939a5ece3030e60c966a885c8e9bd329c4faf7Thomas Hellstrom vmw_master_init(vmaster); 865fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); 866fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz master->driver_priv = vmaster; 867fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 868fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return 0; 869fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 870fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 871fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic void vmw_master_destroy(struct drm_device *dev, 872fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_master *master) 873fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 874fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_master *vmaster = vmw_master(master); 875fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 876fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz master->driver_priv = NULL; 877fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz kfree(vmaster); 878fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 879fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 880fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 881fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_master_set(struct drm_device *dev, 882fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_file *file_priv, 883fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz bool from_open) 884fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 885fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_private *dev_priv = vmw_priv(dev); 886fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); 887fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_master *active = dev_priv->active_master; 888fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_master *vmaster = vmw_master(file_priv->master); 889fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz int ret = 0; 890fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 89130c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom if (!dev_priv->enable_fb) { 89205730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom ret = vmw_3d_resource_inc(dev_priv, true); 89330c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom if (unlikely(ret != 0)) 89430c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom return ret; 89530c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom vmw_kms_save_vga(dev_priv); 89630c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom mutex_lock(&dev_priv->hw_mutex); 89730c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom vmw_write(dev_priv, SVGA_REG_TRACES, 0); 89830c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom mutex_unlock(&dev_priv->hw_mutex); 89930c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom } 90030c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom 901fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (active) { 902fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz BUG_ON(active != &dev_priv->fbdev_master); 903fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ret = ttm_vt_lock(&active->lock, false, vmw_fp->tfile); 904fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(ret != 0)) 905fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz goto out_no_active_lock; 906fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 907fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ttm_lock_set_kill(&active->lock, true, SIGTERM); 908fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM); 909fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely(ret != 0)) { 910fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_ERROR("Unable to clean VRAM on " 911fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz "master drop.\n"); 912fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 913fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 914fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->active_master = NULL; 915fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 916fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 917fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ttm_lock_set_kill(&vmaster->lock, false, SIGTERM); 918fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (!from_open) { 919fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ttm_vt_unlock(&vmaster->lock); 920fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz BUG_ON(vmw_fp->locked_master != file_priv->master); 921fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz drm_master_put(&vmw_fp->locked_master); 922fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 923fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 924fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->active_master = vmaster; 925fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 926fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return 0; 927fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 928fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzout_no_active_lock: 92930c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom if (!dev_priv->enable_fb) { 93030c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom mutex_lock(&dev_priv->hw_mutex); 93130c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom vmw_write(dev_priv, SVGA_REG_TRACES, 1); 93230c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom mutex_unlock(&dev_priv->hw_mutex); 93330c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom vmw_kms_restore_vga(dev_priv); 93405730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom vmw_3d_resource_dec(dev_priv, true); 93530c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom } 936fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return ret; 937fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 938fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 939fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic void vmw_master_drop(struct drm_device *dev, 940fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_file *file_priv, 941fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz bool from_release) 942fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 943fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_private *dev_priv = vmw_priv(dev); 944fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); 945fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct vmw_master *vmaster = vmw_master(file_priv->master); 946fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz int ret; 947fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 948fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz /** 949fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * Make sure the master doesn't disappear while we have 950fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz * it locked. 951fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz */ 952fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 953fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz vmw_fp->locked_master = drm_master_get(file_priv->master); 954fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ret = ttm_vt_lock(&vmaster->lock, false, vmw_fp->tfile); 955e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom vmw_execbuf_release_pinned_bo(dev_priv, false, 0); 956e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom 957fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (unlikely((ret != 0))) { 958fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_ERROR("Unable to lock TTM at VT switch.\n"); 959fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz drm_master_put(&vmw_fp->locked_master); 960fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz } 961fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 962fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ttm_lock_set_kill(&vmaster->lock, true, SIGTERM); 963fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 96430c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom if (!dev_priv->enable_fb) { 96530c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom ret = ttm_bo_evict_mm(&dev_priv->bdev, TTM_PL_VRAM); 96630c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom if (unlikely(ret != 0)) 96730c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom DRM_ERROR("Unable to clean VRAM on master drop.\n"); 96830c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom mutex_lock(&dev_priv->hw_mutex); 96930c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom vmw_write(dev_priv, SVGA_REG_TRACES, 1); 97030c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom mutex_unlock(&dev_priv->hw_mutex); 97130c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom vmw_kms_restore_vga(dev_priv); 97205730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom vmw_3d_resource_dec(dev_priv, true); 97330c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom } 97430c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom 975fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz dev_priv->active_master = &dev_priv->fbdev_master; 976fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ttm_lock_set_kill(&dev_priv->fbdev_master.lock, false, SIGTERM); 977fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz ttm_vt_unlock(&dev_priv->fbdev_master.lock); 978fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 97930c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom if (dev_priv->enable_fb) 98030c78bb838b26ec7997515844c0c734e454b3cbaThomas Hellstrom vmw_fb_on(dev_priv); 981fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 982fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 983fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 984fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic void vmw_remove(struct pci_dev *pdev) 985fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 986fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz struct drm_device *dev = pci_get_drvdata(pdev); 987fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 988fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz drm_put_dev(dev); 989fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 990fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 991d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstromstatic int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, 992d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom void *ptr) 993d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom{ 994d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom struct vmw_private *dev_priv = 995d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom container_of(nb, struct vmw_private, pm_nb); 996d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom struct vmw_master *vmaster = dev_priv->active_master; 997d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom 998d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom switch (val) { 999d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom case PM_HIBERNATION_PREPARE: 1000d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom case PM_SUSPEND_PREPARE: 1001d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom ttm_suspend_lock(&vmaster->lock); 1002d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom 1003d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom /** 1004d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom * This empties VRAM and unbinds all GMR bindings. 1005d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom * Buffer contents is moved to swappable memory. 1006d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom */ 1007e2fa3a76839ada0d788549607263a036aa654243Thomas Hellstrom vmw_execbuf_release_pinned_bo(dev_priv, false, 0); 1008d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom ttm_bo_swapout_all(&dev_priv->bdev); 1009094e0fa8b96c9fab5df9597e728d82f3d87ee471Thomas Hellstrom 1010d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom break; 1011d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom case PM_POST_HIBERNATION: 1012d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom case PM_POST_SUSPEND: 1013094e0fa8b96c9fab5df9597e728d82f3d87ee471Thomas Hellstrom case PM_POST_RESTORE: 1014d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom ttm_suspend_unlock(&vmaster->lock); 1015094e0fa8b96c9fab5df9597e728d82f3d87ee471Thomas Hellstrom 1016d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom break; 1017d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom case PM_RESTORE_PREPARE: 1018d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom break; 1019d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom default: 1020d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom break; 1021d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom } 1022d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom return 0; 1023d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom} 1024d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom 1025d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom/** 1026d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom * These might not be needed with the virtual SVGA device. 1027d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom */ 1028d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom 10297fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstromstatic int vmw_pci_suspend(struct pci_dev *pdev, pm_message_t state) 1030d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom{ 1031094e0fa8b96c9fab5df9597e728d82f3d87ee471Thomas Hellstrom struct drm_device *dev = pci_get_drvdata(pdev); 1032094e0fa8b96c9fab5df9597e728d82f3d87ee471Thomas Hellstrom struct vmw_private *dev_priv = vmw_priv(dev); 1033094e0fa8b96c9fab5df9597e728d82f3d87ee471Thomas Hellstrom 1034094e0fa8b96c9fab5df9597e728d82f3d87ee471Thomas Hellstrom if (dev_priv->num_3d_resources != 0) { 1035094e0fa8b96c9fab5df9597e728d82f3d87ee471Thomas Hellstrom DRM_INFO("Can't suspend or hibernate " 1036094e0fa8b96c9fab5df9597e728d82f3d87ee471Thomas Hellstrom "while 3D resources are active.\n"); 1037094e0fa8b96c9fab5df9597e728d82f3d87ee471Thomas Hellstrom return -EBUSY; 1038094e0fa8b96c9fab5df9597e728d82f3d87ee471Thomas Hellstrom } 1039094e0fa8b96c9fab5df9597e728d82f3d87ee471Thomas Hellstrom 1040d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom pci_save_state(pdev); 1041d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom pci_disable_device(pdev); 1042d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom pci_set_power_state(pdev, PCI_D3hot); 1043d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom return 0; 1044d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom} 1045d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom 10467fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstromstatic int vmw_pci_resume(struct pci_dev *pdev) 1047d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom{ 1048d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom pci_set_power_state(pdev, PCI_D0); 1049d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom pci_restore_state(pdev); 1050d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom return pci_enable_device(pdev); 1051d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom} 1052d9f36a0051b7c0382107cb0342af1126a6eb627dThomas Hellstrom 10537fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstromstatic int vmw_pm_suspend(struct device *kdev) 10547fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom{ 10557fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom struct pci_dev *pdev = to_pci_dev(kdev); 10567fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom struct pm_message dummy; 10577fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom 10587fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom dummy.event = 0; 10597fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom 10607fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom return vmw_pci_suspend(pdev, dummy); 10617fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom} 10627fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom 10637fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstromstatic int vmw_pm_resume(struct device *kdev) 10647fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom{ 10657fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom struct pci_dev *pdev = to_pci_dev(kdev); 10667fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom 10677fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom return vmw_pci_resume(pdev); 10687fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom} 10697fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom 10707fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstromstatic int vmw_pm_prepare(struct device *kdev) 10717fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom{ 10727fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom struct pci_dev *pdev = to_pci_dev(kdev); 10737fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom struct drm_device *dev = pci_get_drvdata(pdev); 10747fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom struct vmw_private *dev_priv = vmw_priv(dev); 10757fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom 10767fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom /** 10777fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom * Release 3d reference held by fbdev and potentially 10787fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom * stop fifo. 10797fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom */ 10807fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom dev_priv->suspended = true; 10817fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom if (dev_priv->enable_fb) 108205730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom vmw_3d_resource_dec(dev_priv, true); 10837fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom 10847fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom if (dev_priv->num_3d_resources != 0) { 10857fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom 10867fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom DRM_INFO("Can't suspend or hibernate " 10877fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom "while 3D resources are active.\n"); 10887fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom 10897fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom if (dev_priv->enable_fb) 109005730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom vmw_3d_resource_inc(dev_priv, true); 10917fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom dev_priv->suspended = false; 10927fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom return -EBUSY; 10937fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom } 10947fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom 10957fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom return 0; 10967fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom} 10977fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom 10987fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstromstatic void vmw_pm_complete(struct device *kdev) 10997fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom{ 11007fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom struct pci_dev *pdev = to_pci_dev(kdev); 11017fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom struct drm_device *dev = pci_get_drvdata(pdev); 11027fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom struct vmw_private *dev_priv = vmw_priv(dev); 11037fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom 11047fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom /** 11057fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom * Reclaim 3d reference held by fbdev and potentially 11067fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom * start fifo. 11077fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom */ 11087fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom if (dev_priv->enable_fb) 110905730b32a78dab4bed8fb7ccc64c53d9fcf31e9dThomas Hellstrom vmw_3d_resource_inc(dev_priv, false); 11107fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom 11117fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom dev_priv->suspended = false; 11127fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom} 11137fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom 11147fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstromstatic const struct dev_pm_ops vmw_pm_ops = { 11157fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom .prepare = vmw_pm_prepare, 11167fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom .complete = vmw_pm_complete, 11177fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom .suspend = vmw_pm_suspend, 11187fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom .resume = vmw_pm_resume, 11197fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom}; 11207fbd721ad35f8ffec8d9a82e0e4b390cb6c9f4f7Thomas Hellstrom 1121e08e96de986ceb2c6b683df0bd0c4ddd4f91dcfdArjan van de Venstatic const struct file_operations vmwgfx_driver_fops = { 1122e08e96de986ceb2c6b683df0bd0c4ddd4f91dcfdArjan van de Ven .owner = THIS_MODULE, 1123e08e96de986ceb2c6b683df0bd0c4ddd4f91dcfdArjan van de Ven .open = drm_open, 1124e08e96de986ceb2c6b683df0bd0c4ddd4f91dcfdArjan van de Ven .release = drm_release, 1125e08e96de986ceb2c6b683df0bd0c4ddd4f91dcfdArjan van de Ven .unlocked_ioctl = vmw_unlocked_ioctl, 1126e08e96de986ceb2c6b683df0bd0c4ddd4f91dcfdArjan van de Ven .mmap = vmw_mmap, 1127e08e96de986ceb2c6b683df0bd0c4ddd4f91dcfdArjan van de Ven .poll = vmw_fops_poll, 1128e08e96de986ceb2c6b683df0bd0c4ddd4f91dcfdArjan van de Ven .read = vmw_fops_read, 1129e08e96de986ceb2c6b683df0bd0c4ddd4f91dcfdArjan van de Ven .fasync = drm_fasync, 1130e08e96de986ceb2c6b683df0bd0c4ddd4f91dcfdArjan van de Ven#if defined(CONFIG_COMPAT) 1131e08e96de986ceb2c6b683df0bd0c4ddd4f91dcfdArjan van de Ven .compat_ioctl = drm_compat_ioctl, 1132e08e96de986ceb2c6b683df0bd0c4ddd4f91dcfdArjan van de Ven#endif 1133e08e96de986ceb2c6b683df0bd0c4ddd4f91dcfdArjan van de Ven .llseek = noop_llseek, 1134e08e96de986ceb2c6b683df0bd0c4ddd4f91dcfdArjan van de Ven}; 1135e08e96de986ceb2c6b683df0bd0c4ddd4f91dcfdArjan van de Ven 1136fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic struct drm_driver driver = { 1137fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | 1138fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRIVER_MODESET, 1139fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .load = vmw_driver_load, 1140fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .unload = vmw_driver_unload, 1141fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .firstopen = vmw_firstopen, 1142fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .lastclose = vmw_lastclose, 1143fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .irq_preinstall = vmw_irq_preinstall, 1144fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .irq_postinstall = vmw_irq_postinstall, 1145fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .irq_uninstall = vmw_irq_uninstall, 1146fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .irq_handler = vmw_irq_handler, 11477a1c2f6c8d8485af5ac6c2a313f6a7162207a4afThomas Hellstrom .get_vblank_counter = vmw_get_vblank_counter, 11481c482ab3596b8ee4c635926b35ee88ad56ba2f9cJakob Bornecrantz .enable_vblank = vmw_enable_vblank, 11491c482ab3596b8ee4c635926b35ee88ad56ba2f9cJakob Bornecrantz .disable_vblank = vmw_disable_vblank, 1150fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .reclaim_buffers_locked = NULL, 1151fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .ioctls = vmw_ioctls, 1152fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .num_ioctls = DRM_ARRAY_SIZE(vmw_ioctls), 1153fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .dma_quiescent = NULL, /*vmw_dma_quiescent, */ 1154fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .master_create = vmw_master_create, 1155fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .master_destroy = vmw_master_destroy, 1156fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .master_set = vmw_master_set, 1157fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .master_drop = vmw_master_drop, 1158fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .open = vmw_driver_open, 11596b82ef50d8617f3fcd51dda9d89d973fe3bc65b8Thomas Hellstrom .preclose = vmw_preclose, 1160fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .postclose = vmw_postclose, 1161e08e96de986ceb2c6b683df0bd0c4ddd4f91dcfdArjan van de Ven .fops = &vmwgfx_driver_fops, 1162fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .name = VMWGFX_DRIVER_NAME, 1163fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .desc = VMWGFX_DRIVER_DESC, 1164fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .date = VMWGFX_DRIVER_DATE, 1165fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .major = VMWGFX_DRIVER_MAJOR, 1166fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .minor = VMWGFX_DRIVER_MINOR, 1167fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz .patchlevel = VMWGFX_DRIVER_PATCHLEVEL 1168fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz}; 1169fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 11708410ea3b95d105a5be5db501656f44bbb91197c1Dave Airliestatic struct pci_driver vmw_pci_driver = { 11718410ea3b95d105a5be5db501656f44bbb91197c1Dave Airlie .name = VMWGFX_DRIVER_NAME, 11728410ea3b95d105a5be5db501656f44bbb91197c1Dave Airlie .id_table = vmw_pci_id_list, 11738410ea3b95d105a5be5db501656f44bbb91197c1Dave Airlie .probe = vmw_probe, 11748410ea3b95d105a5be5db501656f44bbb91197c1Dave Airlie .remove = vmw_remove, 11758410ea3b95d105a5be5db501656f44bbb91197c1Dave Airlie .driver = { 11768410ea3b95d105a5be5db501656f44bbb91197c1Dave Airlie .pm = &vmw_pm_ops 11778410ea3b95d105a5be5db501656f44bbb91197c1Dave Airlie } 11788410ea3b95d105a5be5db501656f44bbb91197c1Dave Airlie}; 11798410ea3b95d105a5be5db501656f44bbb91197c1Dave Airlie 1180fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent) 1181fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 1182dcdb167402cbdca1d021bdfa5f63995ee0a79317Jordan Crouse return drm_get_pci_dev(pdev, ent, &driver); 1183fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 1184fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 1185fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic int __init vmwgfx_init(void) 1186fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 1187fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz int ret; 11888410ea3b95d105a5be5db501656f44bbb91197c1Dave Airlie ret = drm_pci_init(&driver, &vmw_pci_driver); 1189fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz if (ret) 1190fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz DRM_ERROR("Failed initializing DRM.\n"); 1191fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz return ret; 1192fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 1193fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 1194fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzstatic void __exit vmwgfx_exit(void) 1195fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz{ 11968410ea3b95d105a5be5db501656f44bbb91197c1Dave Airlie drm_pci_exit(&driver, &vmw_pci_driver); 1197fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz} 1198fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 1199fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzmodule_init(vmwgfx_init); 1200fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantzmodule_exit(vmwgfx_exit); 1201fb1d9738ca053ea8afa5e86af6463155f983b01cJakob Bornecrantz 1202fb1d9738ca053ea8afa5e86af6463155f983b01cJakob BornecrantzMODULE_AUTHOR("VMware Inc. and others"); 1203fb1d9738ca053ea8afa5e86af6463155f983b01cJakob BornecrantzMODULE_DESCRIPTION("Standalone drm driver for the VMware SVGA device"); 1204fb1d9738ca053ea8afa5e86af6463155f983b01cJakob BornecrantzMODULE_LICENSE("GPL and additional rights"); 120573558ead6467f0590fe58a03a16a94d2a934178bThomas HellstromMODULE_VERSION(__stringify(VMWGFX_DRIVER_MAJOR) "." 120673558ead6467f0590fe58a03a16a94d2a934178bThomas Hellstrom __stringify(VMWGFX_DRIVER_MINOR) "." 120773558ead6467f0590fe58a03a16a94d2a934178bThomas Hellstrom __stringify(VMWGFX_DRIVER_PATCHLEVEL) "." 120873558ead6467f0590fe58a03a16a94d2a934178bThomas Hellstrom "0"); 1209