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