1ae115bc7Smrj /* BEGIN CSTYLED */
2ae115bc7Smrj
3ae115bc7Smrj /* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
4ae115bc7Smrj */
5e92e3a86Szw161486 /*
6ae115bc7Smrj * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
70035d21cSmiao chen - Sun Microsystems - Beijing China * Copyright (c) 2009, Intel Corporation.
8ae115bc7Smrj * All Rights Reserved.
9ae115bc7Smrj *
10ae115bc7Smrj * Permission is hereby granted, free of charge, to any person obtaining a
11ae115bc7Smrj * copy of this software and associated documentation files (the
12ae115bc7Smrj * "Software"), to deal in the Software without restriction, including
13ae115bc7Smrj * without limitation the rights to use, copy, modify, merge, publish,
14ae115bc7Smrj * distribute, sub license, and/or sell copies of the Software, and to
15ae115bc7Smrj * permit persons to whom the Software is furnished to do so, subject to
16ae115bc7Smrj * the following conditions:
17ae115bc7Smrj *
18ae115bc7Smrj * The above copyright notice and this permission notice (including the
19ae115bc7Smrj * next paragraph) shall be included in all copies or substantial portions
20ae115bc7Smrj * of the Software.
21ae115bc7Smrj *
22ae115bc7Smrj * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
23ae115bc7Smrj * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24ae115bc7Smrj * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
25ae115bc7Smrj * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
26ae115bc7Smrj * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
27ae115bc7Smrj * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28ae115bc7Smrj * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29ae115bc7Smrj *
30e92e3a86Szw161486 */
31e92e3a86Szw161486
32e92e3a86Szw161486 /*
33d0231070Smiao chen - Sun Microsystems - Beijing China * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
34e92e3a86Szw161486 * Use is subject to license terms.
35e92e3a86Szw161486 */
36ae115bc7Smrj
37ae115bc7Smrj #include "drmP.h"
38ae115bc7Smrj #include "drm.h"
39ae115bc7Smrj #include "i915_drm.h"
40ae115bc7Smrj #include "i915_drv.h"
41ae115bc7Smrj
42dc8c6b69Sms148562
43e92e3a86Szw161486
44ae115bc7Smrj /* Really want an OS-independent resettable timer. Would like to have
45ae115bc7Smrj * this loop run for (eg) 3 sec, but have the timer reset every time
46ae115bc7Smrj * the head pointer changes, so that EBUSY only happens if the ring
47ae115bc7Smrj * actually stalls for (eg) 3 seconds.
48ae115bc7Smrj */
49ae115bc7Smrj /*ARGSUSED*/
i915_wait_ring(drm_device_t * dev,int n,const char * caller)50ae115bc7Smrj int i915_wait_ring(drm_device_t * dev, int n, const char *caller)
51ae115bc7Smrj {
52ae115bc7Smrj drm_i915_private_t *dev_priv = dev->dev_private;
53ae115bc7Smrj drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
54d0231070Smiao chen - Sun Microsystems - Beijing China u32 last_head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
55d0231070Smiao chen - Sun Microsystems - Beijing China u32 acthd_reg = IS_I965G(dev) ? ACTHD_I965 : ACTHD;
56d0231070Smiao chen - Sun Microsystems - Beijing China u32 last_acthd = I915_READ(acthd_reg);
57d0231070Smiao chen - Sun Microsystems - Beijing China u32 acthd;
58ae115bc7Smrj int i;
59ae115bc7Smrj
60d0231070Smiao chen - Sun Microsystems - Beijing China for (i = 0; i < 100000; i++) {
61d0231070Smiao chen - Sun Microsystems - Beijing China ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
62d0231070Smiao chen - Sun Microsystems - Beijing China acthd = I915_READ(acthd_reg);
63ae115bc7Smrj ring->space = ring->head - (ring->tail + 8);
64ae115bc7Smrj if (ring->space < 0)
65ae115bc7Smrj ring->space += ring->Size;
66ae115bc7Smrj if (ring->space >= n)
67ae115bc7Smrj return 0;
68ae115bc7Smrj
69ae115bc7Smrj if (ring->head != last_head)
70ae115bc7Smrj i = 0;
71ae115bc7Smrj
72d0231070Smiao chen - Sun Microsystems - Beijing China if (acthd != last_acthd)
73d0231070Smiao chen - Sun Microsystems - Beijing China i = 0;
74d0231070Smiao chen - Sun Microsystems - Beijing China
75ae115bc7Smrj last_head = ring->head;
76d0231070Smiao chen - Sun Microsystems - Beijing China last_acthd = acthd;
77d0231070Smiao chen - Sun Microsystems - Beijing China DRM_UDELAY(10);
78ae115bc7Smrj }
79ae115bc7Smrj
80d0538f66Scg149915 return (EBUSY);
81ae115bc7Smrj }
82ae115bc7Smrj
i915_init_hardware_status(drm_device_t * dev)83d0231070Smiao chen - Sun Microsystems - Beijing China int i915_init_hardware_status(drm_device_t *dev)
84d0231070Smiao chen - Sun Microsystems - Beijing China {
85d0231070Smiao chen - Sun Microsystems - Beijing China drm_i915_private_t *dev_priv = dev->dev_private;
86d0231070Smiao chen - Sun Microsystems - Beijing China drm_dma_handle_t *dmah;
87d0231070Smiao chen - Sun Microsystems - Beijing China
88d0231070Smiao chen - Sun Microsystems - Beijing China /* Program Hardware Status Page */
89d0231070Smiao chen - Sun Microsystems - Beijing China dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff,1);
90d0231070Smiao chen - Sun Microsystems - Beijing China
91d0231070Smiao chen - Sun Microsystems - Beijing China if (!dmah) {
92d0231070Smiao chen - Sun Microsystems - Beijing China DRM_ERROR("Can not allocate hardware status page\n");
93d0231070Smiao chen - Sun Microsystems - Beijing China return -ENOMEM;
94d0231070Smiao chen - Sun Microsystems - Beijing China }
95d0231070Smiao chen - Sun Microsystems - Beijing China
96d0231070Smiao chen - Sun Microsystems - Beijing China dev_priv->status_page_dmah = dmah;
97d0231070Smiao chen - Sun Microsystems - Beijing China dev_priv->hw_status_page = (void *)dmah->vaddr;
98d0231070Smiao chen - Sun Microsystems - Beijing China dev_priv->dma_status_page = dmah->paddr;
99d0231070Smiao chen - Sun Microsystems - Beijing China
100d0231070Smiao chen - Sun Microsystems - Beijing China (void) memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
101d0231070Smiao chen - Sun Microsystems - Beijing China
102d0231070Smiao chen - Sun Microsystems - Beijing China I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
1030035d21cSmiao chen - Sun Microsystems - Beijing China (void) I915_READ(HWS_PGA);
1040035d21cSmiao chen - Sun Microsystems - Beijing China
1050035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG("Enabled hardware status page add 0x%lx read GEM HWS 0x%x\n",dev_priv->hw_status_page, READ_HWSP(dev_priv, 0x20));
106d0231070Smiao chen - Sun Microsystems - Beijing China return 0;
107d0231070Smiao chen - Sun Microsystems - Beijing China }
108d0231070Smiao chen - Sun Microsystems - Beijing China
i915_free_hardware_status(drm_device_t * dev)109d0231070Smiao chen - Sun Microsystems - Beijing China void i915_free_hardware_status(drm_device_t *dev)
110d0231070Smiao chen - Sun Microsystems - Beijing China {
111d0231070Smiao chen - Sun Microsystems - Beijing China drm_i915_private_t *dev_priv = dev->dev_private;
112d0231070Smiao chen - Sun Microsystems - Beijing China if (!I915_NEED_GFX_HWS(dev)) {
113d0231070Smiao chen - Sun Microsystems - Beijing China if (dev_priv->status_page_dmah) {
1140035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG("free status_page_dmal %x", dev_priv->status_page_dmah);
115d0231070Smiao chen - Sun Microsystems - Beijing China drm_pci_free(dev, dev_priv->status_page_dmah);
116d0231070Smiao chen - Sun Microsystems - Beijing China dev_priv->status_page_dmah = NULL;
117d0231070Smiao chen - Sun Microsystems - Beijing China /* Need to rewrite hardware status page */
118d0231070Smiao chen - Sun Microsystems - Beijing China I915_WRITE(HWS_PGA, 0x1ffff000);
119d0231070Smiao chen - Sun Microsystems - Beijing China }
120d0231070Smiao chen - Sun Microsystems - Beijing China } else {
121d0231070Smiao chen - Sun Microsystems - Beijing China if (dev_priv->status_gfx_addr) {
1220035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG("free status_gfx_addr %x", dev_priv->status_gfx_addr);
123d0231070Smiao chen - Sun Microsystems - Beijing China dev_priv->status_gfx_addr = 0;
124d0231070Smiao chen - Sun Microsystems - Beijing China drm_core_ioremapfree(&dev_priv->hws_map, dev);
125d0231070Smiao chen - Sun Microsystems - Beijing China I915_WRITE(HWS_PGA, 0x1ffff000);
126d0231070Smiao chen - Sun Microsystems - Beijing China }
127d0231070Smiao chen - Sun Microsystems - Beijing China }
128d0231070Smiao chen - Sun Microsystems - Beijing China
129d0231070Smiao chen - Sun Microsystems - Beijing China }
130d0231070Smiao chen - Sun Microsystems - Beijing China
i915_kernel_lost_context(drm_device_t * dev)131ae115bc7Smrj void i915_kernel_lost_context(drm_device_t * dev)
132ae115bc7Smrj {
133ae115bc7Smrj drm_i915_private_t *dev_priv = dev->dev_private;
134ae115bc7Smrj drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
135ae115bc7Smrj
136d0231070Smiao chen - Sun Microsystems - Beijing China ring->head = I915_READ(PRB0_HEAD) & HEAD_ADDR;
137d0231070Smiao chen - Sun Microsystems - Beijing China ring->tail = I915_READ(PRB0_TAIL) & TAIL_ADDR;
138ae115bc7Smrj ring->space = ring->head - (ring->tail + 8);
139ae115bc7Smrj if (ring->space < 0)
140ae115bc7Smrj ring->space += ring->Size;
141ae115bc7Smrj
142ae115bc7Smrj }
143ae115bc7Smrj
i915_dma_cleanup(drm_device_t * dev)144ae115bc7Smrj static int i915_dma_cleanup(drm_device_t * dev)
145ae115bc7Smrj {
14691fae470Scg149915 drm_i915_private_t *dev_priv =
14791fae470Scg149915 (drm_i915_private_t *) dev->dev_private;
14891fae470Scg149915
149ae115bc7Smrj /* Make sure interrupts are disabled here because the uninstall ioctl
150ae115bc7Smrj * may not have been called from userspace and after dev_private
151ae115bc7Smrj * is freed, it's too late.
152ae115bc7Smrj */
153d0231070Smiao chen - Sun Microsystems - Beijing China if (dev->irq_enabled)
154ae115bc7Smrj (void) drm_irq_uninstall(dev);
155ae115bc7Smrj
156ae115bc7Smrj if (dev_priv->ring.virtual_start) {
157ae115bc7Smrj drm_core_ioremapfree(&dev_priv->ring.map, dev);
15891fae470Scg149915 dev_priv->ring.virtual_start = 0;
15991fae470Scg149915 dev_priv->ring.map.handle = 0;
16091fae470Scg149915 dev_priv->ring.map.size = 0;
161ae115bc7Smrj }
162ae115bc7Smrj
1630035d21cSmiao chen - Sun Microsystems - Beijing China #ifdef I915_HAVE_GEM
1640035d21cSmiao chen - Sun Microsystems - Beijing China if (I915_NEED_GFX_HWS(dev))
1650035d21cSmiao chen - Sun Microsystems - Beijing China #endif
166d0231070Smiao chen - Sun Microsystems - Beijing China i915_free_hardware_status(dev);
167d0538f66Scg149915
168d0231070Smiao chen - Sun Microsystems - Beijing China dev_priv->sarea = NULL;
169d0231070Smiao chen - Sun Microsystems - Beijing China dev_priv->sarea_priv = NULL;
170dc8c6b69Sms148562
171ae115bc7Smrj return 0;
172ae115bc7Smrj }
173ae115bc7Smrj
i915_initialize(drm_device_t * dev,drm_i915_init_t * init)174ae115bc7Smrj static int i915_initialize(drm_device_t * dev,
175ae115bc7Smrj drm_i915_init_t * init)
176ae115bc7Smrj {
17791fae470Scg149915 drm_i915_private_t *dev_priv =
17891fae470Scg149915 (drm_i915_private_t *)dev->dev_private;
179ae115bc7Smrj
180ae115bc7Smrj DRM_GETSAREA();
181ae115bc7Smrj if (!dev_priv->sarea) {
182ae115bc7Smrj DRM_ERROR("can not find sarea!\n");
183ae115bc7Smrj dev->dev_private = (void *)dev_priv;
184ae115bc7Smrj (void) i915_dma_cleanup(dev);
185d0538f66Scg149915 return (EINVAL);
186ae115bc7Smrj }
187ae115bc7Smrj
1880035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->sarea_priv = (drm_i915_sarea_t *)(uintptr_t)
1890035d21cSmiao chen - Sun Microsystems - Beijing China ((u8 *) dev_priv->sarea->handle +
190d0231070Smiao chen - Sun Microsystems - Beijing China init->sarea_priv_offset);
191ae115bc7Smrj
192d0231070Smiao chen - Sun Microsystems - Beijing China if (init->ring_size != 0) {
1930035d21cSmiao chen - Sun Microsystems - Beijing China if (dev_priv->ring.ring_obj != NULL) {
1940035d21cSmiao chen - Sun Microsystems - Beijing China (void) i915_dma_cleanup(dev);
1950035d21cSmiao chen - Sun Microsystems - Beijing China DRM_ERROR("Client tried to initialize ringbuffer in "
1960035d21cSmiao chen - Sun Microsystems - Beijing China "GEM mode\n");
1970035d21cSmiao chen - Sun Microsystems - Beijing China return -EINVAL;
1980035d21cSmiao chen - Sun Microsystems - Beijing China }
1990035d21cSmiao chen - Sun Microsystems - Beijing China
200ae115bc7Smrj dev_priv->ring.Size = init->ring_size;
201ae115bc7Smrj dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
202ae115bc7Smrj
203d0538f66Scg149915 dev_priv->ring.map.offset = (u_offset_t)init->ring_start;
204ae115bc7Smrj dev_priv->ring.map.size = init->ring_size;
205ae115bc7Smrj dev_priv->ring.map.type = 0;
206ae115bc7Smrj dev_priv->ring.map.flags = 0;
207ae115bc7Smrj dev_priv->ring.map.mtrr = 0;
208ae115bc7Smrj
209ae115bc7Smrj drm_core_ioremap(&dev_priv->ring.map, dev);
210ae115bc7Smrj
211ae115bc7Smrj if (dev_priv->ring.map.handle == NULL) {
212ae115bc7Smrj (void) i915_dma_cleanup(dev);
213ae115bc7Smrj DRM_ERROR("can not ioremap virtual address for"
214ae115bc7Smrj " ring buffer\n");
215d0538f66Scg149915 return (ENOMEM);
216ae115bc7Smrj }
217d0231070Smiao chen - Sun Microsystems - Beijing China }
218ae115bc7Smrj
2190035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->ring.virtual_start = (u8 *)dev_priv->ring.map.dev_addr;
220e92e3a86Szw161486 dev_priv->cpp = init->cpp;
2210035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->back_offset = init->back_offset;
2220035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->front_offset = init->front_offset;
2230035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->current_page = 0;
2240035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
225ae115bc7Smrj
226ae115bc7Smrj /* Allow hardware batchbuffers unless told otherwise.
227ae115bc7Smrj */
228ae115bc7Smrj dev_priv->allow_batchbuffer = 1;
229ae115bc7Smrj return 0;
230ae115bc7Smrj }
231ae115bc7Smrj
i915_dma_resume(drm_device_t * dev)232ae115bc7Smrj static int i915_dma_resume(drm_device_t * dev)
233ae115bc7Smrj {
234ae115bc7Smrj drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
235ae115bc7Smrj
236ae115bc7Smrj if (!dev_priv->sarea) {
237ae115bc7Smrj DRM_ERROR("can not find sarea!\n");
238d0538f66Scg149915 return (EINVAL);
239ae115bc7Smrj }
240ae115bc7Smrj
241ae115bc7Smrj if (dev_priv->ring.map.handle == NULL) {
242ae115bc7Smrj DRM_ERROR("can not ioremap virtual address for"
243ae115bc7Smrj " ring buffer\n");
244d0538f66Scg149915 return (ENOMEM);
245ae115bc7Smrj }
246ae115bc7Smrj
247ae115bc7Smrj /* Program Hardware Status Page */
248ae115bc7Smrj if (!dev_priv->hw_status_page) {
249ae115bc7Smrj DRM_ERROR("Can not find hardware status page\n");
250d0538f66Scg149915 return (EINVAL);
251ae115bc7Smrj }
2520035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG("i915_dma_resume hw status page @ %p\n", dev_priv->hw_status_page);
253ae115bc7Smrj
254fc6df3bdSmiao chen - Sun Microsystems - Beijing China if (!I915_NEED_GFX_HWS(dev))
255d0231070Smiao chen - Sun Microsystems - Beijing China I915_WRITE(HWS_PGA, dev_priv->dma_status_page);
256fc6df3bdSmiao chen - Sun Microsystems - Beijing China else
257d0231070Smiao chen - Sun Microsystems - Beijing China I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
258ae115bc7Smrj DRM_DEBUG("Enabled hardware status page\n");
259ae115bc7Smrj
260ae115bc7Smrj return 0;
261ae115bc7Smrj }
262ae115bc7Smrj
263ae115bc7Smrj /*ARGSUSED*/
i915_dma_init(DRM_IOCTL_ARGS)264ae115bc7Smrj static int i915_dma_init(DRM_IOCTL_ARGS)
265ae115bc7Smrj {
266ae115bc7Smrj DRM_DEVICE;
267ae115bc7Smrj drm_i915_init_t init;
268ae115bc7Smrj int retcode = 0;
269ae115bc7Smrj
270d0538f66Scg149915 DRM_COPYFROM_WITH_RETURN(&init, (drm_i915_init_t *)data, sizeof(init));
271ae115bc7Smrj
272ae115bc7Smrj switch (init.func) {
273ae115bc7Smrj case I915_INIT_DMA:
27491fae470Scg149915 retcode = i915_initialize(dev, &init);
275ae115bc7Smrj break;
276ae115bc7Smrj case I915_CLEANUP_DMA:
277ae115bc7Smrj retcode = i915_dma_cleanup(dev);
278ae115bc7Smrj break;
279ae115bc7Smrj case I915_RESUME_DMA:
280ae115bc7Smrj retcode = i915_dma_resume(dev);
281ae115bc7Smrj break;
282ae115bc7Smrj default:
283d0538f66Scg149915 retcode = EINVAL;
284ae115bc7Smrj break;
285ae115bc7Smrj }
286ae115bc7Smrj
287ae115bc7Smrj return retcode;
288ae115bc7Smrj }
289ae115bc7Smrj
290ae115bc7Smrj /* Implement basically the same security restrictions as hardware does
291ae115bc7Smrj * for MI_BATCH_NON_SECURE. These can be made stricter at any time.
292ae115bc7Smrj *
293ae115bc7Smrj * Most of the calculations below involve calculating the size of a
294ae115bc7Smrj * particular instruction. It's important to get the size right as
295ae115bc7Smrj * that tells us where the next instruction to check is. Any illegal
296ae115bc7Smrj * instruction detected will be given a size of zero, which is a
297ae115bc7Smrj * signal to abort the rest of the buffer.
298ae115bc7Smrj */
do_validate_cmd(int cmd)299ae115bc7Smrj static int do_validate_cmd(int cmd)
300ae115bc7Smrj {
301ae115bc7Smrj switch (((cmd >> 29) & 0x7)) {
302ae115bc7Smrj case 0x0:
303ae115bc7Smrj switch ((cmd >> 23) & 0x3f) {
304ae115bc7Smrj case 0x0:
305ae115bc7Smrj return 1; /* MI_NOOP */
306ae115bc7Smrj case 0x4:
307ae115bc7Smrj return 1; /* MI_FLUSH */
308ae115bc7Smrj default:
309ae115bc7Smrj return 0; /* disallow everything else */
310ae115bc7Smrj }
311ae115bc7Smrj #ifndef __SUNPRO_C
312ae115bc7Smrj break;
313ae115bc7Smrj #endif
314ae115bc7Smrj case 0x1:
315ae115bc7Smrj return 0; /* reserved */
316ae115bc7Smrj case 0x2:
317ae115bc7Smrj return (cmd & 0xff) + 2; /* 2d commands */
318ae115bc7Smrj case 0x3:
319ae115bc7Smrj if (((cmd >> 24) & 0x1f) <= 0x18)
320ae115bc7Smrj return 1;
321ae115bc7Smrj
322ae115bc7Smrj switch ((cmd >> 24) & 0x1f) {
323ae115bc7Smrj case 0x1c:
324ae115bc7Smrj return 1;
325ae115bc7Smrj case 0x1d:
326ae115bc7Smrj switch ((cmd >> 16) & 0xff) {
327ae115bc7Smrj case 0x3:
328ae115bc7Smrj return (cmd & 0x1f) + 2;
329ae115bc7Smrj case 0x4:
330ae115bc7Smrj return (cmd & 0xf) + 2;
331ae115bc7Smrj default:
332ae115bc7Smrj return (cmd & 0xffff) + 2;
333ae115bc7Smrj }
334ae115bc7Smrj case 0x1e:
335ae115bc7Smrj if (cmd & (1 << 23))
336ae115bc7Smrj return (cmd & 0xffff) + 1;
337ae115bc7Smrj else
338ae115bc7Smrj return 1;
339ae115bc7Smrj case 0x1f:
340ae115bc7Smrj if ((cmd & (1 << 23)) == 0) /* inline vertices */
341ae115bc7Smrj return (cmd & 0x1ffff) + 2;
342ae115bc7Smrj else if (cmd & (1 << 17)) /* indirect random */
343ae115bc7Smrj if ((cmd & 0xffff) == 0)
344ae115bc7Smrj return 0; /* unknown length, too hard */
345ae115bc7Smrj else
346ae115bc7Smrj return (((cmd & 0xffff) + 1) / 2) + 1;
347ae115bc7Smrj else
348ae115bc7Smrj return 2; /* indirect sequential */
349ae115bc7Smrj default:
350ae115bc7Smrj return 0;
351ae115bc7Smrj }
352ae115bc7Smrj default:
353ae115bc7Smrj return 0;
354ae115bc7Smrj }
355ae115bc7Smrj
356ae115bc7Smrj #ifndef __SUNPRO_C
357ae115bc7Smrj return 0;
358ae115bc7Smrj #endif
359ae115bc7Smrj }
360ae115bc7Smrj
validate_cmd(int cmd)361ae115bc7Smrj static int validate_cmd(int cmd)
362ae115bc7Smrj {
363ae115bc7Smrj int ret = do_validate_cmd(cmd);
364ae115bc7Smrj
365ae115bc7Smrj /* printk("validate_cmd( %x ): %d\n", cmd, ret); */
366ae115bc7Smrj
367ae115bc7Smrj return ret;
368ae115bc7Smrj }
369ae115bc7Smrj
i915_emit_cmds(drm_device_t * dev,int __user * buffer,int dwords)370d0538f66Scg149915 static int i915_emit_cmds(drm_device_t * dev, int __user * buffer, int dwords)
371ae115bc7Smrj {
372ae115bc7Smrj drm_i915_private_t *dev_priv = dev->dev_private;
373ae115bc7Smrj int i;
374ae115bc7Smrj RING_LOCALS;
375ae115bc7Smrj
3760035d21cSmiao chen - Sun Microsystems - Beijing China if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8) {
3770035d21cSmiao chen - Sun Microsystems - Beijing China DRM_ERROR(" emit cmds invalid arg");
378d0538f66Scg149915 return (EINVAL);
3790035d21cSmiao chen - Sun Microsystems - Beijing China }
380e92e3a86Szw161486 BEGIN_LP_RING((dwords+1)&~1);
381e92e3a86Szw161486
382ae115bc7Smrj for (i = 0; i < dwords;) {
383ae115bc7Smrj int cmd, sz;
384ae115bc7Smrj
3850035d21cSmiao chen - Sun Microsystems - Beijing China if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd))) {
3860035d21cSmiao chen - Sun Microsystems - Beijing China DRM_ERROR("emit cmds failed to get cmd from user");
387d0538f66Scg149915 return (EINVAL);
3880035d21cSmiao chen - Sun Microsystems - Beijing China }
389ae115bc7Smrj
3900035d21cSmiao chen - Sun Microsystems - Beijing China if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords) {
3910035d21cSmiao chen - Sun Microsystems - Beijing China DRM_ERROR("emit cmds invalid");
392d0538f66Scg149915 return (EINVAL);
3930035d21cSmiao chen - Sun Microsystems - Beijing China }
394ae115bc7Smrj OUT_RING(cmd);
395ae115bc7Smrj
396ae115bc7Smrj while (++i, --sz) {
397ae115bc7Smrj if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i],
398ae115bc7Smrj sizeof(cmd))) {
3990035d21cSmiao chen - Sun Microsystems - Beijing China DRM_ERROR("emit cmds failed get cmds");
400d0538f66Scg149915 return (EINVAL);
401ae115bc7Smrj }
402ae115bc7Smrj OUT_RING(cmd);
403ae115bc7Smrj }
404ae115bc7Smrj }
405ae115bc7Smrj
406e92e3a86Szw161486 if (dwords & 1)
407e92e3a86Szw161486 OUT_RING(0);
408e92e3a86Szw161486
409e92e3a86Szw161486 ADVANCE_LP_RING();
410e92e3a86Szw161486
411ae115bc7Smrj return 0;
412ae115bc7Smrj }
413ae115bc7Smrj
i915_emit_box(drm_device_t * dev,drm_clip_rect_t __user * boxes,int i,int DR1,int DR4)414d0231070Smiao chen - Sun Microsystems - Beijing China int i915_emit_box(drm_device_t * dev,
415ae115bc7Smrj drm_clip_rect_t __user * boxes,
416d0538f66Scg149915 int i, int DR1, int DR4)
417ae115bc7Smrj {
418ae115bc7Smrj drm_i915_private_t *dev_priv = dev->dev_private;
419ae115bc7Smrj drm_clip_rect_t box;
420ae115bc7Smrj RING_LOCALS;
421ae115bc7Smrj
422ae115bc7Smrj if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) {
4230035d21cSmiao chen - Sun Microsystems - Beijing China DRM_ERROR("emit box failed to copy from user");
424d0538f66Scg149915 return (EFAULT);
425ae115bc7Smrj }
426ae115bc7Smrj
4270bdffa0fShh224818 if (box.y2 <= box.y1 || box.x2 <= box.x1) {
428ae115bc7Smrj DRM_ERROR("Bad box %d,%d..%d,%d\n",
429ae115bc7Smrj box.x1, box.y1, box.x2, box.y2);
430d0538f66Scg149915 return (EINVAL);
431ae115bc7Smrj }
432ae115bc7Smrj
433e92e3a86Szw161486 if (IS_I965G(dev)) {
434e92e3a86Szw161486 BEGIN_LP_RING(4);
435e92e3a86Szw161486 OUT_RING(GFX_OP_DRAWRECT_INFO_I965);
436e92e3a86Szw161486 OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
437e92e3a86Szw161486 OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
438e92e3a86Szw161486 OUT_RING(DR4);
439e92e3a86Szw161486 ADVANCE_LP_RING();
440e92e3a86Szw161486 } else {
441ae115bc7Smrj BEGIN_LP_RING(6);
442ae115bc7Smrj OUT_RING(GFX_OP_DRAWRECT_INFO);
443ae115bc7Smrj OUT_RING(DR1);
444ae115bc7Smrj OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
445ae115bc7Smrj OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
446ae115bc7Smrj OUT_RING(DR4);
447ae115bc7Smrj OUT_RING(0);
448ae115bc7Smrj ADVANCE_LP_RING();
449e92e3a86Szw161486 }
450e92e3a86Szw161486
451e92e3a86Szw161486 return 0;
452e92e3a86Szw161486 }
453e92e3a86Szw161486
454e92e3a86Szw161486 /* XXX: Emitting the counter should really be moved to part of the IRQ
455e92e3a86Szw161486 * emit. For now, do it in both places:
456e92e3a86Szw161486 */
457e92e3a86Szw161486
i915_emit_breadcrumb(drm_device_t * dev)458d0231070Smiao chen - Sun Microsystems - Beijing China void i915_emit_breadcrumb(drm_device_t *dev)
459e92e3a86Szw161486 {
460e92e3a86Szw161486 drm_i915_private_t *dev_priv = dev->dev_private;
461e92e3a86Szw161486 RING_LOCALS;
462e92e3a86Szw161486
4630035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->counter++;
4640035d21cSmiao chen - Sun Microsystems - Beijing China if (dev_priv->counter > 0x7FFFFFFFUL)
4650035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->counter = 0;
466d0231070Smiao chen - Sun Microsystems - Beijing China if (dev_priv->sarea_priv)
467d0231070Smiao chen - Sun Microsystems - Beijing China dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
468d0231070Smiao chen - Sun Microsystems - Beijing China
469e92e3a86Szw161486
470e92e3a86Szw161486 BEGIN_LP_RING(4);
471d0231070Smiao chen - Sun Microsystems - Beijing China OUT_RING(MI_STORE_DWORD_INDEX);
4720035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
473e92e3a86Szw161486 OUT_RING(dev_priv->counter);
474e92e3a86Szw161486 OUT_RING(0);
475e92e3a86Szw161486 ADVANCE_LP_RING();
476d0231070Smiao chen - Sun Microsystems - Beijing China
477e92e3a86Szw161486 }
478e92e3a86Szw161486
i915_dispatch_cmdbuffer(drm_device_t * dev,drm_i915_cmdbuffer_t * cmd)479ae115bc7Smrj static int i915_dispatch_cmdbuffer(drm_device_t * dev,
480d0538f66Scg149915 drm_i915_cmdbuffer_t * cmd)
481ae115bc7Smrj {
482ae115bc7Smrj int nbox = cmd->num_cliprects;
483ae115bc7Smrj int i = 0, count, ret;
484ae115bc7Smrj
485ae115bc7Smrj if (cmd->sz & 0x3) {
486ae115bc7Smrj DRM_ERROR("alignment");
487d0538f66Scg149915 return (EINVAL);
488ae115bc7Smrj }
489ae115bc7Smrj
490ae115bc7Smrj i915_kernel_lost_context(dev);
491ae115bc7Smrj
492ae115bc7Smrj count = nbox ? nbox : 1;
493ae115bc7Smrj
494ae115bc7Smrj for (i = 0; i < count; i++) {
495ae115bc7Smrj if (i < nbox) {
496ae115bc7Smrj ret = i915_emit_box(dev, cmd->cliprects, i,
497d0538f66Scg149915 cmd->DR1, cmd->DR4);
498ae115bc7Smrj if (ret)
499ae115bc7Smrj return ret;
500ae115bc7Smrj }
501ae115bc7Smrj
5020bdffa0fShh224818 ret = i915_emit_cmds(dev, (int __user *)(void *)cmd->buf, cmd->sz / 4);
503ae115bc7Smrj if (ret)
504ae115bc7Smrj return ret;
505ae115bc7Smrj }
506ae115bc7Smrj
507e92e3a86Szw161486 i915_emit_breadcrumb( dev );
508ae115bc7Smrj return 0;
509ae115bc7Smrj }
510ae115bc7Smrj
i915_dispatch_batchbuffer(drm_device_t * dev,drm_i915_batchbuffer_t * batch)511ae115bc7Smrj static int i915_dispatch_batchbuffer(drm_device_t * dev,
512d0538f66Scg149915 drm_i915_batchbuffer_t * batch)
513ae115bc7Smrj {
514ae115bc7Smrj drm_i915_private_t *dev_priv = dev->dev_private;
515ae115bc7Smrj drm_clip_rect_t __user *boxes = batch->cliprects;
516ae115bc7Smrj int nbox = batch->num_cliprects;
517ae115bc7Smrj int i = 0, count;
518ae115bc7Smrj RING_LOCALS;
519ae115bc7Smrj
520ae115bc7Smrj if ((batch->start | batch->used) & 0x7) {
521ae115bc7Smrj DRM_ERROR("alignment");
522d0538f66Scg149915 return (EINVAL);
523ae115bc7Smrj }
524ae115bc7Smrj
525ae115bc7Smrj i915_kernel_lost_context(dev);
526ae115bc7Smrj
527ae115bc7Smrj count = nbox ? nbox : 1;
528ae115bc7Smrj
529ae115bc7Smrj for (i = 0; i < count; i++) {
530ae115bc7Smrj if (i < nbox) {
531ae115bc7Smrj int ret = i915_emit_box(dev, boxes, i,
532d0538f66Scg149915 batch->DR1, batch->DR4);
533ae115bc7Smrj if (ret)
534ae115bc7Smrj return ret;
535ae115bc7Smrj }
536ae115bc7Smrj
537d0231070Smiao chen - Sun Microsystems - Beijing China if (IS_I830(dev) || IS_845G(dev)) {
538ae115bc7Smrj BEGIN_LP_RING(4);
539ae115bc7Smrj OUT_RING(MI_BATCH_BUFFER);
540ae115bc7Smrj OUT_RING(batch->start | MI_BATCH_NON_SECURE);
541ae115bc7Smrj OUT_RING(batch->start + batch->used - 4);
542ae115bc7Smrj OUT_RING(0);
543ae115bc7Smrj ADVANCE_LP_RING();
544d0231070Smiao chen - Sun Microsystems - Beijing China } else {
545d0231070Smiao chen - Sun Microsystems - Beijing China BEGIN_LP_RING(2);
546d0231070Smiao chen - Sun Microsystems - Beijing China if (IS_I965G(dev)) {
547d0231070Smiao chen - Sun Microsystems - Beijing China OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
548d0231070Smiao chen - Sun Microsystems - Beijing China OUT_RING(batch->start);
549d0231070Smiao chen - Sun Microsystems - Beijing China } else {
550d0231070Smiao chen - Sun Microsystems - Beijing China OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
551d0231070Smiao chen - Sun Microsystems - Beijing China OUT_RING(batch->start | MI_BATCH_NON_SECURE);
552d0231070Smiao chen - Sun Microsystems - Beijing China }
553d0231070Smiao chen - Sun Microsystems - Beijing China ADVANCE_LP_RING();
554ae115bc7Smrj }
555ae115bc7Smrj }
556ae115bc7Smrj
557e92e3a86Szw161486 i915_emit_breadcrumb( dev );
558ae115bc7Smrj
559ae115bc7Smrj return 0;
560ae115bc7Smrj }
561ae115bc7Smrj
i915_dispatch_flip(struct drm_device * dev,int planes)5620035d21cSmiao chen - Sun Microsystems - Beijing China static int i915_dispatch_flip(struct drm_device * dev, int planes)
563ae115bc7Smrj {
564ae115bc7Smrj drm_i915_private_t *dev_priv = dev->dev_private;
565ae115bc7Smrj RING_LOCALS;
566ae115bc7Smrj
5670035d21cSmiao chen - Sun Microsystems - Beijing China if (!dev_priv->sarea_priv)
5680035d21cSmiao chen - Sun Microsystems - Beijing China return -EINVAL;
569d0231070Smiao chen - Sun Microsystems - Beijing China
570d0231070Smiao chen - Sun Microsystems - Beijing China DRM_DEBUG("planes=0x%x pfCurrentPage=%d\n",
571d0231070Smiao chen - Sun Microsystems - Beijing China planes, dev_priv->sarea_priv->pf_current_page);
572d0231070Smiao chen - Sun Microsystems - Beijing China
5730035d21cSmiao chen - Sun Microsystems - Beijing China i915_kernel_lost_context(dev);
574d0231070Smiao chen - Sun Microsystems - Beijing China
5750035d21cSmiao chen - Sun Microsystems - Beijing China BEGIN_LP_RING(2);
5760035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(MI_FLUSH | MI_READ_FLUSH);
5770035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(0);
5780035d21cSmiao chen - Sun Microsystems - Beijing China ADVANCE_LP_RING();
579d0231070Smiao chen - Sun Microsystems - Beijing China
5800035d21cSmiao chen - Sun Microsystems - Beijing China BEGIN_LP_RING(6);
5810035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP);
5820035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(0);
5830035d21cSmiao chen - Sun Microsystems - Beijing China if (dev_priv->current_page == 0) {
5840035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(dev_priv->back_offset);
5850035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->current_page = 1;
5860035d21cSmiao chen - Sun Microsystems - Beijing China } else {
5870035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(dev_priv->front_offset);
5880035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->current_page = 0;
5890035d21cSmiao chen - Sun Microsystems - Beijing China }
5900035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(0);
5910035d21cSmiao chen - Sun Microsystems - Beijing China ADVANCE_LP_RING();
592d0231070Smiao chen - Sun Microsystems - Beijing China
5930035d21cSmiao chen - Sun Microsystems - Beijing China BEGIN_LP_RING(2);
5940035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP);
5950035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(0);
5960035d21cSmiao chen - Sun Microsystems - Beijing China ADVANCE_LP_RING();
5970035d21cSmiao chen - Sun Microsystems - Beijing China
5980035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->sarea_priv->last_enqueue = dev_priv->counter++;
5990035d21cSmiao chen - Sun Microsystems - Beijing China
6000035d21cSmiao chen - Sun Microsystems - Beijing China BEGIN_LP_RING(4);
6010035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(MI_STORE_DWORD_INDEX);
6020035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(I915_BREADCRUMB_INDEX << MI_STORE_DWORD_INDEX_SHIFT);
6030035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(dev_priv->counter);
6040035d21cSmiao chen - Sun Microsystems - Beijing China OUT_RING(0);
6050035d21cSmiao chen - Sun Microsystems - Beijing China ADVANCE_LP_RING();
6060035d21cSmiao chen - Sun Microsystems - Beijing China
6070035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
6080035d21cSmiao chen - Sun Microsystems - Beijing China return 0;
609ae115bc7Smrj }
610ae115bc7Smrj
i915_quiescent(drm_device_t * dev)611ae115bc7Smrj static int i915_quiescent(drm_device_t * dev)
612ae115bc7Smrj {
613ae115bc7Smrj drm_i915_private_t *dev_priv = dev->dev_private;
614d0231070Smiao chen - Sun Microsystems - Beijing China int ret;
615ae115bc7Smrj i915_kernel_lost_context(dev);
616d0231070Smiao chen - Sun Microsystems - Beijing China ret = i915_wait_ring(dev, dev_priv->ring.Size - 8, __FUNCTION__);
617d0231070Smiao chen - Sun Microsystems - Beijing China
618d0231070Smiao chen - Sun Microsystems - Beijing China if (ret)
619d0231070Smiao chen - Sun Microsystems - Beijing China {
620d0231070Smiao chen - Sun Microsystems - Beijing China i915_kernel_lost_context (dev);
621d0231070Smiao chen - Sun Microsystems - Beijing China DRM_ERROR ("not quiescent head %08x tail %08x space %08x\n",
622d0231070Smiao chen - Sun Microsystems - Beijing China dev_priv->ring.head,
623d0231070Smiao chen - Sun Microsystems - Beijing China dev_priv->ring.tail,
624d0231070Smiao chen - Sun Microsystems - Beijing China dev_priv->ring.space);
625d0231070Smiao chen - Sun Microsystems - Beijing China }
626d0231070Smiao chen - Sun Microsystems - Beijing China return ret;
627ae115bc7Smrj }
628ae115bc7Smrj
629ae115bc7Smrj /*ARGSUSED*/
i915_flush_ioctl(DRM_IOCTL_ARGS)630ae115bc7Smrj static int i915_flush_ioctl(DRM_IOCTL_ARGS)
631ae115bc7Smrj {
6320035d21cSmiao chen - Sun Microsystems - Beijing China int ret;
633ae115bc7Smrj DRM_DEVICE;
634ae115bc7Smrj
635d0538f66Scg149915 LOCK_TEST_WITH_RETURN(dev, fpriv);
636ae115bc7Smrj
6370035d21cSmiao chen - Sun Microsystems - Beijing China spin_lock(&dev->struct_mutex);
6380035d21cSmiao chen - Sun Microsystems - Beijing China ret = i915_quiescent(dev);
6390035d21cSmiao chen - Sun Microsystems - Beijing China spin_unlock(&dev->struct_mutex);
6400035d21cSmiao chen - Sun Microsystems - Beijing China
6410035d21cSmiao chen - Sun Microsystems - Beijing China return ret;
642ae115bc7Smrj }
643ae115bc7Smrj
644ae115bc7Smrj /*ARGSUSED*/
i915_batchbuffer(DRM_IOCTL_ARGS)645ae115bc7Smrj static int i915_batchbuffer(DRM_IOCTL_ARGS)
646ae115bc7Smrj {
647ae115bc7Smrj DRM_DEVICE;
648ae115bc7Smrj drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
649ae115bc7Smrj drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
650ae115bc7Smrj dev_priv->sarea_priv;
651ae115bc7Smrj drm_i915_batchbuffer_t batch;
652ae115bc7Smrj int ret;
653ae115bc7Smrj
654ae115bc7Smrj if (!dev_priv->allow_batchbuffer) {
655ae115bc7Smrj DRM_ERROR("Batchbuffer ioctl disabled\n");
656d0538f66Scg149915 return (EINVAL);
657ae115bc7Smrj }
658ae115bc7Smrj
659ae115bc7Smrj if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
660ae115bc7Smrj drm_i915_batchbuffer32_t batchbuffer32_t;
661ae115bc7Smrj
662d0538f66Scg149915 DRM_COPYFROM_WITH_RETURN(&batchbuffer32_t,
663d0538f66Scg149915 (void *) data, sizeof (batchbuffer32_t));
664ae115bc7Smrj
665ae115bc7Smrj batch.start = batchbuffer32_t.start;
666ae115bc7Smrj batch.used = batchbuffer32_t.used;
667ae115bc7Smrj batch.DR1 = batchbuffer32_t.DR1;
668ae115bc7Smrj batch.DR4 = batchbuffer32_t.DR4;
669ae115bc7Smrj batch.num_cliprects = batchbuffer32_t.num_cliprects;
670ae115bc7Smrj batch.cliprects = (drm_clip_rect_t __user *)
671ae115bc7Smrj (uintptr_t)batchbuffer32_t.cliprects;
672ae115bc7Smrj } else
673d0538f66Scg149915 DRM_COPYFROM_WITH_RETURN(&batch, (void *) data,
674ae115bc7Smrj sizeof(batch));
675ae115bc7Smrj
676d0231070Smiao chen - Sun Microsystems - Beijing China DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d, counter %d\n",
677d0231070Smiao chen - Sun Microsystems - Beijing China batch.start, batch.used, batch.num_cliprects, dev_priv->counter);
678ae115bc7Smrj
679d0538f66Scg149915 LOCK_TEST_WITH_RETURN(dev, fpriv);
680ae115bc7Smrj
681d0231070Smiao chen - Sun Microsystems - Beijing China /*
682ae115bc7Smrj if (batch.num_cliprects && DRM_VERIFYAREA_READ(batch.cliprects,
683ae115bc7Smrj batch.num_cliprects *
684ae115bc7Smrj sizeof(drm_clip_rect_t)))
685d0538f66Scg149915 return (EFAULT);
6860035d21cSmiao chen - Sun Microsystems - Beijing China
687ae115bc7Smrj */
688ae115bc7Smrj
6890035d21cSmiao chen - Sun Microsystems - Beijing China spin_lock(&dev->struct_mutex);
690d0231070Smiao chen - Sun Microsystems - Beijing China ret = i915_dispatch_batchbuffer(dev, &batch);
6910035d21cSmiao chen - Sun Microsystems - Beijing China spin_unlock(&dev->struct_mutex);
692d0231070Smiao chen - Sun Microsystems - Beijing China sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
693d0231070Smiao chen - Sun Microsystems - Beijing China
694ae115bc7Smrj return ret;
695ae115bc7Smrj }
696ae115bc7Smrj
697ae115bc7Smrj /*ARGSUSED*/
i915_cmdbuffer(DRM_IOCTL_ARGS)698ae115bc7Smrj static int i915_cmdbuffer(DRM_IOCTL_ARGS)
699ae115bc7Smrj {
700ae115bc7Smrj DRM_DEVICE;
701ae115bc7Smrj drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
702ae115bc7Smrj drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
703ae115bc7Smrj dev_priv->sarea_priv;
704ae115bc7Smrj drm_i915_cmdbuffer_t cmdbuf;
705ae115bc7Smrj int ret;
706ae115bc7Smrj
707ae115bc7Smrj if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
708ae115bc7Smrj drm_i915_cmdbuffer32_t cmdbuffer32_t;
709ae115bc7Smrj
710d0538f66Scg149915 DRM_COPYFROM_WITH_RETURN(&cmdbuffer32_t,
711ae115bc7Smrj (drm_i915_cmdbuffer32_t __user *) data,
712ae115bc7Smrj sizeof (drm_i915_cmdbuffer32_t));
713ae115bc7Smrj
714ae115bc7Smrj cmdbuf.buf = (char __user *)(uintptr_t)cmdbuffer32_t.buf;
715ae115bc7Smrj cmdbuf.sz = cmdbuffer32_t.sz;
716ae115bc7Smrj cmdbuf.DR1 = cmdbuffer32_t.DR1;
717ae115bc7Smrj cmdbuf.DR4 = cmdbuffer32_t.DR4;
718ae115bc7Smrj cmdbuf.num_cliprects = cmdbuffer32_t.num_cliprects;
719ae115bc7Smrj cmdbuf.cliprects = (drm_clip_rect_t __user *)
720ae115bc7Smrj (uintptr_t)cmdbuffer32_t.cliprects;
721ae115bc7Smrj } else
722d0538f66Scg149915 DRM_COPYFROM_WITH_RETURN(&cmdbuf, (void *) data,
723ae115bc7Smrj sizeof(cmdbuf));
724ae115bc7Smrj
725ae115bc7Smrj DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
726ae115bc7Smrj cmdbuf.buf, cmdbuf.sz, cmdbuf.num_cliprects);
727ae115bc7Smrj
728d0538f66Scg149915 LOCK_TEST_WITH_RETURN(dev, fpriv);
729ae115bc7Smrj
730d0231070Smiao chen - Sun Microsystems - Beijing China /*
731ae115bc7Smrj if (cmdbuf.num_cliprects &&
732ae115bc7Smrj DRM_VERIFYAREA_READ(cmdbuf.cliprects,
733ae115bc7Smrj cmdbuf.num_cliprects *
734ae115bc7Smrj sizeof(drm_clip_rect_t))) {
735ae115bc7Smrj DRM_ERROR("Fault accessing cliprects\n");
736d0538f66Scg149915 return (EFAULT);
737ae115bc7Smrj }
738ae115bc7Smrj */
739ae115bc7Smrj
7400035d21cSmiao chen - Sun Microsystems - Beijing China spin_lock(&dev->struct_mutex);
741d0538f66Scg149915 ret = i915_dispatch_cmdbuffer(dev, &cmdbuf);
7420035d21cSmiao chen - Sun Microsystems - Beijing China spin_unlock(&dev->struct_mutex);
743ae115bc7Smrj if (ret) {
744ae115bc7Smrj DRM_ERROR("i915_dispatch_cmdbuffer failed\n");
745ae115bc7Smrj return ret;
746ae115bc7Smrj }
747ae115bc7Smrj
748d0231070Smiao chen - Sun Microsystems - Beijing China sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
749ae115bc7Smrj return 0;
750ae115bc7Smrj }
751ae115bc7Smrj
752ae115bc7Smrj /*ARGSUSED*/
i915_flip_bufs(DRM_IOCTL_ARGS)753ae115bc7Smrj static int i915_flip_bufs(DRM_IOCTL_ARGS)
754ae115bc7Smrj {
755ae115bc7Smrj DRM_DEVICE;
756d0231070Smiao chen - Sun Microsystems - Beijing China drm_i915_flip_t param;
7570035d21cSmiao chen - Sun Microsystems - Beijing China int ret;
758d0231070Smiao chen - Sun Microsystems - Beijing China DRM_COPYFROM_WITH_RETURN(¶m, (drm_i915_flip_t *) data,
759d0231070Smiao chen - Sun Microsystems - Beijing China sizeof(param));
760ae115bc7Smrj
761d0231070Smiao chen - Sun Microsystems - Beijing China DRM_DEBUG("i915_flip_bufs\n");
762ae115bc7Smrj
763d0538f66Scg149915 LOCK_TEST_WITH_RETURN(dev, fpriv);
7640035d21cSmiao chen - Sun Microsystems - Beijing China
7650035d21cSmiao chen - Sun Microsystems - Beijing China spin_lock(&dev->struct_mutex);
7660035d21cSmiao chen - Sun Microsystems - Beijing China ret = i915_dispatch_flip(dev, param.pipes);
7670035d21cSmiao chen - Sun Microsystems - Beijing China spin_unlock(&dev->struct_mutex);
7680035d21cSmiao chen - Sun Microsystems - Beijing China return ret;
769ae115bc7Smrj }
770ae115bc7Smrj
771ae115bc7Smrj /*ARGSUSED*/
i915_getparam(DRM_IOCTL_ARGS)772ae115bc7Smrj static int i915_getparam(DRM_IOCTL_ARGS)
773ae115bc7Smrj {
774ae115bc7Smrj DRM_DEVICE;
775ae115bc7Smrj drm_i915_private_t *dev_priv = dev->dev_private;
776ae115bc7Smrj drm_i915_getparam_t param;
777ae115bc7Smrj int value;
778ae115bc7Smrj
779ae115bc7Smrj if (!dev_priv) {
780ae115bc7Smrj DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
781d0538f66Scg149915 return (EINVAL);
782ae115bc7Smrj }
783ae115bc7Smrj
784ae115bc7Smrj if (ddi_model_convert_from(mode & FMODELS) == DDI_MODEL_ILP32) {
785ae115bc7Smrj drm_i915_getparam32_t getparam32_t;
786ae115bc7Smrj
787d0538f66Scg149915 DRM_COPYFROM_WITH_RETURN(&getparam32_t,
788ae115bc7Smrj (drm_i915_getparam32_t __user *) data,
789ae115bc7Smrj sizeof (drm_i915_getparam32_t));
790ae115bc7Smrj
791ae115bc7Smrj param.param = getparam32_t.param;
792ae115bc7Smrj param.value = (int __user *)(uintptr_t)getparam32_t.value;
793ae115bc7Smrj } else
794d0538f66Scg149915 DRM_COPYFROM_WITH_RETURN(¶m,
795d0538f66Scg149915 (drm_i915_getparam_t *) data, sizeof(param));
796ae115bc7Smrj
797ae115bc7Smrj switch (param.param) {
798ae115bc7Smrj case I915_PARAM_IRQ_ACTIVE:
799d0231070Smiao chen - Sun Microsystems - Beijing China value = dev->irq_enabled ? 1 : 0;
800ae115bc7Smrj break;
801ae115bc7Smrj case I915_PARAM_ALLOW_BATCHBUFFER:
802ae115bc7Smrj value = dev_priv->allow_batchbuffer ? 1 : 0;
803ae115bc7Smrj break;
804e92e3a86Szw161486 case I915_PARAM_LAST_DISPATCH:
805e92e3a86Szw161486 value = READ_BREADCRUMB(dev_priv);
806e92e3a86Szw161486 break;
807d0231070Smiao chen - Sun Microsystems - Beijing China case I915_PARAM_CHIPSET_ID:
808d0231070Smiao chen - Sun Microsystems - Beijing China value = dev->pci_device;
809d0231070Smiao chen - Sun Microsystems - Beijing China break;
8100035d21cSmiao chen - Sun Microsystems - Beijing China case I915_PARAM_HAS_GEM:
8110035d21cSmiao chen - Sun Microsystems - Beijing China value = dev->driver->use_gem;
8120035d21cSmiao chen - Sun Microsystems - Beijing China break;
813ae115bc7Smrj default:
8140035d21cSmiao chen - Sun Microsystems - Beijing China DRM_ERROR("Unknown get parameter %d\n", param.param);
815d0538f66Scg149915 return (EINVAL);
816ae115bc7Smrj }
817ae115bc7Smrj
818ae115bc7Smrj if (DRM_COPY_TO_USER(param.value, &value, sizeof(int))) {
819ae115bc7Smrj DRM_ERROR("i915_getparam failed\n");
820d0538f66Scg149915 return (EFAULT);
821ae115bc7Smrj }
822ae115bc7Smrj return 0;
823ae115bc7Smrj }
824ae115bc7Smrj
825ae115bc7Smrj /*ARGSUSED*/
i915_setparam(DRM_IOCTL_ARGS)826ae115bc7Smrj static int i915_setparam(DRM_IOCTL_ARGS)
827ae115bc7Smrj {
828ae115bc7Smrj DRM_DEVICE;
829ae115bc7Smrj drm_i915_private_t *dev_priv = dev->dev_private;
830ae115bc7Smrj drm_i915_setparam_t param;
831ae115bc7Smrj
832ae115bc7Smrj if (!dev_priv) {
833ae115bc7Smrj DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
834d0538f66Scg149915 return (EINVAL);
835ae115bc7Smrj }
836ae115bc7Smrj
837d0538f66Scg149915 DRM_COPYFROM_WITH_RETURN(¶m, (drm_i915_setparam_t *) data,
838ae115bc7Smrj sizeof(param));
839ae115bc7Smrj
840ae115bc7Smrj switch (param.param) {
841ae115bc7Smrj case I915_SETPARAM_USE_MI_BATCHBUFFER_START:
842ae115bc7Smrj break;
843ae115bc7Smrj case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY:
844ae115bc7Smrj dev_priv->tex_lru_log_granularity = param.value;
845ae115bc7Smrj break;
846ae115bc7Smrj case I915_SETPARAM_ALLOW_BATCHBUFFER:
847ae115bc7Smrj dev_priv->allow_batchbuffer = param.value;
848ae115bc7Smrj break;
849ae115bc7Smrj default:
8500035d21cSmiao chen - Sun Microsystems - Beijing China DRM_ERROR("unknown set parameter %d\n", param.param);
851d0538f66Scg149915 return (EINVAL);
852ae115bc7Smrj }
853ae115bc7Smrj
854ae115bc7Smrj return 0;
855ae115bc7Smrj }
856ae115bc7Smrj
857ae115bc7Smrj /*ARGSUSED*/
i915_set_status_page(DRM_IOCTL_ARGS)858dc8c6b69Sms148562 static int i915_set_status_page(DRM_IOCTL_ARGS)
859dc8c6b69Sms148562 {
860dc8c6b69Sms148562 DRM_DEVICE;
861dc8c6b69Sms148562 drm_i915_private_t *dev_priv = dev->dev_private;
862dc8c6b69Sms148562 drm_i915_hws_addr_t hws;
863dc8c6b69Sms148562
864fc6df3bdSmiao chen - Sun Microsystems - Beijing China if (!I915_NEED_GFX_HWS(dev))
865fc6df3bdSmiao chen - Sun Microsystems - Beijing China return (EINVAL);
866fc6df3bdSmiao chen - Sun Microsystems - Beijing China
867dc8c6b69Sms148562 if (!dev_priv) {
868dc8c6b69Sms148562 DRM_ERROR("%s called with no initialization\n", __FUNCTION__);
869dc8c6b69Sms148562 return (EINVAL);
870dc8c6b69Sms148562 }
871dc8c6b69Sms148562 DRM_COPYFROM_WITH_RETURN(&hws, (drm_i915_hws_addr_t __user *) data,
872dc8c6b69Sms148562 sizeof(hws));
8730035d21cSmiao chen - Sun Microsystems - Beijing China DRM_ERROR("i915_set_status_page set status page addr 0x%08x\n", (u32)hws.addr);
874dc8c6b69Sms148562
875dc8c6b69Sms148562 dev_priv->status_gfx_addr = hws.addr & (0x1ffff<<12);
876dc8c6b69Sms148562 DRM_DEBUG("set gfx_addr 0x%08x\n", dev_priv->status_gfx_addr);
877dc8c6b69Sms148562
878dc8c6b69Sms148562 dev_priv->hws_map.offset =
879dc8c6b69Sms148562 (u_offset_t)dev->agp->agp_info.agpi_aperbase + hws.addr;
880d0231070Smiao chen - Sun Microsystems - Beijing China dev_priv->hws_map.size = 4 * 1024; /* 4K pages */
881d0231070Smiao chen - Sun Microsystems - Beijing China dev_priv->hws_map.type = 0;
882dc8c6b69Sms148562 dev_priv->hws_map.flags = 0;
883dc8c6b69Sms148562 dev_priv->hws_map.mtrr = 0;
884dc8c6b69Sms148562
885dc8c6b69Sms148562 DRM_DEBUG("set status page: i915_set_status_page: mapoffset 0x%llx\n",
886dc8c6b69Sms148562 dev_priv->hws_map.offset);
887dc8c6b69Sms148562 drm_core_ioremap(&dev_priv->hws_map, dev);
888dc8c6b69Sms148562 if (dev_priv->hws_map.handle == NULL) {
889dc8c6b69Sms148562 dev->dev_private = (void *)dev_priv;
890dc8c6b69Sms148562 (void) i915_dma_cleanup(dev);
891dc8c6b69Sms148562 dev_priv->status_gfx_addr = 0;
892dc8c6b69Sms148562 DRM_ERROR("can not ioremap virtual address for"
893dc8c6b69Sms148562 " G33 hw status page\n");
894dc8c6b69Sms148562 return (ENOMEM);
895dc8c6b69Sms148562 }
896dc8c6b69Sms148562 dev_priv->hw_status_page = dev_priv->hws_map.dev_addr;
897dc8c6b69Sms148562
898dc8c6b69Sms148562 (void) memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
899d0231070Smiao chen - Sun Microsystems - Beijing China I915_WRITE(HWS_PGA, dev_priv->status_gfx_addr);
900dc8c6b69Sms148562 DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n",
901dc8c6b69Sms148562 dev_priv->status_gfx_addr);
902dc8c6b69Sms148562 DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page);
903dc8c6b69Sms148562 return 0;
904dc8c6b69Sms148562 }
905dc8c6b69Sms148562
906dc8c6b69Sms148562 /*ARGSUSED*/
i915_driver_load(drm_device_t * dev,unsigned long flags)907ae115bc7Smrj int i915_driver_load(drm_device_t *dev, unsigned long flags)
908ae115bc7Smrj {
90991fae470Scg149915 struct drm_i915_private *dev_priv;
9100035d21cSmiao chen - Sun Microsystems - Beijing China unsigned long base, size;
9110035d21cSmiao chen - Sun Microsystems - Beijing China int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1;
91291fae470Scg149915
913ae115bc7Smrj /* i915 has 4 more counters */
914ae115bc7Smrj dev->counters += 4;
915ae115bc7Smrj dev->types[6] = _DRM_STAT_IRQ;
916ae115bc7Smrj dev->types[7] = _DRM_STAT_PRIMARY;
917ae115bc7Smrj dev->types[8] = _DRM_STAT_SECONDARY;
918ae115bc7Smrj dev->types[9] = _DRM_STAT_DMA;
919ae115bc7Smrj
92091fae470Scg149915 dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER);
92191fae470Scg149915 if (dev_priv == NULL)
92291fae470Scg149915 return ENOMEM;
92391fae470Scg149915
92491fae470Scg149915 (void) memset(dev_priv, 0, sizeof(drm_i915_private_t));
92591fae470Scg149915 dev->dev_private = (void *)dev_priv;
926d0231070Smiao chen - Sun Microsystems - Beijing China dev_priv->dev = dev;
92791fae470Scg149915
9280035d21cSmiao chen - Sun Microsystems - Beijing China /* Add register map (needed for suspend/resume) */
9290035d21cSmiao chen - Sun Microsystems - Beijing China
9300035d21cSmiao chen - Sun Microsystems - Beijing China base = drm_get_resource_start(dev, mmio_bar);
9310035d21cSmiao chen - Sun Microsystems - Beijing China size = drm_get_resource_len(dev, mmio_bar);
9320035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->mmio_map = drm_alloc(sizeof (drm_local_map_t), DRM_MEM_MAPS);
9330035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->mmio_map->offset = base;
9340035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->mmio_map->size = size;
9350035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->mmio_map->type = _DRM_REGISTERS;
9360035d21cSmiao chen - Sun Microsystems - Beijing China dev_priv->mmio_map->flags = _DRM_REMOVABLE;
937*c1374a13SSurya Prakki (void) drm_ioremap(dev, dev_priv->mmio_map);
9380035d21cSmiao chen - Sun Microsystems - Beijing China
9390035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG("i915_driverload mmio %p mmio_map->dev_addr %x", dev_priv->mmio_map, dev_priv->mmio_map->dev_addr);
9400035d21cSmiao chen - Sun Microsystems - Beijing China
9410035d21cSmiao chen - Sun Microsystems - Beijing China #if defined(__i386)
9420035d21cSmiao chen - Sun Microsystems - Beijing China dev->driver->use_gem = 0;
9430035d21cSmiao chen - Sun Microsystems - Beijing China #else
9440035d21cSmiao chen - Sun Microsystems - Beijing China if (IS_I965G(dev)) {
9450035d21cSmiao chen - Sun Microsystems - Beijing China dev->driver->use_gem = 1;
9460035d21cSmiao chen - Sun Microsystems - Beijing China } else {
9470035d21cSmiao chen - Sun Microsystems - Beijing China dev->driver->use_gem = 0;
9480035d21cSmiao chen - Sun Microsystems - Beijing China }
9490035d21cSmiao chen - Sun Microsystems - Beijing China #endif /* __i386 */
9500035d21cSmiao chen - Sun Microsystems - Beijing China
9510035d21cSmiao chen - Sun Microsystems - Beijing China dev->driver->get_vblank_counter = i915_get_vblank_counter;
9520035d21cSmiao chen - Sun Microsystems - Beijing China dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
9530035d21cSmiao chen - Sun Microsystems - Beijing China #if defined(__i386)
9542e6e901dSmiao chen - Sun Microsystems - Beijing China if (IS_G4X(dev) || IS_IGDNG(dev) || IS_GM45(dev))
9550035d21cSmiao chen - Sun Microsystems - Beijing China #else
9562e6e901dSmiao chen - Sun Microsystems - Beijing China if (IS_G4X(dev) || IS_IGDNG(dev))
9570035d21cSmiao chen - Sun Microsystems - Beijing China #endif
9580035d21cSmiao chen - Sun Microsystems - Beijing China {
9590035d21cSmiao chen - Sun Microsystems - Beijing China dev->max_vblank_count = 0xffffffff; /* full 32 bit counter */
9600035d21cSmiao chen - Sun Microsystems - Beijing China dev->driver->get_vblank_counter = gm45_get_vblank_counter;
9610035d21cSmiao chen - Sun Microsystems - Beijing China }
9620035d21cSmiao chen - Sun Microsystems - Beijing China
9630035d21cSmiao chen - Sun Microsystems - Beijing China
9640035d21cSmiao chen - Sun Microsystems - Beijing China #ifdef I915_HAVE_GEM
9650035d21cSmiao chen - Sun Microsystems - Beijing China i915_gem_load(dev);
9660035d21cSmiao chen - Sun Microsystems - Beijing China #endif
9670035d21cSmiao chen - Sun Microsystems - Beijing China
9680035d21cSmiao chen - Sun Microsystems - Beijing China if (!I915_NEED_GFX_HWS(dev)) {
9690035d21cSmiao chen - Sun Microsystems - Beijing China ret = i915_init_hardware_status(dev);
9700035d21cSmiao chen - Sun Microsystems - Beijing China if(ret)
9710035d21cSmiao chen - Sun Microsystems - Beijing China return ret;
9720035d21cSmiao chen - Sun Microsystems - Beijing China }
9730035d21cSmiao chen - Sun Microsystems - Beijing China
974d0231070Smiao chen - Sun Microsystems - Beijing China mutex_init(&dev_priv->user_irq_lock, "userirq", MUTEX_DRIVER, NULL);
9750035d21cSmiao chen - Sun Microsystems - Beijing China mutex_init(&dev_priv->error_lock, "error_lock", MUTEX_DRIVER, NULL);
976d0231070Smiao chen - Sun Microsystems - Beijing China
9778566479dSEdward Shu ret = drm_vblank_init(dev, I915_NUM_PIPE);
9788566479dSEdward Shu if (ret) {
9798566479dSEdward Shu (void) i915_driver_unload(dev);
9808566479dSEdward Shu return ret;
9818566479dSEdward Shu }
9828566479dSEdward Shu
983d0231070Smiao chen - Sun Microsystems - Beijing China return ret;
984ae115bc7Smrj }
985ae115bc7Smrj
i915_driver_unload(struct drm_device * dev)98691fae470Scg149915 int i915_driver_unload(struct drm_device *dev)
98791fae470Scg149915 {
988d0231070Smiao chen - Sun Microsystems - Beijing China drm_i915_private_t *dev_priv = dev->dev_private;
989d0231070Smiao chen - Sun Microsystems - Beijing China
990d0231070Smiao chen - Sun Microsystems - Beijing China i915_free_hardware_status(dev);
991d0231070Smiao chen - Sun Microsystems - Beijing China
9920035d21cSmiao chen - Sun Microsystems - Beijing China drm_rmmap(dev, dev_priv->mmio_map);
9930035d21cSmiao chen - Sun Microsystems - Beijing China
994d0231070Smiao chen - Sun Microsystems - Beijing China mutex_destroy(&dev_priv->user_irq_lock);
995d0231070Smiao chen - Sun Microsystems - Beijing China
99691fae470Scg149915 drm_free(dev->dev_private, sizeof(drm_i915_private_t),
99791fae470Scg149915 DRM_MEM_DRIVER);
998d0231070Smiao chen - Sun Microsystems - Beijing China dev->dev_private = NULL;
99991fae470Scg149915
100091fae470Scg149915 return 0;
100191fae470Scg149915 }
100291fae470Scg149915
10030035d21cSmiao chen - Sun Microsystems - Beijing China /*ARGSUSED*/
i915_driver_open(drm_device_t * dev,struct drm_file * file_priv)10040035d21cSmiao chen - Sun Microsystems - Beijing China int i915_driver_open(drm_device_t * dev, struct drm_file *file_priv)
10050035d21cSmiao chen - Sun Microsystems - Beijing China {
10060035d21cSmiao chen - Sun Microsystems - Beijing China struct drm_i915_file_private *i915_file_priv;
10070035d21cSmiao chen - Sun Microsystems - Beijing China
10080035d21cSmiao chen - Sun Microsystems - Beijing China DRM_DEBUG("\n");
10090035d21cSmiao chen - Sun Microsystems - Beijing China i915_file_priv = (struct drm_i915_file_private *)
10100035d21cSmiao chen - Sun Microsystems - Beijing China drm_alloc(sizeof(*i915_file_priv), DRM_MEM_FILES);
10110035d21cSmiao chen - Sun Microsystems - Beijing China
10120035d21cSmiao chen - Sun Microsystems - Beijing China if (!i915_file_priv)
10130035d21cSmiao chen - Sun Microsystems - Beijing China return -ENOMEM;
10140035d21cSmiao chen - Sun Microsystems - Beijing China
10150035d21cSmiao chen - Sun Microsystems - Beijing China file_priv->driver_priv = i915_file_priv;
10160035d21cSmiao chen - Sun Microsystems - Beijing China
10170035d21cSmiao chen - Sun Microsystems - Beijing China i915_file_priv->mm.last_gem_seqno = 0;
10180035d21cSmiao chen - Sun Microsystems - Beijing China i915_file_priv->mm.last_gem_throttle_seqno = 0;
10190035d21cSmiao chen - Sun Microsystems - Beijing China
10200035d21cSmiao chen - Sun Microsystems - Beijing China return 0;
10210035d21cSmiao chen - Sun Microsystems - Beijing China }
102291fae470Scg149915
i915_driver_lastclose(drm_device_t * dev)1023ae115bc7Smrj void i915_driver_lastclose(drm_device_t * dev)
1024ae115bc7Smrj {
1025ae115bc7Smrj drm_i915_private_t *dev_priv = dev->dev_private;
1026d0231070Smiao chen - Sun Microsystems - Beijing China
1027d0231070Smiao chen - Sun Microsystems - Beijing China /* agp off can use this to get called before dev_priv */
1028d0231070Smiao chen - Sun Microsystems - Beijing China if (!dev_priv)
1029d0231070Smiao chen - Sun Microsystems - Beijing China return;
1030d0231070Smiao chen - Sun Microsystems - Beijing China
10310035d21cSmiao chen - Sun Microsystems - Beijing China #ifdef I915_HAVE_GEM
10320035d21cSmiao chen - Sun Microsystems - Beijing China i915_gem_lastclose(dev);
1033d0231070Smiao chen - Sun Microsystems - Beijing China #endif
1034d0231070Smiao chen - Sun Microsystems - Beijing China
1035d0231070Smiao chen - Sun Microsystems - Beijing China DRM_GETSAREA();
1036d0231070Smiao chen - Sun Microsystems - Beijing China if (dev_priv->agp_heap)
1037d0231070Smiao chen - Sun Microsystems - Beijing China i915_mem_takedown(&(dev_priv->agp_heap));
1038ae115bc7Smrj (void) i915_dma_cleanup(dev);
1039ae115bc7Smrj }
1040ae115bc7Smrj
i915_driver_preclose(drm_device_t * dev,drm_file_t * fpriv)1041d0538f66Scg149915 void i915_driver_preclose(drm_device_t * dev, drm_file_t *fpriv)
1042ae115bc7Smrj {
1043ae115bc7Smrj drm_i915_private_t *dev_priv = dev->dev_private;
1044d0538f66Scg149915 i915_mem_release(dev, fpriv, dev_priv->agp_heap);
1045ae115bc7Smrj }
10460035d21cSmiao chen - Sun Microsystems - Beijing China
10470035d21cSmiao chen - Sun Microsystems - Beijing China /*ARGSUSED*/
i915_driver_postclose(drm_device_t * dev,struct drm_file * file_priv)10480035d21cSmiao chen - Sun Microsystems - Beijing China void i915_driver_postclose(drm_device_t * dev, struct drm_file *file_priv)
10490035d21cSmiao chen - Sun Microsystems - Beijing China {
10500035d21cSmiao chen - Sun Microsystems - Beijing China struct drm_i915_file_private *i915_file_priv = file_priv->driver_priv;
10510035d21cSmiao chen - Sun Microsystems - Beijing China
10520035d21cSmiao chen - Sun Microsystems - Beijing China drm_free(i915_file_priv, sizeof(*i915_file_priv), DRM_MEM_FILES);
1053ae115bc7Smrj }
1054ae115bc7Smrj
1055ee33b1b8Smiao chen - Sun Microsystems - Beijing China drm_ioctl_desc_t i915_ioctls[] = {
1056ee33b1b8Smiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_INIT)] =
1057ee33b1b8Smiao chen - Sun Microsystems - Beijing China {i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1058ee33b1b8Smiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_FLUSH)] =
1059ee33b1b8Smiao chen - Sun Microsystems - Beijing China {i915_flush_ioctl, DRM_AUTH},
1060ee33b1b8Smiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_FLIP)] =
1061ee33b1b8Smiao chen - Sun Microsystems - Beijing China {i915_flip_bufs, DRM_AUTH},
1062ee33b1b8Smiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_BATCHBUFFER)] =
1063ee33b1b8Smiao chen - Sun Microsystems - Beijing China {i915_batchbuffer, DRM_AUTH},
1064ee33b1b8Smiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_IRQ_EMIT)] =
1065ee33b1b8Smiao chen - Sun Microsystems - Beijing China {i915_irq_emit, DRM_AUTH},
1066ee33b1b8Smiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_IRQ_WAIT)] =
1067ee33b1b8Smiao chen - Sun Microsystems - Beijing China {i915_irq_wait, DRM_AUTH},
1068ee33b1b8Smiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_GETPARAM)] =
1069ee33b1b8Smiao chen - Sun Microsystems - Beijing China {i915_getparam, DRM_AUTH},
1070ee33b1b8Smiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_SETPARAM)] =
1071ee33b1b8Smiao chen - Sun Microsystems - Beijing China {i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1072ee33b1b8Smiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_ALLOC)] =
1073ee33b1b8Smiao chen - Sun Microsystems - Beijing China {i915_mem_alloc, DRM_AUTH},
1074ee33b1b8Smiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_FREE)] =
1075ee33b1b8Smiao chen - Sun Microsystems - Beijing China {i915_mem_free, DRM_AUTH},
1076ee33b1b8Smiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_INIT_HEAP)] =
1077ee33b1b8Smiao chen - Sun Microsystems - Beijing China {i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1078ee33b1b8Smiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_CMDBUFFER)] =
1079ee33b1b8Smiao chen - Sun Microsystems - Beijing China {i915_cmdbuffer, DRM_AUTH},
1080ee33b1b8Smiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_DESTROY_HEAP)] =
1081ee33b1b8Smiao chen - Sun Microsystems - Beijing China {i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1082d0231070Smiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_SET_VBLANK_PIPE)] =
10830035d21cSmiao chen - Sun Microsystems - Beijing China {i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
1084d0231070Smiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_GET_VBLANK_PIPE)] =
1085d0231070Smiao chen - Sun Microsystems - Beijing China {i915_vblank_pipe_get, DRM_AUTH},
1086d0231070Smiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_VBLANK_SWAP)] =
1087d0231070Smiao chen - Sun Microsystems - Beijing China {i915_vblank_swap, DRM_AUTH},
1088ee33b1b8Smiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_HWS_ADDR)] =
1089ee33b1b8Smiao chen - Sun Microsystems - Beijing China {i915_set_status_page, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY},
10900035d21cSmiao chen - Sun Microsystems - Beijing China #ifdef I915_HAVE_GEM
10910035d21cSmiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_GEM_INIT)] =
10920035d21cSmiao chen - Sun Microsystems - Beijing China {i915_gem_init_ioctl, DRM_AUTH},
10930035d21cSmiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_GEM_EXECBUFFER)] =
10940035d21cSmiao chen - Sun Microsystems - Beijing China {i915_gem_execbuffer, DRM_AUTH},
10950035d21cSmiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_GEM_PIN)] =
10960035d21cSmiao chen - Sun Microsystems - Beijing China {i915_gem_pin_ioctl, DRM_AUTH|DRM_ROOT_ONLY},
10970035d21cSmiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_GEM_UNPIN)] =
10980035d21cSmiao chen - Sun Microsystems - Beijing China {i915_gem_unpin_ioctl, DRM_AUTH|DRM_ROOT_ONLY},
10990035d21cSmiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_GEM_BUSY)] =
11000035d21cSmiao chen - Sun Microsystems - Beijing China {i915_gem_busy_ioctl, DRM_AUTH},
11010035d21cSmiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_GEM_THROTTLE)] =
11020035d21cSmiao chen - Sun Microsystems - Beijing China {i915_gem_throttle_ioctl, DRM_AUTH},
11030035d21cSmiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_GEM_ENTERVT)] =
11040035d21cSmiao chen - Sun Microsystems - Beijing China {i915_gem_entervt_ioctl, DRM_AUTH},
11050035d21cSmiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_GEM_LEAVEVT)] =
11060035d21cSmiao chen - Sun Microsystems - Beijing China {i915_gem_leavevt_ioctl, DRM_AUTH},
11070035d21cSmiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_GEM_CREATE)] =
11080035d21cSmiao chen - Sun Microsystems - Beijing China {i915_gem_create_ioctl, 0},
11090035d21cSmiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_GEM_PREAD)] =
11100035d21cSmiao chen - Sun Microsystems - Beijing China {i915_gem_pread_ioctl, 0},
11110035d21cSmiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_GEM_PWRITE)] =
11120035d21cSmiao chen - Sun Microsystems - Beijing China {i915_gem_pwrite_ioctl, 0},
11130035d21cSmiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_GEM_MMAP)] =
11140035d21cSmiao chen - Sun Microsystems - Beijing China {i915_gem_mmap_ioctl, 0},
11150035d21cSmiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_GEM_SET_DOMAIN)] =
11160035d21cSmiao chen - Sun Microsystems - Beijing China {i915_gem_set_domain_ioctl, 0},
11170035d21cSmiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_GEM_SW_FINISH)] =
11180035d21cSmiao chen - Sun Microsystems - Beijing China {i915_gem_sw_finish_ioctl, 0},
11190035d21cSmiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_GEM_SET_TILING)] =
11200035d21cSmiao chen - Sun Microsystems - Beijing China {i915_gem_set_tiling, 0},
11210035d21cSmiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_GEM_GET_TILING)] =
11220035d21cSmiao chen - Sun Microsystems - Beijing China {i915_gem_get_tiling, 0},
11230035d21cSmiao chen - Sun Microsystems - Beijing China [DRM_IOCTL_NR(DRM_I915_GEM_GET_APERTURE)] =
11240035d21cSmiao chen - Sun Microsystems - Beijing China {i915_gem_get_aperture_ioctl, 0},
11250035d21cSmiao chen - Sun Microsystems - Beijing China #endif
1126ee33b1b8Smiao chen - Sun Microsystems - Beijing China };
1127ae115bc7Smrj
1128ee33b1b8Smiao chen - Sun Microsystems - Beijing China int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
1129ee33b1b8Smiao chen - Sun Microsystems - Beijing China
1130ae115bc7Smrj /**
1131ae115bc7Smrj * Determine if the device really is AGP or not.
1132ae115bc7Smrj *
1133ae115bc7Smrj * All Intel graphics chipsets are treated as AGP, even if they are really
1134ae115bc7Smrj * PCI-e.
1135ae115bc7Smrj *
1136ae115bc7Smrj * \param dev The device to be tested.
1137ae115bc7Smrj *
1138ae115bc7Smrj * \returns
1139ae115bc7Smrj * A value of 1 is always retured to indictate every i9x5 is AGP.
1140ae115bc7Smrj */
1141ae115bc7Smrj /*ARGSUSED*/
i915_driver_device_is_agp(drm_device_t * dev)1142ae115bc7Smrj int i915_driver_device_is_agp(drm_device_t * dev)
1143ae115bc7Smrj {
1144ae115bc7Smrj return 1;
1145ae115bc7Smrj }
1146d0231070Smiao chen - Sun Microsystems - Beijing China
1147