patch-2.4.21 linux-2.4.21/drivers/video/sis/sis_accel.c
Next file: linux-2.4.21/drivers/video/sis/sis_accel.h
Previous file: linux-2.4.21/drivers/video/sis/osdef.h
Back to the patch index
Back to the overall index
- Lines: 284
- Date:
2003-06-13 07:51:37.000000000 -0700
- Orig file:
linux-2.4.20/drivers/video/sis/sis_accel.c
- Orig date:
2002-11-28 15:53:15.000000000 -0800
diff -urN linux-2.4.20/drivers/video/sis/sis_accel.c linux-2.4.21/drivers/video/sis/sis_accel.c
@@ -37,13 +37,21 @@
#include <linux/agp_backend.h>
#include <linux/types.h>
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#include <linux/sisfb.h>
+#else
+#include <video/sisfb.h>
+#endif
#include <asm/io.h>
+
+#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
+#endif
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#include <video/fbcon.h>
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33)
#include <video/fbcon-cfb8.h>
#include <video/fbcon-cfb16.h>
#include <video/fbcon-cfb24.h>
@@ -58,6 +66,7 @@
extern struct video_info ivideo;
extern VGA_ENGINE sisvga_engine;
+extern int sisfb_accel;
static const int sisALUConv[] =
{
@@ -229,15 +238,38 @@
int width, int height)
{
long srcbase, dstbase;
+ int mymin, mymax;
srcbase = dstbase = 0;
- if (src_y >= 2048) {
- srcbase = ivideo.video_linelength * src_y;
- src_y = 0;
- }
- if (dst_y >= 2048) {
- dstbase = ivideo.video_linelength * dst_y;
- dst_y = 0;
+ mymin = min(src_y, dst_y);
+ mymax = max(src_y, dst_y);
+
+ /* Although the chip knows the direction to use
+ * if the source and destination areas overlap,
+ * that logic fails if we fiddle with the bitmap
+ * addresses. Therefore, we check if the source
+ * and destination blitting areas overlap and
+ * adapt the bitmap addresses synchronously
+ * if the coordinates exceed the valid range.
+ * The the areas do not overlap, we do our
+ * normal check.
+ */
+ if((mymax - mymin) < height) {
+ if((src_y >= 2048) || (dst_y >= 2048)) {
+ srcbase = ivideo.video_linelength * mymin;
+ dstbase = ivideo.video_linelength * mymin;
+ src_y -= mymin;
+ dst_y -= mymin;
+ }
+ } else {
+ if(src_y >= 2048) {
+ srcbase = ivideo.video_linelength * src_y;
+ src_y = 0;
+ }
+ if(dst_y >= 2048) {
+ dstbase = ivideo.video_linelength * dst_y;
+ dst_y = 0;
+ }
}
SiS310SetupSRCBase(srcbase);
@@ -287,31 +319,64 @@
return(0);
}
+void sisfb_syncaccel(void)
+{
+ if(sisvga_engine == SIS_300_VGA) {
+ SiS300Sync();
+ } else {
+ SiS310Sync();
+ }
+}
+
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) /* --------------- 2.5 --------------- */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34) /* --- KERNEL 2.5.34 and later --- */
+int fbcon_sis_sync(struct fb_info *info)
+{
+ if(!ivideo.accel)
+ return 0;
+
+ CRITFLAGS
+ if(sisvga_engine == SIS_300_VGA) {
+ SiS300Sync();
+ } else {
+ SiS310Sync();
+ }
+ CRITEND
+ return 0;
+}
-void fbcon_sis_fillrect(struct fb_info *info, struct fb_fillrect *rect)
+void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
{
+ int col=0;
CRITFLAGS
TWDEBUG("Inside sis_fillrect");
if(!rect->width || !rect->height)
return;
- if(!sisfb_accel) {
- cfb_fillrect(info, rect);
+ if(!ivideo.accel) {
+ cfb_fillrect(info, rect);
return;
}
+
+ switch(info->var.bits_per_pixel) {
+ case 8: col = rect->color;
+ break;
+ case 16: col = ((u32 *)(info->pseudo_palette))[rect->color];
+ break;
+ case 32: col = ((u32 *)(info->pseudo_palette))[rect->color];
+ break;
+ }
if(sisvga_engine == SIS_300_VGA) {
CRITBEGIN
- SiS300SetupForSolidFill(rect->color, myrops[rect->rop], 0);
+ SiS300SetupForSolidFill(col, myrops[rect->rop], 0);
SiS300SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height);
CRITEND
SiS300Sync();
} else {
CRITBEGIN
- SiS310SetupForSolidFill(rect->color, myrops[rect->rop], 0);
+ SiS310SetupForSolidFill(col, myrops[rect->rop], 0);
SiS310SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height);
CRITEND
SiS310Sync();
@@ -319,13 +384,13 @@
}
-void fbcon_sis_copyarea(struct fb_info *info, struct fb_copyarea *area)
+void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area)
{
int xdir, ydir;
CRITFLAGS
TWDEBUG("Inside sis_copyarea");
- if(!sisfb_accel) {
+ if(!ivideo.accel) {
cfb_copyarea(info, area);
return;
}
@@ -355,7 +420,7 @@
#endif
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,5,33) /* ------ KERNEL <2.5.34 ------ */
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0) /* -------------- 2.4 --------------- */
void fbcon_sis_bmove(struct display *p, int srcy, int srcx,
int dsty, int dstx, int height, int width)
@@ -363,6 +428,27 @@
int xdir, ydir;
CRITFLAGS
+ if(!ivideo.accel) {
+ switch(ivideo.video_bpp) {
+ case 8:
+#ifdef FBCON_HAS_CFB8
+ fbcon_cfb8_bmove(p, srcy, srcx, dsty, dstx, height, width);
+#endif
+ break;
+ case 16:
+#ifdef FBCON_HAS_CFB16
+ fbcon_cfb16_bmove(p, srcy, srcx, dsty, dstx, height, width);
+#endif
+ break;
+ case 32:
+#ifdef FBCON_HAS_CFB32
+ fbcon_cfb32_bmove(p, srcy, srcx, dsty, dstx, height, width);
+#endif
+ break;
+ }
+ return;
+ }
+
srcx *= fontwidth(p);
srcy *= fontheight(p);
dstx *= fontwidth(p);
@@ -370,7 +456,6 @@
width *= fontwidth(p);
height *= fontheight(p);
-
if(srcx < dstx) xdir = 0;
else xdir = 1;
if(srcy < dsty) ydir = 0;
@@ -388,6 +473,10 @@
SiS310SubsequentScreenToScreenCopy(srcx, srcy, dstx, dsty, width, height);
CRITEND
SiS310Sync();
+#if 0
+ printk(KERN_INFO "sis_bmove sx %d sy %d dx %d dy %d w %d h %d\n",
+ srcx, srcy, dstx, dsty, width, height);
+#endif
}
}
@@ -422,6 +511,13 @@
{
u32 bgx;
+ if(!ivideo.accel) {
+#ifdef FBCON_HAS_CFB8
+ fbcon_cfb8_clear(conp, p, srcy, srcx, height, width);
+#endif
+ return;
+ }
+
bgx = attr_bgcol_ec(p, conp);
fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
}
@@ -430,6 +526,12 @@
int srcy, int srcx, int height, int width)
{
u32 bgx;
+ if(!ivideo.accel) {
+#ifdef FBCON_HAS_CFB16
+ fbcon_cfb16_clear(conp, p, srcy, srcx, height, width);
+#endif
+ return;
+ }
bgx = ((u_int16_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
@@ -440,6 +542,13 @@
{
u32 bgx;
+ if(!ivideo.accel) {
+#ifdef FBCON_HAS_CFB32
+ fbcon_cfb32_clear(conp, p, srcy, srcx, height, width);
+#endif
+ return;
+ }
+
bgx = ((u_int32_t*)p->dispsw_data)[attr_bgcol_ec(p, conp)];
fbcon_sis_clear(conp, p, srcy, srcx, height, width, bgx);
}
@@ -448,6 +557,22 @@
{
CRITFLAGS
+ if(!ivideo.accel) {
+ switch(ivideo.video_bpp) {
+ case 16:
+#ifdef FBCON_HAS_CFB16
+ fbcon_cfb16_revc(p, srcx, srcy);
+#endif
+ break;
+ case 32:
+#ifdef FBCON_HAS_CFB32
+ fbcon_cfb32_revc(p, srcx, srcy);
+#endif
+ break;
+ }
+ return;
+ }
+
srcx *= fontwidth(p);
srcy *= fontheight(p);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)