1 /* 2 * Copyright 2007 Intel Corporation 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice (including the next 12 * paragraph) shall be included in all copies or substantial portions of the 13 * Software. 14 * 15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 * SOFTWARE. 22 * 23 * Authors: 24 * Zhenyu Wang <zhenyu.z.wang (at) intel.com> 25 * 26 */ 27 #ifdef HAVE_CONFIG_H 28 #include "config.h" 29 #endif 30 31 #define _INTEL_XVMC_SERVER_ 32 #include "i830.h" 33 #include "i830_hwmc.h" 34 35 struct intel_xvmc_driver *xvmc_driver; 36 37 /* set global current driver for xvmc */ 38 static Bool intel_xvmc_set_driver(struct intel_xvmc_driver *d) 39 { 40 if (xvmc_driver) { 41 ErrorF("XvMC driver already set!\n"); 42 return FALSE; 43 } else 44 xvmc_driver = d; 45 return TRUE; 46 } 47 48 /* check chip type and load xvmc driver */ 49 /* This must be first called! */ 50 Bool intel_xvmc_probe(ScrnInfoPtr pScrn) 51 { 52 I830Ptr pI830 = I830PTR(pScrn); 53 Bool ret = FALSE; 54 55 if (!pI830->XvMCEnabled) 56 return FALSE; 57 58 if (pI830->use_drm_mode && 59 (IS_I915G(pI830) || IS_I915GM(pI830))) 60 return FALSE; 61 62 if (IS_I9XX(pI830)) { 63 if (IS_I915(pI830)) 64 ret = intel_xvmc_set_driver(&i915_xvmc_driver); 65 else if (IS_G4X(pI830) || IS_IGDNG(pI830)) 66 ret = intel_xvmc_set_driver(&vld_xvmc_driver); 67 else 68 ret = intel_xvmc_set_driver(&i965_xvmc_driver); 69 } else { 70 ErrorF("Your chipset doesn't support XvMC.\n"); 71 return FALSE; 72 } 73 return TRUE; 74 } 75 76 void intel_xvmc_finish(ScrnInfoPtr pScrn) 77 { 78 if (!xvmc_driver) 79 return; 80 (*xvmc_driver->fini)(pScrn); 81 } 82 83 Bool intel_xvmc_driver_init(ScreenPtr pScreen, XF86VideoAdaptorPtr xv_adaptor) 84 { 85 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 86 I830Ptr pI830 = I830PTR(pScrn); 87 struct drm_i915_setparam sp; 88 int ret; 89 90 if (!xvmc_driver) { 91 ErrorF("Failed to probe XvMC driver.\n"); 92 return FALSE; 93 } 94 95 if (!(*xvmc_driver->init)(pScrn, xv_adaptor)) { 96 ErrorF("XvMC driver initialize failed.\n"); 97 return FALSE; 98 } 99 100 /* Currently XvMC uses batchbuffer */ 101 sp.param = I915_SETPARAM_ALLOW_BATCHBUFFER; 102 sp.value = 1; 103 ret = drmCommandWrite(pI830->drmSubFD, DRM_I915_SETPARAM, 104 &sp, sizeof(sp)); 105 if (ret == 0) 106 return TRUE; 107 108 return FALSE; 109 } 110 111 Bool intel_xvmc_screen_init(ScreenPtr pScreen) 112 { 113 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 114 I830Ptr pI830 = I830PTR(pScrn); 115 char buf[64]; 116 117 if (!xvmc_driver) 118 return FALSE; 119 120 if (xf86XvMCScreenInit(pScreen, 1, &xvmc_driver->adaptor)) { 121 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 122 "[XvMC] %s driver initialized.\n", 123 xvmc_driver->name); 124 } else { 125 intel_xvmc_finish(pScrn); 126 pI830->XvMCEnabled = FALSE; 127 xf86DrvMsg(pScrn->scrnIndex, X_INFO, 128 "[XvMC] Failed to initialize XvMC.\n"); 129 return FALSE; 130 } 131 132 sprintf(buf, "pci:%04x:%02x:%02x.%d", 133 pI830->PciInfo->domain, 134 pI830->PciInfo->bus, 135 pI830->PciInfo->dev, 136 pI830->PciInfo->func); 137 138 xf86XvMCRegisterDRInfo(pScreen, INTEL_XVMC_LIBNAME, 139 buf, 140 INTEL_XVMC_MAJOR, INTEL_XVMC_MINOR, INTEL_XVMC_PATCHLEVEL); 141 return TRUE; 142 } 143 144 Bool intel_xvmc_init_batch(ScrnInfoPtr pScrn) 145 { 146 I830Ptr pI830 = I830PTR(pScrn); 147 int size = KB(64); 148 149 if (!i830_allocate_xvmc_buffer(pScrn, "[XvMC] batch buffer", 150 &(xvmc_driver->batch), size, 151 ALIGN_BOTH_ENDS)) 152 return FALSE; 153 154 if (drmAddMap(pI830->drmSubFD, 155 (drm_handle_t)(xvmc_driver->batch->offset+pI830->LinearAddr), 156 xvmc_driver->batch->size, DRM_AGP, 0, 157 &xvmc_driver->batch_handle) < 0) { 158 xf86DrvMsg(pScrn->scrnIndex, X_ERROR, 159 "[drm] drmAddMap(batchbuffer_handle) failed!\n"); 160 return FALSE; 161 } 162 return TRUE; 163 } 164 165 void intel_xvmc_fini_batch(ScrnInfoPtr pScrn) 166 { 167 I830Ptr pI830 = I830PTR(pScrn); 168 169 if (xvmc_driver->batch_handle) { 170 drmRmMap(pI830->drmSubFD, xvmc_driver->batch_handle); 171 xvmc_driver->batch_handle = 0; 172 } 173 if (xvmc_driver->batch) { 174 i830_free_xvmc_buffer(pScrn, xvmc_driver->batch); 175 xvmc_driver->batch = NULL; 176 } 177 } 178