162306a36Sopenharmony_ci/*-*- linux-c -*-
262306a36Sopenharmony_ci *  linux/drivers/video/savage/savage_accel.c -- Hardware Acceleration
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci *      Copyright (C) 2004 Antonino Daplas<adaplas@pol.net>
562306a36Sopenharmony_ci *      All Rights Reserved
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci *  This file is subject to the terms and conditions of the GNU General Public
862306a36Sopenharmony_ci *  License. See the file COPYING in the main directory of this archive for
962306a36Sopenharmony_ci *  more details.
1062306a36Sopenharmony_ci */
1162306a36Sopenharmony_ci#include <linux/kernel.h>
1262306a36Sopenharmony_ci#include <linux/string.h>
1362306a36Sopenharmony_ci#include <linux/fb.h>
1462306a36Sopenharmony_ci#include <linux/module.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#include "savagefb.h"
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_cistatic u32 savagefb_rop[] = {
1962306a36Sopenharmony_ci	0xCC, /* ROP_COPY */
2062306a36Sopenharmony_ci	0x5A  /* ROP_XOR  */
2162306a36Sopenharmony_ci};
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_ciint savagefb_sync(struct fb_info *info)
2462306a36Sopenharmony_ci{
2562306a36Sopenharmony_ci	struct savagefb_par *par = info->par;
2662306a36Sopenharmony_ci
2762306a36Sopenharmony_ci	par->SavageWaitIdle(par);
2862306a36Sopenharmony_ci	return 0;
2962306a36Sopenharmony_ci}
3062306a36Sopenharmony_ci
3162306a36Sopenharmony_civoid savagefb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
3262306a36Sopenharmony_ci{
3362306a36Sopenharmony_ci	struct savagefb_par *par = info->par;
3462306a36Sopenharmony_ci	int sx = region->sx, dx = region->dx;
3562306a36Sopenharmony_ci	int sy = region->sy, dy = region->dy;
3662306a36Sopenharmony_ci	int cmd;
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci	if (!region->width || !region->height)
3962306a36Sopenharmony_ci		return;
4062306a36Sopenharmony_ci	par->bci_ptr = 0;
4162306a36Sopenharmony_ci	cmd = BCI_CMD_RECT | BCI_CMD_DEST_GBD | BCI_CMD_SRC_GBD;
4262306a36Sopenharmony_ci	BCI_CMD_SET_ROP(cmd, savagefb_rop[0]);
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	if (dx <= sx) {
4562306a36Sopenharmony_ci		cmd |= BCI_CMD_RECT_XP;
4662306a36Sopenharmony_ci	} else {
4762306a36Sopenharmony_ci		sx += region->width - 1;
4862306a36Sopenharmony_ci		dx += region->width - 1;
4962306a36Sopenharmony_ci	}
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	if (dy <= sy) {
5262306a36Sopenharmony_ci		cmd |= BCI_CMD_RECT_YP;
5362306a36Sopenharmony_ci	} else {
5462306a36Sopenharmony_ci		sy += region->height - 1;
5562306a36Sopenharmony_ci		dy += region->height - 1;
5662306a36Sopenharmony_ci	}
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci	par->SavageWaitFifo(par,4);
5962306a36Sopenharmony_ci	BCI_SEND(cmd);
6062306a36Sopenharmony_ci	BCI_SEND(BCI_X_Y(sx, sy));
6162306a36Sopenharmony_ci	BCI_SEND(BCI_X_Y(dx, dy));
6262306a36Sopenharmony_ci	BCI_SEND(BCI_W_H(region->width, region->height));
6362306a36Sopenharmony_ci}
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_civoid savagefb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
6662306a36Sopenharmony_ci{
6762306a36Sopenharmony_ci	struct savagefb_par *par = info->par;
6862306a36Sopenharmony_ci	int cmd, color;
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	if (!rect->width || !rect->height)
7162306a36Sopenharmony_ci		return;
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci	if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
7462306a36Sopenharmony_ci		color = rect->color;
7562306a36Sopenharmony_ci	else
7662306a36Sopenharmony_ci		color = ((u32 *)info->pseudo_palette)[rect->color];
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |
7962306a36Sopenharmony_ci	      BCI_CMD_DEST_GBD | BCI_CMD_SRC_SOLID |
8062306a36Sopenharmony_ci	      BCI_CMD_SEND_COLOR;
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci	par->bci_ptr = 0;
8362306a36Sopenharmony_ci	BCI_CMD_SET_ROP(cmd, savagefb_rop[rect->rop]);
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	par->SavageWaitFifo(par,4);
8662306a36Sopenharmony_ci	BCI_SEND(cmd);
8762306a36Sopenharmony_ci	BCI_SEND(color);
8862306a36Sopenharmony_ci	BCI_SEND( BCI_X_Y(rect->dx, rect->dy) );
8962306a36Sopenharmony_ci	BCI_SEND( BCI_W_H(rect->width, rect->height) );
9062306a36Sopenharmony_ci}
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_civoid savagefb_imageblit(struct fb_info *info, const struct fb_image *image)
9362306a36Sopenharmony_ci{
9462306a36Sopenharmony_ci	struct savagefb_par *par = info->par;
9562306a36Sopenharmony_ci	int fg, bg, size, i, width;
9662306a36Sopenharmony_ci	int cmd;
9762306a36Sopenharmony_ci	u32 *src = (u32 *) image->data;
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	if (!image->width || !image->height)
10062306a36Sopenharmony_ci		return;
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci	if (image->depth != 1) {
10362306a36Sopenharmony_ci		cfb_imageblit(info, image);
10462306a36Sopenharmony_ci		return;
10562306a36Sopenharmony_ci	}
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) {
10862306a36Sopenharmony_ci		fg = image->fg_color;
10962306a36Sopenharmony_ci		bg = image->bg_color;
11062306a36Sopenharmony_ci	} else {
11162306a36Sopenharmony_ci		fg = ((u32 *)info->pseudo_palette)[image->fg_color];
11262306a36Sopenharmony_ci		bg = ((u32 *)info->pseudo_palette)[image->bg_color];
11362306a36Sopenharmony_ci	}
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |
11662306a36Sopenharmony_ci	      BCI_CMD_CLIP_LR | BCI_CMD_DEST_GBD | BCI_CMD_SRC_MONO |
11762306a36Sopenharmony_ci	      BCI_CMD_SEND_COLOR;
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci	par->bci_ptr = 0;
12062306a36Sopenharmony_ci	BCI_CMD_SET_ROP(cmd, savagefb_rop[0]);
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci	width = (image->width + 31) & ~31;
12362306a36Sopenharmony_ci	size = (width * image->height)/8;
12462306a36Sopenharmony_ci	size >>= 2;
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci	par->SavageWaitFifo(par, size + 5);
12762306a36Sopenharmony_ci	BCI_SEND(cmd);
12862306a36Sopenharmony_ci	BCI_SEND(BCI_CLIP_LR(image->dx, image->dx + image->width - 1));
12962306a36Sopenharmony_ci	BCI_SEND(fg);
13062306a36Sopenharmony_ci	BCI_SEND(bg);
13162306a36Sopenharmony_ci	BCI_SEND(BCI_X_Y(image->dx, image->dy));
13262306a36Sopenharmony_ci	BCI_SEND(BCI_W_H(width, image->height));
13362306a36Sopenharmony_ci	for (i = 0; i < size; i++)
13462306a36Sopenharmony_ci		BCI_SEND(src[i]);
13562306a36Sopenharmony_ci}
13662306a36Sopenharmony_ci
13762306a36Sopenharmony_ciMODULE_LICENSE("GPL");
138