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