300 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			300 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * $Id$
 | 
						|
 *
 | 
						|
 * Copyright © 2003 Anders Carlsson
 | 
						|
 *
 | 
						|
 * Permission to use, copy, modify, distribute, and sell this software and its
 | 
						|
 * documentation for any purpose is hereby granted without fee, provided that
 | 
						|
 * the above copyright notice appear in all copies and that both that
 | 
						|
 * copyright notice and this permission notice appear in supporting
 | 
						|
 * documentation, and that the name of Anders Carlsson not be used in
 | 
						|
 * advertising or publicity pertaining to distribution of the software without
 | 
						|
 * specific, written prior permission.  Anders Carlsson makes no
 | 
						|
 * representations about the suitability of this software for any purpose.  It
 | 
						|
 * is provided "as is" without express or implied warranty.
 | 
						|
 *
 | 
						|
 * ANDERS CARLSSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
						|
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
						|
 * EVENT SHALL ANDERS CARLSSON BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
						|
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 | 
						|
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 | 
						|
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
						|
 * PERFORMANCE OF THIS SOFTWARE.
 | 
						|
 */
 | 
						|
/* $Header$ */
 | 
						|
#ifdef HAVE_CONFIG_H
 | 
						|
#include <config.h>
 | 
						|
#endif
 | 
						|
#include "r128.h"
 | 
						|
#include "kaa.h"
 | 
						|
 | 
						|
CARD8 r128SolidRop[16] = {
 | 
						|
    /* GXclear      */      0x00,         /* 0 */
 | 
						|
    /* GXand        */      0xa0,         /* src AND dst */
 | 
						|
    /* GXandReverse */      0x50,         /* src AND NOT dst */
 | 
						|
    /* GXcopy       */      0xf0,         /* src */
 | 
						|
    /* GXandInverted*/      0x0a,         /* NOT src AND dst */
 | 
						|
    /* GXnoop       */      0xaa,         /* dst */
 | 
						|
    /* GXxor        */      0x5a,         /* src XOR dst */
 | 
						|
    /* GXor         */      0xfa,         /* src OR dst */
 | 
						|
    /* GXnor        */      0x05,         /* NOT src AND NOT dst */
 | 
						|
    /* GXequiv      */      0xa5,         /* NOT src XOR dst */
 | 
						|
    /* GXinvert     */      0x55,         /* NOT dst */
 | 
						|
    /* GXorReverse  */      0xf5,         /* src OR NOT dst */
 | 
						|
    /* GXcopyInverted*/     0x0f,         /* NOT src */
 | 
						|
    /* GXorInverted */      0xaf,         /* NOT src OR dst */
 | 
						|
    /* GXnand       */      0x5f,         /* NOT src OR NOT dst */
 | 
						|
    /* GXset        */      0xff,         /* 1 */
 | 
						|
};
 | 
						|
 | 
						|
CARD8 r128BltRop[16] = {
 | 
						|
    /* GXclear      */      0x00,         /* 0 */
 | 
						|
    /* GXand        */      0x88,         /* src AND dst */
 | 
						|
    /* GXandReverse */      0x44,         /* src AND NOT dst */
 | 
						|
    /* GXcopy       */      0xcc,         /* src */
 | 
						|
    /* GXandInverted*/      0x22,         /* NOT src AND dst */
 | 
						|
    /* GXnoop       */      0xaa,         /* dst */
 | 
						|
    /* GXxor        */      0x66,         /* src XOR dst */
 | 
						|
    /* GXor         */      0xee,         /* src OR dst */
 | 
						|
    /* GXnor        */      0x11,         /* NOT src AND NOT dst */
 | 
						|
    /* GXequiv      */      0x99,         /* NOT src XOR dst */
 | 
						|
    /* GXinvert     */      0x55,         /* NOT dst */
 | 
						|
    /* GXorReverse  */      0xdd,         /* src OR NOT dst */
 | 
						|
    /* GXcopyInverted*/     0x33,         /* NOT src */
 | 
						|
    /* GXorInverted */      0xbb,         /* NOT src OR dst */
 | 
						|
    /* GXnand       */      0x77,         /* NOT src OR NOT dst */
 | 
						|
    /* GXset        */      0xff,         /* 1 */
 | 
						|
};
 | 
						|
 | 
						|
int copydx, copydy;
 | 
						|
int fifo_size;
 | 
						|
char *mmio;
 | 
						|
 | 
						|
static void
 | 
						|
r128WaitAvail (int n)
 | 
						|
{
 | 
						|
    if (fifo_size < n)
 | 
						|
    {
 | 
						|
	while ((fifo_size = R128_IN32 (mmio, R128_REG_GUI_STAT) & 0xfff) < n)
 | 
						|
	    ;
 | 
						|
    }
 | 
						|
    
 | 
						|
    fifo_size -= n;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
r128WaitIdle (void)
 | 
						|
{
 | 
						|
    int tries;
 | 
						|
    
 | 
						|
    r128WaitAvail (64);
 | 
						|
 | 
						|
    tries = 1000000;
 | 
						|
    while (tries--)
 | 
						|
    {
 | 
						|
	if ((R128_IN32 (mmio, R128_REG_GUI_STAT) & R128_GUI_ACTIVE) == 0)
 | 
						|
	    break;
 | 
						|
    }
 | 
						|
 | 
						|
    R128_OUT32 (mmio, R128_REG_PC_NGUI_CTLSTAT,
 | 
						|
		R128_IN32 (mmio, R128_REG_PC_NGUI_CTLSTAT | 0xff));
 | 
						|
 | 
						|
    tries = 1000000;
 | 
						|
    while (tries--)
 | 
						|
    {
 | 
						|
	if ((R128_IN32 (mmio, R128_REG_PC_NGUI_CTLSTAT) & R128_PC_BUSY) != R128_PC_BUSY)
 | 
						|
	    break;
 | 
						|
    }
 | 
						|
    
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
r128WaitMarker (ScreenPtr pScreen, int marker)
 | 
						|
{
 | 
						|
    KdScreenPriv (pScreen);
 | 
						|
    r128CardInfo (pScreenPriv);
 | 
						|
 | 
						|
    mmio = r128c->reg_base;
 | 
						|
 | 
						|
    r128WaitIdle ();
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
r128Setup (ScreenPtr pScreen, int wait)
 | 
						|
{
 | 
						|
  KdScreenPriv (pScreen);
 | 
						|
  r128ScreenInfo (pScreenPriv);
 | 
						|
  r128CardInfo (pScreenPriv);
 | 
						|
 | 
						|
  fifo_size = 0;
 | 
						|
 | 
						|
  mmio = r128c->reg_base;
 | 
						|
    
 | 
						|
  if (!mmio)
 | 
						|
      return FALSE;
 | 
						|
 | 
						|
  r128WaitAvail (2);
 | 
						|
  R128_OUT32 (mmio, R128_REG_DEFAULT_OFFSET, 0);
 | 
						|
  R128_OUT32 (mmio, R128_REG_DEFAULT_PITCH, r128s->pitch);
 | 
						|
 | 
						|
  r128WaitAvail (4);
 | 
						|
  R128_OUT32 (mmio, R128_AUX_SC_CNTL, 0);
 | 
						|
  R128_OUT32 (mmio, R128_DEFAULT_SC_BOTTOM_RIGHT, (R128_DEFAULT_SC_RIGHT_MAX
 | 
						|
						| R128_DEFAULT_SC_BOTTOM_MAX));
 | 
						|
  R128_OUT32 (mmio, R128_SC_TOP_LEFT, 0);
 | 
						|
  R128_OUT32 (mmio, R128_SC_BOTTOM_RIGHT, (R128_DEFAULT_SC_RIGHT_MAX
 | 
						|
						| R128_DEFAULT_SC_BOTTOM_MAX));
 | 
						|
  r128WaitAvail (wait);
 | 
						|
  return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
r128PrepareSolid (PixmapPtr pPixmap, int alu, Pixel pm, Pixel fg)
 | 
						|
{
 | 
						|
    KdScreenPriv (pPixmap->drawable.pScreen);
 | 
						|
    r128ScreenInfo (pScreenPriv);
 | 
						|
 | 
						|
    r128Setup (pPixmap->drawable.pScreen, 4);
 | 
						|
    R128_OUT32 (mmio, R128_REG_DP_GUI_MASTER_CNTL, r128s->dp_gui_master_cntl
 | 
						|
		| R128_GMC_BRUSH_SOLID_COLOR
 | 
						|
		| R128_GMC_SRC_DATATYPE_COLOR
 | 
						|
		| (r128SolidRop[alu] << R128_GMC_ROP3_SHIFT));
 | 
						|
    R128_OUT32 (mmio, R128_REG_DP_BRUSH_FRGD_CLR, fg);
 | 
						|
    R128_OUT32 (mmio, R128_REG_DP_WRITE_MASK, pm);
 | 
						|
    R128_OUT32 (mmio, R128_REG_DP_CNTL,
 | 
						|
		(R128_DST_X_LEFT_TO_RIGHT | R128_DST_Y_TOP_TO_BOTTOM));
 | 
						|
    
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
r128Solid (int x1, int y1, int x2, int y2)
 | 
						|
{
 | 
						|
    r128WaitAvail (2);
 | 
						|
    R128_OUT32 (mmio, R128_REG_DST_Y_X, (y1 << 16) | x1);
 | 
						|
    R128_OUT32 (mmio, R128_REG_DST_WIDTH_HEIGHT, ((x2 - x1) << 16) | (y2 - y1));
 | 
						|
    
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
r128DoneSolid (void)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
r128PrepareCopy (PixmapPtr pSrc, PixmapPtr pDst, int dx, int dy, int alu, Pixel pm)
 | 
						|
{
 | 
						|
    KdScreenPriv (pSrc->drawable.pScreen);
 | 
						|
    r128ScreenInfo (pScreenPriv);
 | 
						|
    
 | 
						|
    copydx = dx;
 | 
						|
    copydy = dy;
 | 
						|
 | 
						|
    r128Setup (pSrc->drawable.pScreen, 3);
 | 
						|
    R128_OUT32 (mmio, R128_REG_DP_GUI_MASTER_CNTL, r128s->dp_gui_master_cntl
 | 
						|
		| R128_GMC_BRUSH_SOLID_COLOR
 | 
						|
		| R128_GMC_SRC_DATATYPE_COLOR
 | 
						|
		| (r128BltRop[alu] << R128_GMC_ROP3_SHIFT)
 | 
						|
		| R128_DP_SRC_SOURCE_MEMORY);
 | 
						|
    R128_OUT32 (mmio, R128_REG_DP_WRITE_MASK, pm);
 | 
						|
    R128_OUT32 (mmio, R128_REG_DP_CNTL,
 | 
						|
		((dx >= 0 ? R128_DST_X_LEFT_TO_RIGHT : 0)
 | 
						|
		 | (dy >= 0 ? R128_DST_Y_TOP_TO_BOTTOM : 0)));
 | 
						|
		   
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
r128Copy (int srcX, int srcY, int dstX, int dstY, int w, int h)
 | 
						|
{
 | 
						|
    if (copydx < 0)
 | 
						|
    {
 | 
						|
	srcX += w - 1;
 | 
						|
	dstX += w - 1;
 | 
						|
    }
 | 
						|
 | 
						|
    if (copydy < 0)
 | 
						|
    {
 | 
						|
	srcY += h - 1;
 | 
						|
	dstY += h - 1;
 | 
						|
    }
 | 
						|
 | 
						|
    r128WaitAvail (3);
 | 
						|
    R128_OUT32 (mmio, R128_REG_SRC_Y_X, (srcY << 16) | srcX);
 | 
						|
    R128_OUT32 (mmio, R128_REG_DST_Y_X, (dstY << 16) | dstX);
 | 
						|
    R128_OUT32 (mmio, R128_REG_DST_HEIGHT_WIDTH, (h << 16) | w);
 | 
						|
}
 | 
						|
 | 
						|
static void
 | 
						|
r128DoneCopy (void)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
Bool
 | 
						|
r128DrawInit (ScreenPtr pScreen)
 | 
						|
{
 | 
						|
    KdScreenPriv (pScreen);
 | 
						|
    r128ScreenInfo (pScreenPriv);
 | 
						|
 | 
						|
    memset(&r128s->kaa, 0, sizeof(KaaScreenInfoRec));
 | 
						|
    r128s->kaa.waitMarker	= r128WaitMarker;
 | 
						|
    r128s->kaa.PrepareSolid	= r128PrepareSolid;
 | 
						|
    r128s->kaa.Solid		= r128Solid;
 | 
						|
    r128s->kaa.DoneSolid	= r128DoneSolid;
 | 
						|
    r128s->kaa.PrepareCopy	= r128PrepareCopy;
 | 
						|
    r128s->kaa.Copy		= r128Copy;
 | 
						|
    r128s->kaa.DoneCopy		= r128DoneCopy;
 | 
						|
 | 
						|
    if (!kaaDrawInit (pScreen, &r128s->kaa))
 | 
						|
	return FALSE;
 | 
						|
 | 
						|
    return TRUE;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
r128DrawEnable (ScreenPtr pScreen)
 | 
						|
{
 | 
						|
    KdScreenPriv (pScreen);
 | 
						|
    r128ScreenInfo (pScreenPriv);
 | 
						|
 | 
						|
    r128s->pitch = pScreenPriv->screen->width >> 3;
 | 
						|
 | 
						|
    switch (pScreenPriv->screen->fb[0].depth) {
 | 
						|
    case 8:
 | 
						|
	r128s->datatype = 2;
 | 
						|
	break;
 | 
						|
    case 15:
 | 
						|
	r128s->datatype = 3;
 | 
						|
	break;	
 | 
						|
    case 16:
 | 
						|
	r128s->datatype = 4;
 | 
						|
	break;
 | 
						|
    case 24:
 | 
						|
	r128s->datatype = 5;
 | 
						|
	break;
 | 
						|
    case 32:
 | 
						|
	r128s->datatype = 6;
 | 
						|
	break;
 | 
						|
    default:
 | 
						|
	FatalError ("unsupported pixel format");
 | 
						|
    }
 | 
						|
 | 
						|
    r128s->dp_gui_master_cntl = ((r128s->datatype << R128_GMC_DST_DATATYPE_SHIFT)
 | 
						|
				 | R128_GMC_CLR_CMP_CNTL_DIS
 | 
						|
				 | R128_GMC_AUX_CLIP_DIS);
 | 
						|
    
 | 
						|
    kaaMarkSync (pScreen);
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
r128DrawDisable (ScreenPtr pScreen)
 | 
						|
{
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
r128DrawFini (ScreenPtr pScreen)
 | 
						|
{
 | 
						|
}
 |