VServer 1.9.2 (patch-2.6.8.1-vs1.9.2.diff)
[linux-2.6.git] / drivers / video / sis / sis_accel.c
index 07e29d7..30e90a5 100644 (file)
@@ -18,9 +18,7 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
  *
- * Based on the XFree86 driver's sis300_accel.c which is
- *     Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
- * and sis310_accel.c which is
+ * Based on the XFree86/X.org driver which is
  *     Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria
  *
  * Author: Thomas Winischhofer <thomas@winischhofer.net>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/errno.h>
-#include <linux/string.h>
-#include <linux/mm.h>
-#include <linux/tty.h>
-#include <linux/slab.h>
-#include <linux/delay.h>
 #include <linux/fb.h>
 #include <linux/console.h>
 #include <linux/selection.h>
 #include <linux/ioport.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/vt_kern.h>
 #include <linux/capability.h>
 #include <linux/fs.h>
-#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>
 #include <video/fbcon-cfb8.h>
 #include <video/fbcon-cfb32.h>
 #endif
 
-#include "osdef.h"
-#include "vgatypes.h"
-#include "vstruct.h"
-#include "sis_accel.h"
 #include "sis.h"
+#include "sis_accel.h"
 
-extern struct     video_info ivideo;
-extern VGA_ENGINE sisvga_engine;
-extern int sisfb_accel;
-
-static const int sisALUConv[] =
+static const u8 sisALUConv[] =
 {
     0x00,       /* dest = 0;            0,      GXclear,        0 */
     0x88,       /* dest &= src;         DSa,    GXand,          0x1 */
@@ -101,7 +72,7 @@ static const int sisALUConv[] =
     0xFF,       /* dest = 0xFF;         1,      GXset,          0xF */
 };
 /* same ROP but with Pattern as Source */
-static const int sisPatALUConv[] =
+static const u8 sisPatALUConv[] =
 {
     0x00,       /* dest = 0;            0,      GXclear,        0 */
     0xA0,       /* dest &= src;         DPa,    GXand,          0x1 */
@@ -122,26 +93,26 @@ static const int sisPatALUConv[] =
 };
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,34)
-static const unsigned char myrops[] = {
+static const int myrops[] = {
        3, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
-   };
+};
 #endif
 
 /* 300 series ----------------------------------------------------- */
 #ifdef CONFIG_FB_SIS_300
 static void
-SiS300Sync(void)
+SiS300Sync(struct sis_video_info *ivideo)
 {
        SiS300Idle
 }
 
 static void
-SiS300SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
-                                unsigned int planemask, int trans_color)
+SiS300SetupForScreenToScreenCopy(struct sis_video_info *ivideo, int xdir, int ydir,
+                                 int rop, int trans_color)
 {
-       SiS300SetupDSTColorDepth(ivideo.DstColor);
-       SiS300SetupSRCPitch(ivideo.video_linelength)
-       SiS300SetupDSTRect(ivideo.video_linelength, -1)
+       SiS300SetupDSTColorDepth(ivideo->DstColor);
+       SiS300SetupSRCPitch(ivideo->video_linelength)
+       SiS300SetupDSTRect(ivideo->video_linelength, 0xffff)
 
        if(trans_color != -1) {
                SiS300SetupROP(0x0A)
@@ -159,29 +130,28 @@ SiS300SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
 }
 
 static void
-SiS300SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y,
-                                int width, int height)
+SiS300SubsequentScreenToScreenCopy(struct sis_video_info *ivideo, int src_x,
+                                  int src_y, int dst_x, int dst_y, int width, int height)
 {
-       long srcbase, dstbase;
+       u32 srcbase = 0, dstbase = 0;
 
-       srcbase = dstbase = 0;
-       if (src_y >= 2048) {
-               srcbase = ivideo.video_linelength * src_y;
+       if(src_y >= 2048) {
+               srcbase = ivideo->video_linelength * src_y;
                src_y = 0;
        }
-       if (dst_y >= 2048) {
-               dstbase = ivideo.video_linelength * dst_y;
+       if(dst_y >= 2048) {
+               dstbase = ivideo->video_linelength * dst_y;
                dst_y = 0;
        }
 
        SiS300SetupSRCBase(srcbase);
        SiS300SetupDSTBase(dstbase);
 
-       if(!(ivideo.CommandReg & X_INC))  {
+       if(!(ivideo->CommandReg & X_INC))  {
                src_x += width-1;
                dst_x += width-1;
        }
-       if(!(ivideo.CommandReg & Y_INC))  {
+       if(!(ivideo->CommandReg & Y_INC))  {
                src_y += height-1;
                dst_y += height-1;
        }
@@ -192,23 +162,22 @@ SiS300SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y,
 }
 
 static void
-SiS300SetupForSolidFill(int color, int rop, unsigned int planemask)
+SiS300SetupForSolidFill(struct sis_video_info *ivideo, u32 color, int rop)
 {
        SiS300SetupPATFG(color)
-       SiS300SetupDSTRect(ivideo.video_linelength, -1)
-       SiS300SetupDSTColorDepth(ivideo.DstColor);
+       SiS300SetupDSTRect(ivideo->video_linelength, 0xffff)
+       SiS300SetupDSTColorDepth(ivideo->DstColor);
        SiS300SetupROP(sisPatALUConv[rop])
        SiS300SetupCMDFlag(PATFG)
 }
 
 static void
-SiS300SubsequentSolidFillRect(int x, int y, int w, int h)
+SiS300SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w, int h)
 {
-       long dstbase;
+       u32 dstbase = 0;
 
-       dstbase = 0;
        if(y >= 2048) {
-               dstbase = ivideo.video_linelength * y;
+               dstbase = ivideo->video_linelength * y;
                y = 0;
        }
        SiS300SetupDSTBase(dstbase)
@@ -223,19 +192,18 @@ SiS300SubsequentSolidFillRect(int x, int y, int w, int h)
 
 #ifdef CONFIG_FB_SIS_315
 static void
-SiS310Sync(void)
+SiS310Sync(struct sis_video_info *ivideo)
 {
        SiS310Idle
 }
 
 static void
-SiS310SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
-                                unsigned int planemask, int trans_color)
+SiS310SetupForScreenToScreenCopy(struct sis_video_info *ivideo, int rop, int trans_color)
 {
-       SiS310SetupDSTColorDepth(ivideo.DstColor);
-       SiS310SetupSRCPitch(ivideo.video_linelength)
-       SiS310SetupDSTRect(ivideo.video_linelength, -1)
-       if (trans_color != -1) {
+       SiS310SetupDSTColorDepth(ivideo->DstColor);
+       SiS310SetupSRCPitch(ivideo->video_linelength)
+       SiS310SetupDSTRect(ivideo->video_linelength, 0xffff)
+       if(trans_color != -1) {
                SiS310SetupROP(0x0A)
                SiS310SetupSRCTrans(trans_color)
                SiS310SetupCMDFlag(TRANSPARENT_BITBLT)
@@ -244,20 +212,17 @@ SiS310SetupForScreenToScreenCopy(int xdir, int ydir, int rop,
                /* Set command - not needed, both 0 */
                /* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */
        }
-       SiS310SetupCMDFlag(ivideo.SiS310_AccelDepth)
+       SiS310SetupCMDFlag(ivideo->SiS310_AccelDepth)
        /* The 315 series is smart enough to know the direction */
 }
 
 static void
-SiS310SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y,
-                                int width, int height)
+SiS310SubsequentScreenToScreenCopy(struct sis_video_info *ivideo, int src_x, int src_y,
+                        int dst_x, int dst_y, int width, int height)
 {
-       long srcbase, dstbase;
-       int mymin, mymax;
-
-       srcbase = dstbase = 0;
-       mymin = min(src_y, dst_y);
-       mymax = max(src_y, dst_y);
+       u32 srcbase = 0, dstbase = 0;
+       int mymin = min(src_y, dst_y);
+       int mymax = max(src_y, dst_y);
        
        /* Although the chip knows the direction to use
         * if the source and destination areas overlap, 
@@ -271,18 +236,18 @@ SiS310SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y,
         */
        if((mymax - mymin) < height) { 
           if((src_y >= 2048) || (dst_y >= 2048)) {           
-             srcbase = ivideo.video_linelength * mymin;
-             dstbase = ivideo.video_linelength * mymin;
+             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;
+             srcbase = ivideo->video_linelength * src_y;
              src_y = 0;
           }
           if(dst_y >= 2048) {
-             dstbase = ivideo.video_linelength * dst_y;
+             dstbase = ivideo->video_linelength * dst_y;
              dst_y = 0;
           }
        }
@@ -296,23 +261,22 @@ SiS310SubsequentScreenToScreenCopy(int src_x, int src_y, int dst_x, int dst_y,
 }
 
 static void
-SiS310SetupForSolidFill(int color, int rop, unsigned int planemask)
+SiS310SetupForSolidFill(struct sis_video_info *ivideo, u32 color, int rop)
 {
        SiS310SetupPATFG(color)
-       SiS310SetupDSTRect(ivideo.video_linelength, -1)
-       SiS310SetupDSTColorDepth(ivideo.DstColor);
+       SiS310SetupDSTRect(ivideo->video_linelength, 0xffff)
+       SiS310SetupDSTColorDepth(ivideo->DstColor);
        SiS310SetupROP(sisPatALUConv[rop])
-       SiS310SetupCMDFlag(PATFG | ivideo.SiS310_AccelDepth)
+       SiS310SetupCMDFlag(PATFG | ivideo->SiS310_AccelDepth)
 }
 
 static void
-SiS310SubsequentSolidFillRect(int x, int y, int w, int h)
+SiS310SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w, int h)
 {
-       long dstbase;
+       u32 dstbase = 0;
 
-       dstbase = 0;
        if(y >= 2048) {
-               dstbase = ivideo.video_linelength * y;
+               dstbase = ivideo->video_linelength * y;
                y = 0;
        }
        SiS310SetupDSTBase(dstbase)
@@ -327,23 +291,23 @@ SiS310SubsequentSolidFillRect(int x, int y, int w, int h)
 
 /* The exported routines */
 
-int sisfb_initaccel(void)
+int sisfb_initaccel(struct sis_video_info *ivideo)
 {
 #ifdef SISFB_USE_SPINLOCKS
-    spin_lock_init(&ivideo.lockaccel);
+    spin_lock_init(&ivideo->lockaccel);
 #endif
     return(0);
 }
 
-void sisfb_syncaccel(void)
+void sisfb_syncaccel(struct sis_video_info *ivideo)
 {
-    if(sisvga_engine == SIS_300_VGA) {
+    if(ivideo->sisvga_engine == SIS_300_VGA) {
 #ifdef CONFIG_FB_SIS_300
-       SiS300Sync();
+       SiS300Sync(ivideo);
 #endif
     } else {
 #ifdef CONFIG_FB_SIS_315
-       SiS310Sync();
+       SiS310Sync(ivideo);
 #endif
     }
 }
@@ -352,18 +316,19 @@ void sisfb_syncaccel(void)
 
 int fbcon_sis_sync(struct fb_info *info)
 {
+   struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
    CRITFLAGS
 
-   if(!ivideo.accel)
+   if(!ivideo->accel)
        return 0;
 
-   if(sisvga_engine == SIS_300_VGA) {
+   if(ivideo->sisvga_engine == SIS_300_VGA) {
 #ifdef CONFIG_FB_SIS_300
-      SiS300Sync();
+      SiS300Sync(ivideo);
 #endif
    } else {
 #ifdef CONFIG_FB_SIS_315
-      SiS310Sync();
+      SiS310Sync(ivideo);
 #endif
    }
    CRITEND
@@ -372,42 +337,53 @@ int fbcon_sis_sync(struct fb_info *info)
 
 void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 {
-   int col=0;
+   struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+   u32 col = 0;
+   u32 vxres = info->var.xres_virtual;
+   u32 vyres = info->var.yres_virtual;
+   int width, height;
    CRITFLAGS
 
-   TWDEBUG("Inside sis_fillrect");
-   if(!rect->width || !rect->height)
-       return;
+   if(info->state != FBINFO_STATE_RUNNING) {
+       return;
+   }
 
-   if(!ivideo.accel) {
+   if(!ivideo->accel) {
        cfb_fillrect(info, rect);
        return;
    }
    
+   if(!rect->width || !rect->height || rect->dx >= vxres || rect->dy >= vyres) {
+       return;
+   }
+
+   /* Clipping */
+   width = ((rect->dx + rect->width) > vxres) ? (vxres - rect->dx) : rect->width;
+   height = ((rect->dy + rect->height) > vyres) ? (vyres - rect->dy) : rect->height;
+
    switch(info->var.bits_per_pixel) {
        case 8:  col = rect->color;
                 break;
-       case 16: col = ((u32 *)(info->pseudo_palette))[rect->color];
-                break;
+       case 16:
        case 32: col = ((u32 *)(info->pseudo_palette))[rect->color];
                 break;
    }
 
-   if(sisvga_engine == SIS_300_VGA) {
+   if(ivideo->sisvga_engine == SIS_300_VGA) {
 #ifdef CONFIG_FB_SIS_300
       CRITBEGIN
-      SiS300SetupForSolidFill(col, myrops[rect->rop], 0);
-      SiS300SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height);
+      SiS300SetupForSolidFill(ivideo, col, myrops[rect->rop]);
+      SiS300SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
       CRITEND
-      SiS300Sync();
+      SiS300Sync(ivideo);
 #endif
    } else {
 #ifdef CONFIG_FB_SIS_315
       CRITBEGIN
-      SiS310SetupForSolidFill(col, myrops[rect->rop], 0);
-      SiS310SubsequentSolidFillRect(rect->dx, rect->dy, rect->width, rect->height);
+      SiS310SetupForSolidFill(ivideo, col, myrops[rect->rop]);
+      SiS310SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height);
       CRITEND
-      SiS310Sync();
+      SiS310Sync(ivideo);
 #endif
    }
 
@@ -415,38 +391,58 @@ void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect)
 
 void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 {
-   int xdir, ydir;
+   struct sis_video_info *ivideo = (struct sis_video_info *)info->par;
+   u32 vxres = info->var.xres_virtual;
+   u32 vyres = info->var.yres_virtual;
+   int width = area->width;
+   int height = area->height;
    CRITFLAGS
 
-   TWDEBUG("Inside sis_copyarea");
-   if(!ivideo.accel) {
+   if(info->state != FBINFO_STATE_RUNNING) {
+       return;
+   }
+
+   if(!ivideo->accel) {
        cfb_copyarea(info, area);
        return;
    }
 
-   if(!area->width || !area->height)
+   if(!width || !height ||
+      area->sx >= vxres || area->sy >= vyres ||
+      area->dx >= vxres || area->dy >= vyres) {
        return;
+   }
 
-   if(area->sx < area->dx) xdir = 0;
-   else                    xdir = 1;
-   if(area->sy < area->dy) ydir = 0;
-   else                    ydir = 1;
+   /* Clipping */
+   if((area->sx + width) > vxres) width = vxres - area->sx;
+   if((area->dx + width) > vxres) width = vxres - area->dx;
+   if((area->sy + height) > vyres) height = vyres - area->sy;
+   if((area->dy + height) > vyres) height = vyres - area->dy;
 
-   if(sisvga_engine == SIS_300_VGA) {
+   if(ivideo->sisvga_engine == SIS_300_VGA) {
 #ifdef CONFIG_FB_SIS_300
+      int xdir, ydir;
+
+      if(area->sx < area->dx) xdir = 0;
+      else                    xdir = 1;
+      if(area->sy < area->dy) ydir = 0;
+      else                    ydir = 1;
+
       CRITBEGIN
-      SiS300SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
-      SiS300SubsequentScreenToScreenCopy(area->sx, area->sy, area->dx, area->dy, area->width, area->height);
+      SiS300SetupForScreenToScreenCopy(ivideo, xdir, ydir, 3, -1);
+      SiS300SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy, area->dx, area->dy,
+                                        width, height);
       CRITEND
-      SiS300Sync();
+      SiS300Sync(ivideo);
 #endif
    } else {
 #ifdef CONFIG_FB_SIS_315
       CRITBEGIN
-      SiS310SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
-      SiS310SubsequentScreenToScreenCopy(area->sx, area->sy, area->dx, area->dy, area->width, area->height);
+      SiS310SetupForScreenToScreenCopy(ivideo, 3, -1);
+      SiS310SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy, area->dx, area->dy,
+                                        width, height);
       CRITEND
-      SiS310Sync();
+      SiS310Sync(ivideo);
 #endif
    }
 }
@@ -458,11 +454,12 @@ void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area)
 void fbcon_sis_bmove(struct display *p, int srcy, int srcx,
                            int dsty, int dstx, int height, int width)
 {
-        int xdir, ydir;
+       struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
+
        CRITFLAGS
 
-       if(!ivideo.accel) {
-           switch(ivideo.video_bpp) {
+       if(!ivideo->accel) {
+           switch(ivideo->video_bpp) {
            case 8:
 #ifdef FBCON_HAS_CFB8
               fbcon_cfb8_bmove(p, srcy, srcx, dsty, dstx, height, width);
@@ -489,30 +486,28 @@ void fbcon_sis_bmove(struct display *p, int srcy, int srcx,
        width *= fontwidth(p);
        height *= fontheight(p);
 
-       if(srcx < dstx) xdir = 0;
-       else            xdir = 1;
-       if(srcy < dsty) ydir = 0;
-       else            ydir = 1;
-
-       if(sisvga_engine == SIS_300_VGA) {
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
 #ifdef CONFIG_FB_SIS_300
+          int xdir, ydir;
+
+          if(srcx < dstx) xdir = 0;
+          else            xdir = 1;
+          if(srcy < dsty) ydir = 0;
+          else            ydir = 1;
+
           CRITBEGIN
-          SiS300SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
-          SiS300SubsequentScreenToScreenCopy(srcx, srcy, dstx, dsty, width, height);
+          SiS300SetupForScreenToScreenCopy(ivideo, xdir, ydir, 3, -1);
+          SiS300SubsequentScreenToScreenCopy(ivideo, srcx, srcy, dstx, dsty, width, height);
           CRITEND
-          SiS300Sync();
+          SiS300Sync(ivideo);
 #endif
        } else {
 #ifdef CONFIG_FB_SIS_315
           CRITBEGIN
-          SiS310SetupForScreenToScreenCopy(xdir, ydir, 3, 0, -1);
-          SiS310SubsequentScreenToScreenCopy(srcx, srcy, dstx, dsty, width, height);
+          SiS310SetupForScreenToScreenCopy(ivideo, 3, -1);
+          SiS310SubsequentScreenToScreenCopy(ivideo, 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
+          SiS310Sync(ivideo);
 #endif
        }
 }
@@ -520,6 +515,7 @@ void fbcon_sis_bmove(struct display *p, int srcy, int srcx,
 static void fbcon_sis_clear(struct vc_data *conp, struct display *p,
                        int srcy, int srcx, int height, int width, int color)
 {
+        struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
        CRITFLAGS
 
        srcx *= fontwidth(p);
@@ -527,21 +523,21 @@ static void fbcon_sis_clear(struct vc_data *conp, struct display *p,
        width *= fontwidth(p);
        height *= fontheight(p);
 
-       if(sisvga_engine == SIS_300_VGA) {
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
 #ifdef CONFIG_FB_SIS_300
           CRITBEGIN
-          SiS300SetupForSolidFill(color, 3, 0);
-          SiS300SubsequentSolidFillRect(srcx, srcy, width, height);
+          SiS300SetupForSolidFill(ivideo, color, 3);
+          SiS300SubsequentSolidFillRect(ivideo, srcx, srcy, width, height);
           CRITEND
-          SiS300Sync();
+          SiS300Sync(ivideo);
 #endif
        } else {
 #ifdef CONFIG_FB_SIS_315
           CRITBEGIN
-          SiS310SetupForSolidFill(color, 3, 0);
-          SiS310SubsequentSolidFillRect(srcx, srcy, width, height);
+          SiS310SetupForSolidFill(ivideo, color, 3);
+          SiS310SubsequentSolidFillRect(ivideo, srcx, srcy, width, height);
           CRITEND
-          SiS310Sync();
+          SiS310Sync(ivideo);
 #endif
        }
 }
@@ -549,9 +545,10 @@ static void fbcon_sis_clear(struct vc_data *conp, struct display *p,
 void fbcon_sis_clear8(struct vc_data *conp, struct display *p,
                        int srcy, int srcx, int height, int width)
 {
+       struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
        u32 bgx;
 
-       if(!ivideo.accel) {
+       if(!ivideo->accel) {
 #ifdef FBCON_HAS_CFB8
            fbcon_cfb8_clear(conp, p, srcy, srcx, height, width);
 #endif
@@ -565,8 +562,10 @@ void fbcon_sis_clear8(struct vc_data *conp, struct display *p,
 void fbcon_sis_clear16(struct vc_data *conp, struct display *p,
                        int srcy, int srcx, int height, int width)
 {
+        struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
        u32 bgx;
-       if(!ivideo.accel) {
+
+       if(!ivideo->accel) {
 #ifdef FBCON_HAS_CFB16
            fbcon_cfb16_clear(conp, p, srcy, srcx, height, width);
 #endif
@@ -580,9 +579,10 @@ void fbcon_sis_clear16(struct vc_data *conp, struct display *p,
 void fbcon_sis_clear32(struct vc_data *conp, struct display *p,
                        int srcy, int srcx, int height, int width)
 {
+       struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
        u32 bgx;
 
-       if(!ivideo.accel) {
+       if(!ivideo->accel) {
 #ifdef FBCON_HAS_CFB32
            fbcon_cfb32_clear(conp, p, srcy, srcx, height, width);
 #endif
@@ -595,10 +595,11 @@ void fbcon_sis_clear32(struct vc_data *conp, struct display *p,
 
 void fbcon_sis_revc(struct display *p, int srcx, int srcy)
 {
+       struct sis_video_info *ivideo = (struct sis_video_info *)p->fb_info->par;
        CRITFLAGS
 
-       if(!ivideo.accel) {
-           switch(ivideo.video_bpp) {
+       if(!ivideo->accel) {
+           switch(ivideo->video_bpp) {
            case 16:
 #ifdef FBCON_HAS_CFB16
               fbcon_cfb16_revc(p, srcx, srcy);
@@ -616,59 +617,59 @@ void fbcon_sis_revc(struct display *p, int srcx, int srcy)
        srcx *= fontwidth(p);
        srcy *= fontheight(p);
 
-       if(sisvga_engine == SIS_300_VGA) {
+       if(ivideo->sisvga_engine == SIS_300_VGA) {
 #ifdef CONFIG_FB_SIS_300
           CRITBEGIN
-          SiS300SetupForSolidFill(0, 0x0a, 0);
-          SiS300SubsequentSolidFillRect(srcx, srcy, fontwidth(p), fontheight(p));
+          SiS300SetupForSolidFill(ivideo, 0, 0x0a);
+          SiS300SubsequentSolidFillRect(ivideo, srcx, srcy, fontwidth(p), fontheight(p));
           CRITEND
-          SiS300Sync();
+          SiS300Sync(ivideo);
 #endif
        } else {
 #ifdef CONFIG_FB_SIS_315
           CRITBEGIN
-          SiS310SetupForSolidFill(0, 0x0a, 0);
-          SiS310SubsequentSolidFillRect(srcx, srcy, fontwidth(p), fontheight(p));
+          SiS310SetupForSolidFill(ivideo, 0, 0x0a);
+          SiS310SubsequentSolidFillRect(ivideo, srcx, srcy, fontwidth(p), fontheight(p));
           CRITEND
-          SiS310Sync();
+          SiS310Sync(ivideo);
 #endif
        }
 }
 
 #ifdef FBCON_HAS_CFB8
 struct display_switch fbcon_sis8 = {
-       .setup                  = fbcon_cfb8_setup,
-       .bmove                  = fbcon_sis_bmove,
-       .clear                  = fbcon_sis_clear8,
-       .putc                   = fbcon_cfb8_putc,
-       .putcs                  = fbcon_cfb8_putcs,
-       .revc                   = fbcon_cfb8_revc,
-       .clear_margins          = fbcon_cfb8_clear_margins,
-       .fontwidthmask          = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+       .setup          = fbcon_cfb8_setup,
+       .bmove          = fbcon_sis_bmove,
+       .clear          = fbcon_sis_clear8,
+       .putc           = fbcon_cfb8_putc,
+       .putcs          = fbcon_cfb8_putcs,
+       .revc           = fbcon_cfb8_revc,
+       .clear_margins  = fbcon_cfb8_clear_margins,
+       .fontwidthmask  = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 #endif
 #ifdef FBCON_HAS_CFB16
 struct display_switch fbcon_sis16 = {
-       .setup                  = fbcon_cfb16_setup,
-       .bmove                  = fbcon_sis_bmove,
-       .clear                  = fbcon_sis_clear16,
-       .putc                   = fbcon_cfb16_putc,
-       .putcs                  = fbcon_cfb16_putcs,
-       .revc                   = fbcon_sis_revc,
-       .clear_margins          = fbcon_cfb16_clear_margins,
-       .fontwidthmask          = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+       .setup          = fbcon_cfb16_setup,
+       .bmove          = fbcon_sis_bmove,
+       .clear          = fbcon_sis_clear16,
+       .putc           = fbcon_cfb16_putc,
+       .putcs          = fbcon_cfb16_putcs,
+       .revc           = fbcon_sis_revc,
+       .clear_margins  = fbcon_cfb16_clear_margins,
+       .fontwidthmask  = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 #endif
 #ifdef FBCON_HAS_CFB32
 struct display_switch fbcon_sis32 = {
-       .setup                  = fbcon_cfb32_setup,
-       .bmove                  = fbcon_sis_bmove,
-       .clear                  = fbcon_sis_clear32,
-       .putc                   = fbcon_cfb32_putc,
-       .putcs                  = fbcon_cfb32_putcs,
-       .revc                   = fbcon_sis_revc,
-       .clear_margins          = fbcon_cfb32_clear_margins,
-       .fontwidthmask          = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+       .setup          = fbcon_cfb32_setup,
+       .bmove          = fbcon_sis_bmove,
+       .clear          = fbcon_sis_clear32,
+       .putc           = fbcon_cfb32_putc,
+       .putcs          = fbcon_cfb32_putcs,
+       .revc           = fbcon_sis_revc,
+       .clear_margins  = fbcon_cfb32_clear_margins,
+       .fontwidthmask  = FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
 };
 #endif