1fa225cbcSrjs/**************************************************************************
2fa225cbcSrjs
3fa225cbcSrjsCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
4fa225cbcSrjsAll Rights Reserved.
5fa225cbcSrjs
6fa225cbcSrjsPermission is hereby granted, free of charge, to any person obtaining a
7fa225cbcSrjscopy of this software and associated documentation files (the
8fa225cbcSrjs"Software"), to deal in the Software without restriction, including
9fa225cbcSrjswithout limitation the rights to use, copy, modify, merge, publish,
10fa225cbcSrjsdistribute, sub license, and/or sell copies of the Software, and to
11fa225cbcSrjspermit persons to whom the Software is furnished to do so, subject to
12fa225cbcSrjsthe following conditions:
13fa225cbcSrjs
14fa225cbcSrjsThe above copyright notice and this permission notice (including the
15fa225cbcSrjsnext paragraph) shall be included in all copies or substantial portions
16fa225cbcSrjsof the Software.
17fa225cbcSrjs
18fa225cbcSrjsTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19fa225cbcSrjsOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20fa225cbcSrjsMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21fa225cbcSrjsIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
22fa225cbcSrjsANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23fa225cbcSrjsTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24fa225cbcSrjsSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25fa225cbcSrjs
26fa225cbcSrjs**************************************************************************/
27fa225cbcSrjs
28fa225cbcSrjs/*
29fa225cbcSrjs * Authors:
30fa225cbcSrjs *   Keith Whitwell <keith@tungstengraphics.com>
31fa225cbcSrjs *
32fa225cbcSrjs */
33fa225cbcSrjs
34fa225cbcSrjs/*
35fa225cbcSrjs * XXX So far, for GXxor this is about 40% of the speed of SW, but CPU
36fa225cbcSrjs * utilisation falls from 95% to < 5%.
37fa225cbcSrjs */
38fa225cbcSrjs
39fa225cbcSrjs#ifdef HAVE_CONFIG_H
40fa225cbcSrjs#include "config.h"
41fa225cbcSrjs#endif
42fa225cbcSrjs
43fa225cbcSrjs#include <errno.h>
44fa225cbcSrjs
4553ba5c8bSmrg#include "xorg-server.h"
46fa225cbcSrjs#include "xf86.h"
47fa225cbcSrjs#include "i830.h"
48fa225cbcSrjs#include "i810_reg.h"
49fa225cbcSrjs#include "i830_debug.h"
50fa225cbcSrjs#include "i830_ring.h"
51fa225cbcSrjs#include "i915_drm.h"
52fa225cbcSrjs
53fa225cbcSrjsunsigned long
54fa225cbcSrjsintel_get_pixmap_offset(PixmapPtr pPix)
55fa225cbcSrjs{
56fa225cbcSrjs    ScreenPtr pScreen = pPix->drawable.pScreen;
57fa225cbcSrjs    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
58fa225cbcSrjs    I830Ptr pI830 = I830PTR(pScrn);
59fa225cbcSrjs
60fa225cbcSrjs    return (unsigned long)pPix->devPrivate.ptr - (unsigned long)pI830->FbBase;
61fa225cbcSrjs}
62fa225cbcSrjs
63fa225cbcSrjsunsigned long
64fa225cbcSrjsintel_get_pixmap_pitch(PixmapPtr pPix)
65fa225cbcSrjs{
66fa225cbcSrjs    return (unsigned long)pPix->devKind;
67fa225cbcSrjs}
68fa225cbcSrjs
69fa225cbcSrjsint
70fa225cbcSrjsI830WaitLpRing(ScrnInfoPtr pScrn, int n, int timeout_millis)
71fa225cbcSrjs{
72fa225cbcSrjs   I830Ptr pI830 = I830PTR(pScrn);
73fa225cbcSrjs   I830RingBuffer *ring = &pI830->ring;
74fa225cbcSrjs   int iters = 0;
75fa225cbcSrjs   unsigned int start = 0;
76fa225cbcSrjs   unsigned int now = 0;
77fa225cbcSrjs   int last_head = 0;
78fa225cbcSrjs   unsigned int first = 0;
79fa225cbcSrjs
80fa225cbcSrjs   /* If your system hasn't moved the head pointer in 2 seconds, I'm going to
81fa225cbcSrjs    * call it crashed.
82fa225cbcSrjs    */
83fa225cbcSrjs   if (timeout_millis == 0)
84fa225cbcSrjs      timeout_millis = 2000;
85fa225cbcSrjs
86fa225cbcSrjs   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) {
87fa225cbcSrjs      ErrorF("I830WaitLpRing %d\n", n);
88fa225cbcSrjs      first = GetTimeInMillis();
89fa225cbcSrjs   }
90fa225cbcSrjs
91fa225cbcSrjs   while (ring->space < n) {
92fa225cbcSrjs      ring->head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK;
93fa225cbcSrjs      ring->space = ring->head - (ring->tail + 8);
94fa225cbcSrjs
95fa225cbcSrjs      if (ring->space < 0)
96fa225cbcSrjs	 ring->space += ring->mem->size;
97fa225cbcSrjs
98fa225cbcSrjs      iters++;
99fa225cbcSrjs      now = GetTimeInMillis();
100fa225cbcSrjs      if (start == 0 || now < start || ring->head != last_head) {
101fa225cbcSrjs	 if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
102fa225cbcSrjs	    if (now > start)
103fa225cbcSrjs	       ErrorF("space: %d wanted %d\n", ring->space, n);
104fa225cbcSrjs	 start = now;
105fa225cbcSrjs	 last_head = ring->head;
106fa225cbcSrjs      } else if (now - start > timeout_millis) {
107fa225cbcSrjs	 ErrorF("Error in I830WaitLpRing(), timeout for %d seconds\n",
108fa225cbcSrjs		timeout_millis/1000);
109fa225cbcSrjs	 if (IS_I965G(pI830))
110fa225cbcSrjs	     i965_dump_error_state(pScrn);
111fa225cbcSrjs	 else
112fa225cbcSrjs	     i830_dump_error_state(pScrn);
113fa225cbcSrjs	 ErrorF("space: %d wanted %d\n", ring->space, n);
114fa225cbcSrjs	 pI830->uxa_driver = NULL;
115fa225cbcSrjs	 FatalError("lockup\n");
116fa225cbcSrjs      }
117fa225cbcSrjs
118fa225cbcSrjs      DELAY(10);
119fa225cbcSrjs   }
120fa225cbcSrjs
121fa225cbcSrjs   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL) {
122fa225cbcSrjs      now = GetTimeInMillis();
123fa225cbcSrjs      if (now - first) {
124fa225cbcSrjs	 ErrorF("Elapsed %u ms\n", now - first);
125fa225cbcSrjs	 ErrorF("space: %d wanted %d\n", ring->space, n);
126fa225cbcSrjs      }
127fa225cbcSrjs   }
128fa225cbcSrjs
129fa225cbcSrjs   return iters;
130fa225cbcSrjs}
131fa225cbcSrjs
132fa225cbcSrjsvoid
133fa225cbcSrjsI830Sync(ScrnInfoPtr pScrn)
134fa225cbcSrjs{
135fa225cbcSrjs   I830Ptr pI830 = I830PTR(pScrn);
136fa225cbcSrjs
137fa225cbcSrjs   if (I810_DEBUG & (DEBUG_VERBOSE_ACCEL | DEBUG_VERBOSE_SYNC))
138fa225cbcSrjs      ErrorF("I830Sync\n");
139fa225cbcSrjs
140fa225cbcSrjs   if (!pScrn->vtSema || !pI830->batch_bo)
141fa225cbcSrjs       return;
142fa225cbcSrjs
143fa225cbcSrjs   I830EmitFlush(pScrn);
144fa225cbcSrjs
145fa225cbcSrjs   intel_batch_flush(pScrn, TRUE);
146fa225cbcSrjs   intel_batch_wait_last(pScrn);
147fa225cbcSrjs}
148fa225cbcSrjs
149fa225cbcSrjsvoid
150fa225cbcSrjsI830EmitFlush(ScrnInfoPtr pScrn)
151fa225cbcSrjs{
152fa225cbcSrjs   I830Ptr pI830 = I830PTR(pScrn);
153fa225cbcSrjs   int flags = MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE;
154fa225cbcSrjs
155fa225cbcSrjs   if (IS_I965G(pI830))
156fa225cbcSrjs      flags = 0;
157fa225cbcSrjs
158fa225cbcSrjs   {
159fa225cbcSrjs       BEGIN_BATCH(1);
160fa225cbcSrjs       OUT_BATCH(MI_FLUSH | flags);
161fa225cbcSrjs       ADVANCE_BATCH();
162fa225cbcSrjs   }
163fa225cbcSrjs}
164fa225cbcSrjs
165fa225cbcSrjs
166fa225cbcSrjs#if (ALWAYS_SYNC || ALWAYS_FLUSH)
167fa225cbcSrjsvoid
168fa225cbcSrjsi830_debug_sync(ScrnInfoPtr scrn)
169fa225cbcSrjs{
170fa225cbcSrjs    if (ALWAYS_SYNC)
171fa225cbcSrjs	I830Sync(scrn);
172fa225cbcSrjs    else
173fa225cbcSrjs	intel_batch_flush(scrn, FALSE);
174fa225cbcSrjs}
175fa225cbcSrjs#endif
176fa225cbcSrjs
177fa225cbcSrjs/* The following function sets up the supported acceleration. Call it
178fa225cbcSrjs * from the FbInit() function in the SVGA driver, or before ScreenInit
179fa225cbcSrjs * in a monolithic server.
180fa225cbcSrjs */
181fa225cbcSrjsBool
182fa225cbcSrjsI830AccelInit(ScreenPtr pScreen)
183fa225cbcSrjs{
184fa225cbcSrjs    ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
185fa225cbcSrjs    I830Ptr pI830 = I830PTR(pScrn);
186fa225cbcSrjs
187fa225cbcSrjs    /* Limits are described in the BLT engine chapter under Graphics Data Size
188fa225cbcSrjs     * Limitations, and the descriptions of SURFACE_STATE, 3DSTATE_BUFFER_INFO,
189fa225cbcSrjs     * 3DSTATE_DRAWING_RECTANGLE, 3DSTATE_MAP_INFO, and 3DSTATE_MAP_INFO.
190fa225cbcSrjs     *
191fa225cbcSrjs     * i845 through i965 limits 2D rendering to 65536 lines and pitch of 32768.
192fa225cbcSrjs     *
193fa225cbcSrjs     * i965 limits 3D surface to (2*element size)-aligned offset if un-tiled.
194fa225cbcSrjs     * i965 limits 3D surface to 4kB-aligned offset if tiled.
195fa225cbcSrjs     * i965 limits 3D surfaces to w,h of ?,8192.
196fa225cbcSrjs     * i965 limits 3D surface to pitch of 1B - 128kB.
197fa225cbcSrjs     * i965 limits 3D surface pitch alignment to 1 or 2 times the element size.
198fa225cbcSrjs     * i965 limits 3D surface pitch alignment to 512B if tiled.
199fa225cbcSrjs     * i965 limits 3D destination drawing rect to w,h of 8192,8192.
200fa225cbcSrjs     *
201fa225cbcSrjs     * i915 limits 3D textures to 4B-aligned offset if un-tiled.
202fa225cbcSrjs     * i915 limits 3D textures to ~4kB-aligned offset if tiled.
203fa225cbcSrjs     * i915 limits 3D textures to width,height of 2048,2048.
204fa225cbcSrjs     * i915 limits 3D textures to pitch of 16B - 8kB, in dwords.
205fa225cbcSrjs     * i915 limits 3D destination to ~4kB-aligned offset if tiled.
206fa225cbcSrjs     * i915 limits 3D destination to pitch of 16B - 8kB, in dwords, if un-tiled.
207fa225cbcSrjs     * i915 limits 3D destination to pitch 64B-aligned if used with depth.
208fa225cbcSrjs     * i915 limits 3D destination to pitch of 512B - 8kB, in tiles, if tiled.
209fa225cbcSrjs     * i915 limits 3D destination to POT aligned pitch if tiled.
210fa225cbcSrjs     * i915 limits 3D destination drawing rect to w,h of 2048,2048.
211fa225cbcSrjs     *
212fa225cbcSrjs     * i845 limits 3D textures to 4B-aligned offset if un-tiled.
213fa225cbcSrjs     * i845 limits 3D textures to ~4kB-aligned offset if tiled.
214fa225cbcSrjs     * i845 limits 3D textures to width,height of 2048,2048.
215fa225cbcSrjs     * i845 limits 3D textures to pitch of 4B - 8kB, in dwords.
216fa225cbcSrjs     * i845 limits 3D destination to 4B-aligned offset if un-tiled.
217fa225cbcSrjs     * i845 limits 3D destination to ~4kB-aligned offset if tiled.
218fa225cbcSrjs     * i845 limits 3D destination to pitch of 8B - 8kB, in dwords.
219fa225cbcSrjs     * i845 limits 3D destination drawing rect to w,h of 2048,2048.
220fa225cbcSrjs     *
221fa225cbcSrjs     * For the tiled issues, the only tiled buffer we draw to should be
222fa225cbcSrjs     * the front, which will have an appropriate pitch/offset already set up,
223fa225cbcSrjs     * so UXA doesn't need to worry.
224fa225cbcSrjs     */
225fa225cbcSrjs    if (IS_I965G(pI830)) {
226fa225cbcSrjs	pI830->accel_pixmap_offset_alignment = 4 * 2;
227fa225cbcSrjs	pI830->accel_pixmap_pitch_alignment = 64;
228fa225cbcSrjs	pI830->accel_max_x = 8192;
229fa225cbcSrjs	pI830->accel_max_y = 8192;
230fa225cbcSrjs    } else {
231fa225cbcSrjs	pI830->accel_pixmap_offset_alignment = 4;
232fa225cbcSrjs	pI830->accel_pixmap_pitch_alignment = 64;
233fa225cbcSrjs	pI830->accel_max_x = 2048;
234fa225cbcSrjs	pI830->accel_max_y = 2048;
235fa225cbcSrjs    }
236fa225cbcSrjs
237fa225cbcSrjs    return i830_uxa_init(pScreen);
238fa225cbcSrjs}
239