18c2ecf20Sopenharmony_ci/*-*- linux-c -*-
28c2ecf20Sopenharmony_ci *  linux/drivers/video/savage/savage_accel.c -- Hardware Acceleration
38c2ecf20Sopenharmony_ci *
48c2ecf20Sopenharmony_ci *      Copyright (C) 2004 Antonino Daplas<adaplas@pol.net>
58c2ecf20Sopenharmony_ci *      All Rights Reserved
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci *  This file is subject to the terms and conditions of the GNU General Public
88c2ecf20Sopenharmony_ci *  License. See the file COPYING in the main directory of this archive for
98c2ecf20Sopenharmony_ci *  more details.
108c2ecf20Sopenharmony_ci */
118c2ecf20Sopenharmony_ci#include <linux/kernel.h>
128c2ecf20Sopenharmony_ci#include <linux/string.h>
138c2ecf20Sopenharmony_ci#include <linux/fb.h>
148c2ecf20Sopenharmony_ci#include <linux/module.h>
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#include "savagefb.h"
178c2ecf20Sopenharmony_ci
188c2ecf20Sopenharmony_cistatic u32 savagefb_rop[] = {
198c2ecf20Sopenharmony_ci	0xCC, /* ROP_COPY */
208c2ecf20Sopenharmony_ci	0x5A  /* ROP_XOR  */
218c2ecf20Sopenharmony_ci};
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ciint savagefb_sync(struct fb_info *info)
248c2ecf20Sopenharmony_ci{
258c2ecf20Sopenharmony_ci	struct savagefb_par *par = info->par;
268c2ecf20Sopenharmony_ci
278c2ecf20Sopenharmony_ci	par->SavageWaitIdle(par);
288c2ecf20Sopenharmony_ci	return 0;
298c2ecf20Sopenharmony_ci}
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_civoid savagefb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
328c2ecf20Sopenharmony_ci{
338c2ecf20Sopenharmony_ci	struct savagefb_par *par = info->par;
348c2ecf20Sopenharmony_ci	int sx = region->sx, dx = region->dx;
358c2ecf20Sopenharmony_ci	int sy = region->sy, dy = region->dy;
368c2ecf20Sopenharmony_ci	int cmd;
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci	if (!region->width || !region->height)
398c2ecf20Sopenharmony_ci		return;
408c2ecf20Sopenharmony_ci	par->bci_ptr = 0;
418c2ecf20Sopenharmony_ci	cmd = BCI_CMD_RECT | BCI_CMD_DEST_GBD | BCI_CMD_SRC_GBD;
428c2ecf20Sopenharmony_ci	BCI_CMD_SET_ROP(cmd, savagefb_rop[0]);
438c2ecf20Sopenharmony_ci
448c2ecf20Sopenharmony_ci	if (dx <= sx) {
458c2ecf20Sopenharmony_ci		cmd |= BCI_CMD_RECT_XP;
468c2ecf20Sopenharmony_ci	} else {
478c2ecf20Sopenharmony_ci		sx += region->width - 1;
488c2ecf20Sopenharmony_ci		dx += region->width - 1;
498c2ecf20Sopenharmony_ci	}
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	if (dy <= sy) {
528c2ecf20Sopenharmony_ci		cmd |= BCI_CMD_RECT_YP;
538c2ecf20Sopenharmony_ci	} else {
548c2ecf20Sopenharmony_ci		sy += region->height - 1;
558c2ecf20Sopenharmony_ci		dy += region->height - 1;
568c2ecf20Sopenharmony_ci	}
578c2ecf20Sopenharmony_ci
588c2ecf20Sopenharmony_ci	par->SavageWaitFifo(par,4);
598c2ecf20Sopenharmony_ci	BCI_SEND(cmd);
608c2ecf20Sopenharmony_ci	BCI_SEND(BCI_X_Y(sx, sy));
618c2ecf20Sopenharmony_ci	BCI_SEND(BCI_X_Y(dx, dy));
628c2ecf20Sopenharmony_ci	BCI_SEND(BCI_W_H(region->width, region->height));
638c2ecf20Sopenharmony_ci}
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_civoid savagefb_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
668c2ecf20Sopenharmony_ci{
678c2ecf20Sopenharmony_ci	struct savagefb_par *par = info->par;
688c2ecf20Sopenharmony_ci	int cmd, color;
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci	if (!rect->width || !rect->height)
718c2ecf20Sopenharmony_ci		return;
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
748c2ecf20Sopenharmony_ci		color = rect->color;
758c2ecf20Sopenharmony_ci	else
768c2ecf20Sopenharmony_ci		color = ((u32 *)info->pseudo_palette)[rect->color];
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_ci	cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |
798c2ecf20Sopenharmony_ci	      BCI_CMD_DEST_GBD | BCI_CMD_SRC_SOLID |
808c2ecf20Sopenharmony_ci	      BCI_CMD_SEND_COLOR;
818c2ecf20Sopenharmony_ci
828c2ecf20Sopenharmony_ci	par->bci_ptr = 0;
838c2ecf20Sopenharmony_ci	BCI_CMD_SET_ROP(cmd, savagefb_rop[rect->rop]);
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci	par->SavageWaitFifo(par,4);
868c2ecf20Sopenharmony_ci	BCI_SEND(cmd);
878c2ecf20Sopenharmony_ci	BCI_SEND(color);
888c2ecf20Sopenharmony_ci	BCI_SEND( BCI_X_Y(rect->dx, rect->dy) );
898c2ecf20Sopenharmony_ci	BCI_SEND( BCI_W_H(rect->width, rect->height) );
908c2ecf20Sopenharmony_ci}
918c2ecf20Sopenharmony_ci
928c2ecf20Sopenharmony_civoid savagefb_imageblit(struct fb_info *info, const struct fb_image *image)
938c2ecf20Sopenharmony_ci{
948c2ecf20Sopenharmony_ci	struct savagefb_par *par = info->par;
958c2ecf20Sopenharmony_ci	int fg, bg, size, i, width;
968c2ecf20Sopenharmony_ci	int cmd;
978c2ecf20Sopenharmony_ci	u32 *src = (u32 *) image->data;
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci	if (!image->width || !image->height)
1008c2ecf20Sopenharmony_ci		return;
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci	if (image->depth != 1) {
1038c2ecf20Sopenharmony_ci		cfb_imageblit(info, image);
1048c2ecf20Sopenharmony_ci		return;
1058c2ecf20Sopenharmony_ci	}
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci	if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) {
1088c2ecf20Sopenharmony_ci		fg = image->fg_color;
1098c2ecf20Sopenharmony_ci		bg = image->bg_color;
1108c2ecf20Sopenharmony_ci	} else {
1118c2ecf20Sopenharmony_ci		fg = ((u32 *)info->pseudo_palette)[image->fg_color];
1128c2ecf20Sopenharmony_ci		bg = ((u32 *)info->pseudo_palette)[image->bg_color];
1138c2ecf20Sopenharmony_ci	}
1148c2ecf20Sopenharmony_ci
1158c2ecf20Sopenharmony_ci	cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |
1168c2ecf20Sopenharmony_ci	      BCI_CMD_CLIP_LR | BCI_CMD_DEST_GBD | BCI_CMD_SRC_MONO |
1178c2ecf20Sopenharmony_ci	      BCI_CMD_SEND_COLOR;
1188c2ecf20Sopenharmony_ci
1198c2ecf20Sopenharmony_ci	par->bci_ptr = 0;
1208c2ecf20Sopenharmony_ci	BCI_CMD_SET_ROP(cmd, savagefb_rop[0]);
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_ci	width = (image->width + 31) & ~31;
1238c2ecf20Sopenharmony_ci	size = (width * image->height)/8;
1248c2ecf20Sopenharmony_ci	size >>= 2;
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci	par->SavageWaitFifo(par, size + 5);
1278c2ecf20Sopenharmony_ci	BCI_SEND(cmd);
1288c2ecf20Sopenharmony_ci	BCI_SEND(BCI_CLIP_LR(image->dx, image->dx + image->width - 1));
1298c2ecf20Sopenharmony_ci	BCI_SEND(fg);
1308c2ecf20Sopenharmony_ci	BCI_SEND(bg);
1318c2ecf20Sopenharmony_ci	BCI_SEND(BCI_X_Y(image->dx, image->dy));
1328c2ecf20Sopenharmony_ci	BCI_SEND(BCI_W_H(width, image->height));
1338c2ecf20Sopenharmony_ci	for (i = 0; i < size; i++)
1348c2ecf20Sopenharmony_ci		BCI_SEND(src[i]);
1358c2ecf20Sopenharmony_ci}
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ciMODULE_LICENSE("GPL");
138