103b705cfSriastradh
203b705cfSriastradh/**************************************************************************
303b705cfSriastradh
403b705cfSriastradhCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
503b705cfSriastradhAll Rights Reserved.
603b705cfSriastradh
703b705cfSriastradhPermission is hereby granted, free of charge, to any person obtaining a
803b705cfSriastradhcopy of this software and associated documentation files (the
903b705cfSriastradh"Software"), to deal in the Software without restriction, including
1003b705cfSriastradhwithout limitation the rights to use, copy, modify, merge, publish,
1103b705cfSriastradhdistribute, sub license, and/or sell copies of the Software, and to
1203b705cfSriastradhpermit persons to whom the Software is furnished to do so, subject to
1303b705cfSriastradhthe following conditions:
1403b705cfSriastradh
1503b705cfSriastradhThe above copyright notice and this permission notice (including the
1603b705cfSriastradhnext paragraph) shall be included in all copies or substantial portions
1703b705cfSriastradhof the Software.
1803b705cfSriastradh
1903b705cfSriastradhTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
2003b705cfSriastradhOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
2103b705cfSriastradhMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
2203b705cfSriastradhIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
2303b705cfSriastradhANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
2403b705cfSriastradhTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
2503b705cfSriastradhSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2603b705cfSriastradh
2703b705cfSriastradh**************************************************************************/
2803b705cfSriastradh
2903b705cfSriastradh#ifdef HAVE_CONFIG_H
3003b705cfSriastradh#include "config.h"
3103b705cfSriastradh#endif
3203b705cfSriastradh
3303b705cfSriastradh/*
3403b705cfSriastradh * Authors:
3503b705cfSriastradh *   Keith Whitwell <keith@tungstengraphics.com>
3603b705cfSriastradh *
3703b705cfSriastradh */
3803b705cfSriastradh
3942542f5fSchristos#include "xorg-server.h"
4003b705cfSriastradh#include "xf86.h"
4103b705cfSriastradh#include "xaarop.h"
4203b705cfSriastradh#include "i810.h"
4303b705cfSriastradh
4403b705cfSriastradhstatic void
4503b705cfSriastradhI810SetupForMono8x8PatternFill(ScrnInfoPtr pScrn, int pattx, int patty,
4603b705cfSriastradh			       int fg, int bg, int rop,
4703b705cfSriastradh			       unsigned int planemask)
4803b705cfSriastradh{
4903b705cfSriastradh   I810Ptr pI810 = I810PTR(pScrn);
5003b705cfSriastradh
5103b705cfSriastradh   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
5203b705cfSriastradh      ErrorF("I810SetupFor8x8PatternColorExpand\n");
5303b705cfSriastradh
5403b705cfSriastradh   /* FULL_MONO_PAT_BLT, p176 */
5503b705cfSriastradh   pI810->BR[0] = (BR00_BITBLT_CLIENT | BR00_OP_MONO_PAT_BLT | 0x9);
5603b705cfSriastradh   pI810->BR[18] = bg;
5703b705cfSriastradh   pI810->BR[19] = fg;
5803b705cfSriastradh   pI810->BR[13] = (pScrn->displayWidth * pI810->cpp);
5903b705cfSriastradh   pI810->BR[13] |= I810PatternROP[rop] << 16;
6003b705cfSriastradh   if (bg == -1)
6103b705cfSriastradh      pI810->BR[13] |= BR13_MONO_PATN_TRANS;
6203b705cfSriastradh}
6303b705cfSriastradh
6403b705cfSriastradhstatic void
6503b705cfSriastradhI810SubsequentMono8x8PatternFillRect(ScrnInfoPtr pScrn, int pattx, int patty,
6603b705cfSriastradh				     int x, int y, int w, int h)
6703b705cfSriastradh{
6803b705cfSriastradh   I810Ptr pI810 = I810PTR(pScrn);
6903b705cfSriastradh   int addr =
7003b705cfSriastradh	 pI810->bufferOffset + (y * pScrn->displayWidth + x) * pI810->cpp;
7103b705cfSriastradh
7203b705cfSriastradh   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
7303b705cfSriastradh      ErrorF("I810Subsequent8x8PatternColorExpand\n");
7403b705cfSriastradh
7503b705cfSriastradh   {
7603b705cfSriastradh      BEGIN_LP_RING(12);
7703b705cfSriastradh      OUT_RING(pI810->BR[0] | ((y << 5) & BR00_PAT_VERT_ALIGN));
7803b705cfSriastradh      OUT_RING(pI810->BR[13]);
7903b705cfSriastradh      OUT_RING((h << 16) | (w * pI810->cpp));
8003b705cfSriastradh      OUT_RING(addr);
8103b705cfSriastradh      OUT_RING(pI810->BR[13] & 0xFFFF);	/* src pitch */
8203b705cfSriastradh      OUT_RING(addr);			/* src addr */
8303b705cfSriastradh      OUT_RING(0);			/* transparency color */
8403b705cfSriastradh      OUT_RING(pI810->BR[18]);		/* bg */
8503b705cfSriastradh      OUT_RING(pI810->BR[19]);		/* fg */
8603b705cfSriastradh      OUT_RING(pattx);			/* pattern data */
8703b705cfSriastradh      OUT_RING(patty);
8803b705cfSriastradh      OUT_RING(0);
8903b705cfSriastradh      ADVANCE_LP_RING();
9003b705cfSriastradh   }
9103b705cfSriastradh}
9203b705cfSriastradh
9303b705cfSriastradhstatic void
9403b705cfSriastradhI810GetNextScanlineColorExpandBuffer(ScrnInfoPtr pScrn)
9503b705cfSriastradh{
9603b705cfSriastradh   I810Ptr pI810 = I810PTR(pScrn);
9703b705cfSriastradh   XAAInfoRecPtr infoPtr = pI810->AccelInfoRec;
9803b705cfSriastradh
9903b705cfSriastradh   if (pI810->nextColorExpandBuf == pI810->NumScanlineColorExpandBuffers)
10003b705cfSriastradh      I810Sync(pScrn);
10103b705cfSriastradh
10203b705cfSriastradh   infoPtr->ScanlineColorExpandBuffers[0] =
10303b705cfSriastradh	 pI810->ScanlineColorExpandBuffers[pI810->nextColorExpandBuf];
10403b705cfSriastradh
10503b705cfSriastradh   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
10603b705cfSriastradh      ErrorF("using color expand buffer %d\n", pI810->nextColorExpandBuf);
10703b705cfSriastradh
10803b705cfSriastradh   pI810->nextColorExpandBuf++;
10903b705cfSriastradh}
11003b705cfSriastradh
11103b705cfSriastradhstatic void
11203b705cfSriastradhI810SetupForScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
11303b705cfSriastradh					       int fg, int bg, int rop,
11403b705cfSriastradh					       unsigned int planemask)
11503b705cfSriastradh{
11603b705cfSriastradh   I810Ptr pI810 = I810PTR(pScrn);
11703b705cfSriastradh
11803b705cfSriastradh   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
11903b705cfSriastradh      ErrorF("I810SetupForScanlineScreenToScreenColorExpand %d %d %x %x\n",
12003b705cfSriastradh	     fg, bg, rop, planemask);
12103b705cfSriastradh
12203b705cfSriastradh   pI810->BR[13] = (pScrn->displayWidth * pI810->cpp);
12303b705cfSriastradh   pI810->BR[13] |= I810CopyROP[rop] << 16;
12403b705cfSriastradh   pI810->BR[13] |= (1 << 27);
12503b705cfSriastradh   if (bg == -1)
12603b705cfSriastradh      pI810->BR[13] |= BR13_MONO_TRANSPCY;
12703b705cfSriastradh
12803b705cfSriastradh   pI810->BR[18] = bg;
12903b705cfSriastradh   pI810->BR[19] = fg;
13003b705cfSriastradh
13103b705cfSriastradh   I810GetNextScanlineColorExpandBuffer(pScrn);
13203b705cfSriastradh}
13303b705cfSriastradh
13403b705cfSriastradhstatic void
13503b705cfSriastradhI810SubsequentScanlineCPUToScreenColorExpandFill(ScrnInfoPtr pScrn,
13603b705cfSriastradh						 int x, int y,
13703b705cfSriastradh						 int w, int h, int skipleft)
13803b705cfSriastradh{
13903b705cfSriastradh   I810Ptr pI810 = I810PTR(pScrn);
14003b705cfSriastradh
14103b705cfSriastradh   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
14203b705cfSriastradh      ErrorF("I810SubsequentScanlineCPUToScreenColorExpandFill "
14303b705cfSriastradh	     "%d,%d %dx%x %d\n", x, y, w, h, skipleft);
14403b705cfSriastradh
14503b705cfSriastradh   pI810->BR[0] = BR00_BITBLT_CLIENT | BR00_OP_MONO_SRC_COPY_BLT | 0x06;
14603b705cfSriastradh   pI810->BR[9] = (pI810->bufferOffset +
14703b705cfSriastradh		   (y * pScrn->displayWidth + x) * pI810->cpp);
14803b705cfSriastradh   pI810->BR[14] = ((1 << 16) | (w * pI810->cpp));
14903b705cfSriastradh   pI810->BR[11] = ((w + 31) / 32) - 1;
15003b705cfSriastradh}
15103b705cfSriastradh
15203b705cfSriastradhstatic void
15303b705cfSriastradhI810SubsequentColorExpandScanline(ScrnInfoPtr pScrn, int bufno)
15403b705cfSriastradh{
15503b705cfSriastradh   I810Ptr pI810 = I810PTR(pScrn);
15603b705cfSriastradh
15703b705cfSriastradh   pI810->BR[12] = (pI810->AccelInfoRec->ScanlineColorExpandBuffers[0] -
15803b705cfSriastradh		    pI810->FbBase);
15903b705cfSriastradh
16003b705cfSriastradh   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
16103b705cfSriastradh      ErrorF("I810SubsequentColorExpandScanline %d (addr %x)\n",
16203b705cfSriastradh	     bufno, pI810->BR[12]);
16303b705cfSriastradh
16403b705cfSriastradh   {
16503b705cfSriastradh      BEGIN_LP_RING(8);
16603b705cfSriastradh      OUT_RING(pI810->BR[0]);
16703b705cfSriastradh      OUT_RING(pI810->BR[13]);
16803b705cfSriastradh      OUT_RING(pI810->BR[14]);
16903b705cfSriastradh      OUT_RING(pI810->BR[9]);
17003b705cfSriastradh      OUT_RING(pI810->BR[11]);
17103b705cfSriastradh      OUT_RING(pI810->BR[12]);		/* srcaddr */
17203b705cfSriastradh      OUT_RING(pI810->BR[18]);
17303b705cfSriastradh      OUT_RING(pI810->BR[19]);
17403b705cfSriastradh      ADVANCE_LP_RING();
17503b705cfSriastradh   }
17603b705cfSriastradh
17703b705cfSriastradh   /* Advance to next scanline.
17803b705cfSriastradh    */
17903b705cfSriastradh   pI810->BR[9] += pScrn->displayWidth * pI810->cpp;
18003b705cfSriastradh   I810GetNextScanlineColorExpandBuffer(pScrn);
18103b705cfSriastradh}
18203b705cfSriastradh
18303b705cfSriastradh/* Emit on gaining VT?
18403b705cfSriastradh */
18503b705cfSriastradh#if 0
18603b705cfSriastradhstatic void
18703b705cfSriastradhI810EmitInvarientState(ScrnInfoPtr pScrn)
18803b705cfSriastradh{
18903b705cfSriastradh   I810Ptr pI810 = I810PTR(pScrn);
19003b705cfSriastradh
19103b705cfSriastradh   BEGIN_LP_RING(10);
19203b705cfSriastradh
19303b705cfSriastradh   OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
19403b705cfSriastradh   OUT_RING(GFX_CMD_CONTEXT_SEL | CS_UPDATE_USE | CS_USE_CTX0);
19503b705cfSriastradh   OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
19603b705cfSriastradh   OUT_RING(0);
19703b705cfSriastradh
19803b705cfSriastradh   OUT_RING(GFX_OP_COLOR_CHROMA_KEY);
19903b705cfSriastradh   OUT_RING(CC1_UPDATE_KILL_WRITE |
20003b705cfSriastradh	    CC1_DISABLE_KILL_WRITE |
20103b705cfSriastradh	    CC1_UPDATE_COLOR_IDX |
20203b705cfSriastradh	    CC1_UPDATE_CHROMA_LOW | CC1_UPDATE_CHROMA_HI | 0);
20303b705cfSriastradh   OUT_RING(0);
20403b705cfSriastradh   OUT_RING(0);
20503b705cfSriastradh
20603b705cfSriastradh/*     OUT_RING( CMD_OP_Z_BUFFER_INFO ); */
20703b705cfSriastradh/*     OUT_RING( pI810->DepthBuffer.Start | pI810->auxPitchBits); */
20803b705cfSriastradh
20903b705cfSriastradh   ADVANCE_LP_RING();
21003b705cfSriastradh}
21103b705cfSriastradh#endif
21203b705cfSriastradh
21303b705cfSriastradh/* The following function sets up the supported acceleration. Call it
21403b705cfSriastradh * from the FbInit() function in the SVGA driver, or before ScreenInit
21503b705cfSriastradh * in a monolithic server.
21603b705cfSriastradh */
21703b705cfSriastradhBool
21803b705cfSriastradhI810AccelInit(ScreenPtr pScreen)
21903b705cfSriastradh{
22003b705cfSriastradh   XAAInfoRecPtr infoPtr;
22103b705cfSriastradh   ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
22203b705cfSriastradh   I810Ptr pI810 = I810PTR(pScrn);
22303b705cfSriastradh
22403b705cfSriastradh   if (I810_DEBUG & DEBUG_VERBOSE_ACCEL)
22503b705cfSriastradh      ErrorF("I810AccelInit\n");
22603b705cfSriastradh
22703b705cfSriastradh   pI810->AccelInfoRec = infoPtr = XAACreateInfoRec();
22803b705cfSriastradh   if (!infoPtr)
22903b705cfSriastradh      return FALSE;
23003b705cfSriastradh
23103b705cfSriastradh   pI810->bufferOffset = 0;
23203b705cfSriastradh   infoPtr->Flags = LINEAR_FRAMEBUFFER | OFFSCREEN_PIXMAPS;
23303b705cfSriastradh   infoPtr->Flags |= PIXMAP_CACHE;
23403b705cfSriastradh
23503b705cfSriastradh   /* Sync
23603b705cfSriastradh    */
23703b705cfSriastradh   infoPtr->Sync = I810Sync;
23803b705cfSriastradh
23903b705cfSriastradh   /* Solid filled rectangles
24003b705cfSriastradh    */
24103b705cfSriastradh   {
24203b705cfSriastradh      infoPtr->SolidFillFlags = NO_PLANEMASK;
24303b705cfSriastradh      infoPtr->SetupForSolidFill = I810SetupForSolidFill;
24403b705cfSriastradh      infoPtr->SubsequentSolidFillRect = I810SubsequentSolidFillRect;
24503b705cfSriastradh   }
24603b705cfSriastradh
24703b705cfSriastradh   /* Screen to screen copy
24803b705cfSriastradh    *   - the transparency op hangs the blit engine, disable for now.
24903b705cfSriastradh    */
25003b705cfSriastradh   {
25103b705cfSriastradh      infoPtr->ScreenToScreenCopyFlags = (0
25203b705cfSriastradh					  | NO_PLANEMASK
25303b705cfSriastradh					  | NO_TRANSPARENCY | 0);
25403b705cfSriastradh
25503b705cfSriastradh      infoPtr->SetupForScreenToScreenCopy = I810SetupForScreenToScreenCopy;
25603b705cfSriastradh      infoPtr->SubsequentScreenToScreenCopy =
25703b705cfSriastradh	    I810SubsequentScreenToScreenCopy;
25803b705cfSriastradh   }
25903b705cfSriastradh
26003b705cfSriastradh   /* 8x8 pattern fills
26103b705cfSriastradh    */
26203b705cfSriastradh   {
26303b705cfSriastradh      infoPtr->SetupForMono8x8PatternFill = I810SetupForMono8x8PatternFill;
26403b705cfSriastradh      infoPtr->SubsequentMono8x8PatternFillRect =
26503b705cfSriastradh	    I810SubsequentMono8x8PatternFillRect;
26603b705cfSriastradh
26703b705cfSriastradh      infoPtr->Mono8x8PatternFillFlags = (HARDWARE_PATTERN_PROGRAMMED_BITS |
26803b705cfSriastradh					  HARDWARE_PATTERN_SCREEN_ORIGIN |
26903b705cfSriastradh					  BIT_ORDER_IN_BYTE_MSBFIRST |
27003b705cfSriastradh					  NO_PLANEMASK | 0);
27103b705cfSriastradh   }
27203b705cfSriastradh
27303b705cfSriastradh   /* 8x8 color fills - not considered useful for XAA.
27403b705cfSriastradh    */
27503b705cfSriastradh
27603b705cfSriastradh   /* Scanline color expansion - Use the same scheme as the 3.3 driver.
27703b705cfSriastradh    *
27803b705cfSriastradh    */
27903b705cfSriastradh   if (pI810->Scratch.Size != 0) {
28003b705cfSriastradh      int i;
28103b705cfSriastradh      int width = ALIGN(pScrn->displayWidth, 32) / 8;
28203b705cfSriastradh      int nr_buffers = pI810->Scratch.Size / width;
28303b705cfSriastradh      unsigned char *ptr = pI810->FbBase + pI810->Scratch.Start;
28403b705cfSriastradh
28503b705cfSriastradh      pI810->NumScanlineColorExpandBuffers = nr_buffers;
28603b705cfSriastradh      pI810->ScanlineColorExpandBuffers = (unsigned char **)
28703b705cfSriastradh	    xnfcalloc(nr_buffers, sizeof(unsigned char *));
28803b705cfSriastradh
28903b705cfSriastradh      for (i = 0; i < nr_buffers; i++, ptr += width)
29003b705cfSriastradh	 pI810->ScanlineColorExpandBuffers[i] = ptr;
29103b705cfSriastradh
29203b705cfSriastradh      infoPtr->ScanlineCPUToScreenColorExpandFillFlags = (NO_PLANEMASK |
29303b705cfSriastradh							  ROP_NEEDS_SOURCE |
29403b705cfSriastradh							  BIT_ORDER_IN_BYTE_MSBFIRST
29503b705cfSriastradh							  | 0);
29603b705cfSriastradh
29703b705cfSriastradh      infoPtr->ScanlineColorExpandBuffers = (unsigned char **)
29803b705cfSriastradh	    xnfcalloc(1, sizeof(unsigned char *));
29903b705cfSriastradh      infoPtr->NumScanlineColorExpandBuffers = 1;
30003b705cfSriastradh
30103b705cfSriastradh      infoPtr->ScanlineColorExpandBuffers[0] =
30203b705cfSriastradh	    pI810->ScanlineColorExpandBuffers[0];
30303b705cfSriastradh      pI810->nextColorExpandBuf = 0;
30403b705cfSriastradh
30503b705cfSriastradh      infoPtr->SetupForScanlineCPUToScreenColorExpandFill =
30603b705cfSriastradh	    I810SetupForScanlineCPUToScreenColorExpandFill;
30703b705cfSriastradh
30803b705cfSriastradh      infoPtr->SubsequentScanlineCPUToScreenColorExpandFill =
30903b705cfSriastradh	    I810SubsequentScanlineCPUToScreenColorExpandFill;
31003b705cfSriastradh
31103b705cfSriastradh      infoPtr->SubsequentColorExpandScanline =
31203b705cfSriastradh	    I810SubsequentColorExpandScanline;
31303b705cfSriastradh   }
31403b705cfSriastradh
31503b705cfSriastradh   /* Possible todo: Image writes w/ non-GXCOPY rop.
31603b705cfSriastradh    */
31703b705cfSriastradh
31803b705cfSriastradh   I810SelectBuffer(pScrn, I810_SELECT_FRONT);
31903b705cfSriastradh
32003b705cfSriastradh   return XAAInit(pScreen, infoPtr);
32103b705cfSriastradh}
322