1f7018c21STomi Valkeinen /*-*- linux-c -*-
2f7018c21STomi Valkeinen  *  linux/drivers/video/savage/savage_accel.c -- Hardware Acceleration
3f7018c21STomi Valkeinen  *
4f7018c21STomi Valkeinen  *      Copyright (C) 2004 Antonino Daplas<adaplas@pol.net>
5f7018c21STomi Valkeinen  *      All Rights Reserved
6f7018c21STomi Valkeinen  *
7f7018c21STomi Valkeinen  *  This file is subject to the terms and conditions of the GNU General Public
8f7018c21STomi Valkeinen  *  License. See the file COPYING in the main directory of this archive for
9f7018c21STomi Valkeinen  *  more details.
10f7018c21STomi Valkeinen  */
11f7018c21STomi Valkeinen #include <linux/kernel.h>
12f7018c21STomi Valkeinen #include <linux/string.h>
13f7018c21STomi Valkeinen #include <linux/fb.h>
14f7018c21STomi Valkeinen #include <linux/module.h>
15f7018c21STomi Valkeinen 
16f7018c21STomi Valkeinen #include "savagefb.h"
17f7018c21STomi Valkeinen 
18f7018c21STomi Valkeinen static u32 savagefb_rop[] = {
19f7018c21STomi Valkeinen 	0xCC, /* ROP_COPY */
20f7018c21STomi Valkeinen 	0x5A  /* ROP_XOR  */
21f7018c21STomi Valkeinen };
22f7018c21STomi Valkeinen 
savagefb_sync(struct fb_info * info)23f7018c21STomi Valkeinen int savagefb_sync(struct fb_info *info)
24f7018c21STomi Valkeinen {
25f7018c21STomi Valkeinen 	struct savagefb_par *par = info->par;
26f7018c21STomi Valkeinen 
27f7018c21STomi Valkeinen 	par->SavageWaitIdle(par);
28f7018c21STomi Valkeinen 	return 0;
29f7018c21STomi Valkeinen }
30f7018c21STomi Valkeinen 
savagefb_copyarea(struct fb_info * info,const struct fb_copyarea * region)31f7018c21STomi Valkeinen void savagefb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
32f7018c21STomi Valkeinen {
33f7018c21STomi Valkeinen 	struct savagefb_par *par = info->par;
34f7018c21STomi Valkeinen 	int sx = region->sx, dx = region->dx;
35f7018c21STomi Valkeinen 	int sy = region->sy, dy = region->dy;
36f7018c21STomi Valkeinen 	int cmd;
37f7018c21STomi Valkeinen 
38f7018c21STomi Valkeinen 	if (!region->width || !region->height)
39f7018c21STomi Valkeinen 		return;
40f7018c21STomi Valkeinen 	par->bci_ptr = 0;
41f7018c21STomi Valkeinen 	cmd = BCI_CMD_RECT | BCI_CMD_DEST_GBD | BCI_CMD_SRC_GBD;
42f7018c21STomi Valkeinen 	BCI_CMD_SET_ROP(cmd, savagefb_rop[0]);
43f7018c21STomi Valkeinen 
44f7018c21STomi Valkeinen 	if (dx <= sx) {
45f7018c21STomi Valkeinen 		cmd |= BCI_CMD_RECT_XP;
46f7018c21STomi Valkeinen 	} else {
47f7018c21STomi Valkeinen 		sx += region->width - 1;
48f7018c21STomi Valkeinen 		dx += region->width - 1;
49f7018c21STomi Valkeinen 	}
50f7018c21STomi Valkeinen 
51f7018c21STomi Valkeinen 	if (dy <= sy) {
52f7018c21STomi Valkeinen 		cmd |= BCI_CMD_RECT_YP;
53f7018c21STomi Valkeinen 	} else {
54f7018c21STomi Valkeinen 		sy += region->height - 1;
55f7018c21STomi Valkeinen 		dy += region->height - 1;
56f7018c21STomi Valkeinen 	}
57f7018c21STomi Valkeinen 
58f7018c21STomi Valkeinen 	par->SavageWaitFifo(par,4);
59f7018c21STomi Valkeinen 	BCI_SEND(cmd);
60f7018c21STomi Valkeinen 	BCI_SEND(BCI_X_Y(sx, sy));
61f7018c21STomi Valkeinen 	BCI_SEND(BCI_X_Y(dx, dy));
62f7018c21STomi Valkeinen 	BCI_SEND(BCI_W_H(region->width, region->height));
63f7018c21STomi Valkeinen }
64f7018c21STomi Valkeinen 
savagefb_fillrect(struct fb_info * info,const struct fb_fillrect * rect)65f7018c21STomi Valkeinen void savagefb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
66f7018c21STomi Valkeinen {
67f7018c21STomi Valkeinen 	struct savagefb_par *par = info->par;
68f7018c21STomi Valkeinen 	int cmd, color;
69f7018c21STomi Valkeinen 
70f7018c21STomi Valkeinen 	if (!rect->width || !rect->height)
71f7018c21STomi Valkeinen 		return;
72f7018c21STomi Valkeinen 
73f7018c21STomi Valkeinen 	if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
74f7018c21STomi Valkeinen 		color = rect->color;
75f7018c21STomi Valkeinen 	else
76f7018c21STomi Valkeinen 		color = ((u32 *)info->pseudo_palette)[rect->color];
77f7018c21STomi Valkeinen 
78f7018c21STomi Valkeinen 	cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |
79f7018c21STomi Valkeinen 	      BCI_CMD_DEST_GBD | BCI_CMD_SRC_SOLID |
80f7018c21STomi Valkeinen 	      BCI_CMD_SEND_COLOR;
81f7018c21STomi Valkeinen 
82f7018c21STomi Valkeinen 	par->bci_ptr = 0;
83f7018c21STomi Valkeinen 	BCI_CMD_SET_ROP(cmd, savagefb_rop[rect->rop]);
84f7018c21STomi Valkeinen 
85f7018c21STomi Valkeinen 	par->SavageWaitFifo(par,4);
86f7018c21STomi Valkeinen 	BCI_SEND(cmd);
87f7018c21STomi Valkeinen 	BCI_SEND(color);
88f7018c21STomi Valkeinen 	BCI_SEND( BCI_X_Y(rect->dx, rect->dy) );
89f7018c21STomi Valkeinen 	BCI_SEND( BCI_W_H(rect->width, rect->height) );
90f7018c21STomi Valkeinen }
91f7018c21STomi Valkeinen 
savagefb_imageblit(struct fb_info * info,const struct fb_image * image)92f7018c21STomi Valkeinen void savagefb_imageblit(struct fb_info *info, const struct fb_image *image)
93f7018c21STomi Valkeinen {
94f7018c21STomi Valkeinen 	struct savagefb_par *par = info->par;
95f7018c21STomi Valkeinen 	int fg, bg, size, i, width;
96f7018c21STomi Valkeinen 	int cmd;
97f7018c21STomi Valkeinen 	u32 *src = (u32 *) image->data;
98f7018c21STomi Valkeinen 
99f7018c21STomi Valkeinen 	if (!image->width || !image->height)
100f7018c21STomi Valkeinen 		return;
101f7018c21STomi Valkeinen 
102f7018c21STomi Valkeinen 	if (image->depth != 1) {
103f7018c21STomi Valkeinen 		cfb_imageblit(info, image);
104f7018c21STomi Valkeinen 		return;
105f7018c21STomi Valkeinen 	}
106f7018c21STomi Valkeinen 
107f7018c21STomi Valkeinen 	if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) {
108f7018c21STomi Valkeinen 		fg = image->fg_color;
109f7018c21STomi Valkeinen 		bg = image->bg_color;
110f7018c21STomi Valkeinen 	} else {
111f7018c21STomi Valkeinen 		fg = ((u32 *)info->pseudo_palette)[image->fg_color];
112f7018c21STomi Valkeinen 		bg = ((u32 *)info->pseudo_palette)[image->bg_color];
113f7018c21STomi Valkeinen 	}
114f7018c21STomi Valkeinen 
115f7018c21STomi Valkeinen 	cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |
116f7018c21STomi Valkeinen 	      BCI_CMD_CLIP_LR | BCI_CMD_DEST_GBD | BCI_CMD_SRC_MONO |
117f7018c21STomi Valkeinen 	      BCI_CMD_SEND_COLOR;
118f7018c21STomi Valkeinen 
119f7018c21STomi Valkeinen 	par->bci_ptr = 0;
120f7018c21STomi Valkeinen 	BCI_CMD_SET_ROP(cmd, savagefb_rop[0]);
121f7018c21STomi Valkeinen 
122f7018c21STomi Valkeinen 	width = (image->width + 31) & ~31;
123f7018c21STomi Valkeinen 	size = (width * image->height)/8;
124f7018c21STomi Valkeinen 	size >>= 2;
125f7018c21STomi Valkeinen 
126f7018c21STomi Valkeinen 	par->SavageWaitFifo(par, size + 5);
127f7018c21STomi Valkeinen 	BCI_SEND(cmd);
128f7018c21STomi Valkeinen 	BCI_SEND(BCI_CLIP_LR(image->dx, image->dx + image->width - 1));
129f7018c21STomi Valkeinen 	BCI_SEND(fg);
130f7018c21STomi Valkeinen 	BCI_SEND(bg);
131f7018c21STomi Valkeinen 	BCI_SEND(BCI_X_Y(image->dx, image->dy));
132f7018c21STomi Valkeinen 	BCI_SEND(BCI_W_H(width, image->height));
133f7018c21STomi Valkeinen 	for (i = 0; i < size; i++)
134f7018c21STomi Valkeinen 		BCI_SEND(src[i]);
135f7018c21STomi Valkeinen }
136f7018c21STomi Valkeinen 
137f7018c21STomi Valkeinen MODULE_LICENSE("GPL");
138