

#ifndef _PXA3XX_GFX_H_
#define _PXA3XX_GFX_H_


#define	GC_CDEV_PATH	"/dev/pxa3xx-gc"
#define GC_MAJOR 241	/* local/experimental */
#define GCIO_ADD_COMMAND 	_IOWR(GC_MAJOR, 2, unsigned long *)	/* adds a command to the ring buffer */
#define GCIO_WAIT_ALL_COMPLETE	_IOR(GC_MAJOR, 3, int)			/* Wait for the GC to execute all the commands in the ring buffer */
#define GCIO_GET_RINGBUFF_FREE	_IOR(GC_MAJOR, 4, int)			/* Get how many free bytes there is in the ring buffer */
#define GCIO_RESET		_IOR(GC_MAJOR, 5, int)



/* Pixel formats */
#define PF_8B_LOOKUP		0x00
#define PF_15B_RGB555		0x01
#define	PF_16B_RGBT5551		0x02
#define	PF_16B_RGB565		0x03
#define	PF_18B_RGB666		0x04
#define	PF_19B_RGBT6661		0x05
#define	PF_24B_RGB888		0x06
#define	PF_24B_RGBA6666		0x07
#define	PF_24B_RGBT8881		0x08
#define	PF_32B_RGBA8888		0x09
#define	PF_48B_RGB161616	0x0A
#define	PF_64B_RGBA16161616	0x0B
#define	PF_INVALID		0xFF

/** Instruction Opcodes */
#define	GCI_BIT		29
#define	GCI_MASK	0x7
#define	GCI_MEMORY	(0x0 << GCI_BIT)
#define	GCI_2DGFX	(0x2 << GCI_BIT)

#define OPCODE_BIT	24
#define OPCODE_MASK	0x1F
#define	GC_BBST		(GCI_MEMORY | (0x00 << OPCODE_BIT))	/* Batch Buffer Start */
#define	GC_BBEND	(GCI_MEMORY | (0x01 << OPCODE_BIT))	/* Batch Buffer End */	
#define	GC_BUFFI	(GCI_MEMORY | (0x02 << OPCODE_BIT))	/* Buffer Info */	
#define	GC_LREG		(GCI_MEMORY | (0x04 << OPCODE_BIT))	/* Load Register */	
#define	GC_NOP		(GCI_MEMORY | (0x05 << OPCODE_BIT))	/* NOP */	
#define	GC_DBFLIP	(GCI_MEMORY | (0x06 << OPCODE_BIT))	/* Destination Buffer Flip */	
#define	GC_STREG	(GCI_MEMORY | (0x07 << OPCODE_BIT))	/* Store Register */	
#define	GC_INT		(GCI_MEMORY | (0x08 << OPCODE_BIT))	/* Interrupt CPU */	
#define	GC_WAIT		(GCI_MEMORY | (0x09 << OPCODE_BIT))	/* Wait For Event */	

#define GC_CFILL	(GCI_2DGFX | (0x00 << OPCODE_BIT))	/* Colour Fill */
#define GC_CKBLT	(GCI_2DGFX | (0x01 << OPCODE_BIT))	/* Chroma Key BLT */
#define GC_LINE		(GCI_2DGFX | (0x02 << OPCODE_BIT))	/* Line Draw */
#define GC_AALINE	(GCI_2DGFX | (0x03 << OPCODE_BIT))	/* Antialiased Line Draw */
#define GC_STRBLT	(GCI_2DGFX | (0x05 << OPCODE_BIT))	/* Strech BLT */
#define GC_ABLND	(GCI_2DGFX | (0x07 << OPCODE_BIT))	/* Alpha Blend BLT */
#define GC_SCALE	(GCI_2DGFX | (0x08 << OPCODE_BIT))	/* Scale BLT */
#define GC_BIAS		(GCI_2DGFX | (0x09 << OPCODE_BIT))	/* Bias BLT */
#define GC_RAST		(GCI_2DGFX | (0x0B << OPCODE_BIT))	/* Raster OP BLT */
#define GC_PATT		(GCI_2DGFX | (0x0C << OPCODE_BIT))	/* Pattern Copy BLT */
#define GC_DECBLT	(GCI_2DGFX | (0x0D << OPCODE_BIT))	/* Deceminate BLT */

/** Buffer identifies for GC_BUFFI */
#define GC_BUFFI_ADDR_BIT	4
#define GC_BUFFI_SOURCE0	0x00
#define GC_BUFFI_SOURCE1	0x01
#define GC_BUFFI_DEST0		0x08
#define GC_BUFFI_DEST1		0x09
#define GC_BUFFI_DEST2		0x0A

#define GC_CFILL_IMM		(1 << 4)	/* Immeadiate color value rather than register */


struct pxa3xxAccelSolidInfo {
	Pixel fg;
	unsigned char pixelFormat;
	int width;
	int height;
};

struct pxa3xxAccelCompositeInfo {


};

struct pxa3xxAccelCopyInfo {	
	int srcIsDest;

	int srcWidth;
	int srcHeight;
	int dstWidth;
	int dstHeight;
	int maskWidth;
	int maskHeight;

	int maskValid;
	unsigned char op;

	/* We might need a temp area for doing up-memory copies */
	KdOffscreenArea *temp_off_screen;
	unsigned long temp_phys;
	ScreenPtr pScreen;	/* Need this for handling temp area */

	/* Buffer info for src==dst copies */
	unsigned long srcDstPhys;
	unsigned char srcDstStep;
	unsigned short srcDstStride;
	unsigned char srcDstPixelFormat;


};

struct pxa3xxAccelVidMemInfo {
	unsigned long phys;
	unsigned char *virt;
	unsigned long size;		/* real amount of memory the kernel reserved for video */
	unsigned long vidSize;		/* size of width*height*bpp */
	int width;
	int height;
	int stride;
	int bpp;
	int step;

	unsigned long kdrive_off_screen_base;
	unsigned long scrapAreaRel;
	unsigned long scrapAreaPhys;

};

struct pxa3xxAccelPriv {
	int cdev_fd;	/* character device for pxa3xx-gc driver */
	FbdevPriv *fbPriv; /* The framebuffer devices's private area */
	KaaScreenInfoRec kaa;

	int opPrepared;
	int haveSetBuffers;

	int enabled;

	struct pxa3xxAccelVidMemInfo vidMem;

	struct pxa3xxAccelSolidInfo thisSolid;
	struct pxa3xxAccelCopyInfo thisCopy;

	/* for restriction checks */
	unsigned char src0Step;
	unsigned short src0Stride;
	unsigned char src0PixelFormat;
 
};

Bool pxa3xxGFXInit(ScreenPtr pScreen);
void pxa3xxGFXEnable(ScreenPtr pScreen);
void pxa3xxGFXDisable(ScreenPtr pScreen);
void pxa3xxGFXFini(ScreenPtr pScreen);

int pxa3xxGFX_Wait_Complete(void);

//Command prototypes
int pxa3xxGFXCmd_Ringbuff_Add(unsigned long *data, int len); /** Executes a nop command */
int pxa3xxGFXCmd_nop(unsigned long nop_id);
int pxa3xxGFXCmd_set_buff(unsigned int buff, 
				unsigned long base, unsigned char step,
				unsigned int stride, unsigned char pixelFormat);
int pxa3xxGFXCmd_color_fill(int x0, int y0, int w, int h, unsigned char pixelFormat, unsigned long color);
int pxa3xxGFXCmd_stretch_blt(int sx0, int sy0, int sw, int sh, int dx0, int dy0, int dw, int dh);
int pxa3xxGFXCmd_deceminate_blt(int sx0, int sy0, int sw, int sh, int dx0, int dy0, int dw, int dh );

inline int pxa3xxGFXCmd_copy_blt(int s0x, int s0y, int dx, int dy, int w, int h);
int pxa3xxGFXCmd_raster_blt(int s0x, int s0y, int s1x, int s1y, int dx, int dy, int w, int h, unsigned char op);
	


int markSync(ScreenPtr pScreen);
void waitMarker(ScreenPtr pScreen, int marker);
inline int isPixmapInVidmem(struct pxa3xxAccelPriv *gfxPriv, PixmapPtr pPixmap);
unsigned char getPixelFormat(PixmapPtr pPixmap);
inline unsigned char getStep(PixmapPtr pPixmap);
inline unsigned short getStride(PixmapPtr pPixmap);
inline unsigned long getPhysAddr(PixmapPtr pPixmap);
inline unsigned long getPhysAddrFromOffset(unsigned long relative);
inline Bool isGFXEnabled(void);

void scrapSave(ScreenPtr pScreen, KdOffscreenArea *area);

Bool PrepareSolid(PixmapPtr pPixmap, int alu, Pixel planemask, Pixel fg);
void Solid(int x1, int y1, int x2, int y2);
void DoneSolid(void);
Bool PrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, Bool upsidedown,
			Bool reverse, int alu, Pixel planemask);
void Copy(int srcX, int	srcY, int dstX, int dstY,int width, int height);
void DoneCopy(void);
Bool PrepareBlend(int op, PicturePtr pSrcPicture, PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pDst);
void Blend(int srcX, int srcY, int dstX, int dstY, int width, int height);
void DoneBlend(void);
Bool CheckComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture, PicturePtr pDstPicture);
Bool PrepareComposite(int op, PicturePtr pSrcPicture, PicturePtr pMaskPicture,
		PicturePtr pDstPicture, PixmapPtr pSrc, PixmapPtr pMask, PixmapPtr pDst);
void  Composite(int srcX, int srcY, int maskX, int maskY,
			int dstX, int dstY, int width, int height);
void DoneComposite(void);
Bool PrepareTrapezoids(PicturePtr pDstPicture, PixmapPtr pDst);
void Trapezoids(KaaTrapezoid *traps, int ntraps);
void DoneTrapezoids(void);
Bool UploadToScreen(PixmapPtr pDst, char *src, int src_pitch);
Bool UploadToScratch(PixmapPtr pSrc, PixmapPtr pDst);


inline void startOp(int op);
inline void checkOp(int op);
inline void endOp(int op);

#endif /* _PXA3XX_GFX_H_ */
