103b705cfSriastradh/************************************************************************** 203b705cfSriastradh 303b705cfSriastradhCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 403b705cfSriastradhCopyright © 2002 David Dawes 503b705cfSriastradh 603b705cfSriastradhAll Rights Reserved. 703b705cfSriastradh 803b705cfSriastradhPermission is hereby granted, free of charge, to any person obtaining a 903b705cfSriastradhcopy of this software and associated documentation files (the 1003b705cfSriastradh"Software"), to deal in the Software without restriction, including 1103b705cfSriastradhwithout limitation the rights to use, copy, modify, merge, publish, 1203b705cfSriastradhdistribute, sub license, and/or sell copies of the Software, and to 1303b705cfSriastradhpermit persons to whom the Software is furnished to do so, subject to 1403b705cfSriastradhthe following conditions: 1503b705cfSriastradh 1603b705cfSriastradhThe above copyright notice and this permission notice (including the 1703b705cfSriastradhnext paragraph) shall be included in all copies or substantial portions 1803b705cfSriastradhof the Software. 1903b705cfSriastradh 2003b705cfSriastradhTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 2103b705cfSriastradhOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 2203b705cfSriastradhMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 2303b705cfSriastradhIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 2403b705cfSriastradhANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 2503b705cfSriastradhTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 2603b705cfSriastradhSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2703b705cfSriastradh 2803b705cfSriastradh**************************************************************************/ 2903b705cfSriastradh 3003b705cfSriastradh#ifndef _INTEL_RING_H 3103b705cfSriastradh#define _INTEL_RING_H 3203b705cfSriastradh 3303b705cfSriastradh#define OUT_RING(n) do { \ 3403b705cfSriastradh if (I810_DEBUG & DEBUG_VERBOSE_RING) \ 3503b705cfSriastradh ErrorF("OUT_RING %lx: %x, (mask %x)\n", \ 3603b705cfSriastradh (unsigned long)(outring), (unsigned int)(n), ringmask); \ 3703b705cfSriastradh *(volatile unsigned int *)(virt + outring) = n; \ 3803b705cfSriastradh outring += 4; ringused += 4; \ 3903b705cfSriastradh outring &= ringmask; \ 4003b705cfSriastradh} while (0) 4103b705cfSriastradh 4203b705cfSriastradh#define ADVANCE_LP_RING() do { \ 4303b705cfSriastradh if (ringused > needed) \ 4403b705cfSriastradh FatalError("%s: ADVANCE_LP_RING: exceeded allocation %d/%d\n ", \ 4503b705cfSriastradh __FUNCTION__, ringused, needed); \ 4603b705cfSriastradh else if (ringused < needed) \ 4703b705cfSriastradh FatalError("%s: ADVANCE_LP_RING: under-used allocation %d/%d\n ", \ 4803b705cfSriastradh __FUNCTION__, ringused, needed); \ 4903b705cfSriastradh pI810->LpRing->tail = outring; \ 5003b705cfSriastradh pI810->LpRing->space -= ringused; \ 5103b705cfSriastradh if (outring & 0x07) \ 5203b705cfSriastradh FatalError("%s: ADVANCE_LP_RING: " \ 5303b705cfSriastradh "outring (0x%x) isn't on a QWord boundary\n", \ 5403b705cfSriastradh __FUNCTION__, outring); \ 5503b705cfSriastradh OUTREG(LP_RING + RING_TAIL, outring); \ 5603b705cfSriastradh} while (0) 5703b705cfSriastradh 5803b705cfSriastradh/* 5903b705cfSriastradh * XXX Note: the head/tail masks are different for 810 and i830. 6003b705cfSriastradh * If the i810 always sets the higher bits to 0, then this shouldn't be 6103b705cfSriastradh * a problem. Check this! 6203b705cfSriastradh */ 6303b705cfSriastradh#define DO_RING_IDLE() do { \ 6403b705cfSriastradh int _head; \ 6503b705cfSriastradh int _tail; \ 6603b705cfSriastradh do { \ 6703b705cfSriastradh _head = INREG(LP_RING + RING_HEAD) & I830_HEAD_MASK; \ 6803b705cfSriastradh _tail = INREG(LP_RING + RING_TAIL) & I830_TAIL_MASK; \ 6903b705cfSriastradh DELAY(10); \ 7003b705cfSriastradh } while (_head != _tail); \ 7103b705cfSriastradh} while( 0) 7203b705cfSriastradh 7303b705cfSriastradh#define BEGIN_LP_RING(n) \ 7403b705cfSriastradh unsigned int outring, ringmask, ringused = 0; \ 7503b705cfSriastradh volatile unsigned char *virt; \ 7642542f5fSchristos unsigned needed; \ 7703b705cfSriastradh if ((n) & 1) \ 7803b705cfSriastradh ErrorF("BEGIN_LP_RING called with odd argument: %d\n", n); \ 7903b705cfSriastradh if ((n) > 2 && (I810_DEBUG&DEBUG_ALWAYS_SYNC)) \ 8003b705cfSriastradh DO_RING_IDLE(); \ 8103b705cfSriastradh needed = (n) * 4; \ 8203b705cfSriastradh if (pI810->LpRing->space < needed) \ 8303b705cfSriastradh WaitRingFunc(pScrn, needed, 0); \ 8403b705cfSriastradh outring = pI810->LpRing->tail; \ 8503b705cfSriastradh ringmask = pI810->LpRing->tail_mask; \ 8603b705cfSriastradh virt = pI810->LpRing->virtual_start; \ 8703b705cfSriastradh if (I810_DEBUG & DEBUG_VERBOSE_RING) \ 8803b705cfSriastradh ErrorF( "BEGIN_LP_RING %d in %s\n", n, FUNCTION_NAME); 8903b705cfSriastradh 9003b705cfSriastradh#endif /* _INTEL_RING_H */ 91