15e0f8ad0SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later 2f7018c21STomi Valkeinen /* 3f7018c21STomi Valkeinen * SiS 300/540/630[S]/730[S], 4f7018c21STomi Valkeinen * SiS 315[E|PRO]/550/[M]650/651/[M]661[F|M]X/740/[M]741[GX]/330/[M]760[GX], 5f7018c21STomi Valkeinen * XGI V3XT/V5/V8, Z7 6f7018c21STomi Valkeinen * frame buffer driver for Linux kernels >= 2.4.14 and >=2.6.3 7f7018c21STomi Valkeinen * 8f7018c21STomi Valkeinen * 2D acceleration part 9f7018c21STomi Valkeinen * 10f7018c21STomi Valkeinen * Based on the XFree86/X.org driver which is 11f7018c21STomi Valkeinen * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria 12f7018c21STomi Valkeinen * 13f7018c21STomi Valkeinen * Author: Thomas Winischhofer <thomas@winischhofer.net> 14f7018c21STomi Valkeinen * (see http://www.winischhofer.net/ 15f7018c21STomi Valkeinen * for more information and updates) 16f7018c21STomi Valkeinen */ 17f7018c21STomi Valkeinen 18f7018c21STomi Valkeinen #include <linux/module.h> 19f7018c21STomi Valkeinen #include <linux/kernel.h> 20f7018c21STomi Valkeinen #include <linux/fb.h> 21f7018c21STomi Valkeinen #include <linux/ioport.h> 22f7018c21STomi Valkeinen #include <linux/types.h> 23f7018c21STomi Valkeinen #include <asm/io.h> 24f7018c21STomi Valkeinen 25f7018c21STomi Valkeinen #include "sis.h" 26f7018c21STomi Valkeinen #include "sis_accel.h" 27f7018c21STomi Valkeinen 28f7018c21STomi Valkeinen static const u8 sisALUConv[] = 29f7018c21STomi Valkeinen { 30f7018c21STomi Valkeinen 0x00, /* dest = 0; 0, GXclear, 0 */ 31f7018c21STomi Valkeinen 0x88, /* dest &= src; DSa, GXand, 0x1 */ 32f7018c21STomi Valkeinen 0x44, /* dest = src & ~dest; SDna, GXandReverse, 0x2 */ 33f7018c21STomi Valkeinen 0xCC, /* dest = src; S, GXcopy, 0x3 */ 34f7018c21STomi Valkeinen 0x22, /* dest &= ~src; DSna, GXandInverted, 0x4 */ 35f7018c21STomi Valkeinen 0xAA, /* dest = dest; D, GXnoop, 0x5 */ 36f7018c21STomi Valkeinen 0x66, /* dest = ^src; DSx, GXxor, 0x6 */ 37f7018c21STomi Valkeinen 0xEE, /* dest |= src; DSo, GXor, 0x7 */ 38f7018c21STomi Valkeinen 0x11, /* dest = ~src & ~dest; DSon, GXnor, 0x8 */ 39f7018c21STomi Valkeinen 0x99, /* dest ^= ~src ; DSxn, GXequiv, 0x9 */ 40f7018c21STomi Valkeinen 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */ 41f7018c21STomi Valkeinen 0xDD, /* dest = src|~dest ; SDno, GXorReverse, 0xB */ 42f7018c21STomi Valkeinen 0x33, /* dest = ~src; Sn, GXcopyInverted, 0xC */ 43f7018c21STomi Valkeinen 0xBB, /* dest |= ~src; DSno, GXorInverted, 0xD */ 44f7018c21STomi Valkeinen 0x77, /* dest = ~src|~dest; DSan, GXnand, 0xE */ 45f7018c21STomi Valkeinen 0xFF, /* dest = 0xFF; 1, GXset, 0xF */ 46f7018c21STomi Valkeinen }; 47f7018c21STomi Valkeinen /* same ROP but with Pattern as Source */ 48f7018c21STomi Valkeinen static const u8 sisPatALUConv[] = 49f7018c21STomi Valkeinen { 50f7018c21STomi Valkeinen 0x00, /* dest = 0; 0, GXclear, 0 */ 51f7018c21STomi Valkeinen 0xA0, /* dest &= src; DPa, GXand, 0x1 */ 52f7018c21STomi Valkeinen 0x50, /* dest = src & ~dest; PDna, GXandReverse, 0x2 */ 53f7018c21STomi Valkeinen 0xF0, /* dest = src; P, GXcopy, 0x3 */ 54f7018c21STomi Valkeinen 0x0A, /* dest &= ~src; DPna, GXandInverted, 0x4 */ 55f7018c21STomi Valkeinen 0xAA, /* dest = dest; D, GXnoop, 0x5 */ 56f7018c21STomi Valkeinen 0x5A, /* dest = ^src; DPx, GXxor, 0x6 */ 57f7018c21STomi Valkeinen 0xFA, /* dest |= src; DPo, GXor, 0x7 */ 58f7018c21STomi Valkeinen 0x05, /* dest = ~src & ~dest; DPon, GXnor, 0x8 */ 59f7018c21STomi Valkeinen 0xA5, /* dest ^= ~src ; DPxn, GXequiv, 0x9 */ 60f7018c21STomi Valkeinen 0x55, /* dest = ~dest; Dn, GXInvert, 0xA */ 61f7018c21STomi Valkeinen 0xF5, /* dest = src|~dest ; PDno, GXorReverse, 0xB */ 62f7018c21STomi Valkeinen 0x0F, /* dest = ~src; Pn, GXcopyInverted, 0xC */ 63f7018c21STomi Valkeinen 0xAF, /* dest |= ~src; DPno, GXorInverted, 0xD */ 64f7018c21STomi Valkeinen 0x5F, /* dest = ~src|~dest; DPan, GXnand, 0xE */ 65f7018c21STomi Valkeinen 0xFF, /* dest = 0xFF; 1, GXset, 0xF */ 66f7018c21STomi Valkeinen }; 67f7018c21STomi Valkeinen 68f7018c21STomi Valkeinen static const int myrops[] = { 69f7018c21STomi Valkeinen 3, 10, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 70f7018c21STomi Valkeinen }; 71f7018c21STomi Valkeinen 72f7018c21STomi Valkeinen /* 300 series ----------------------------------------------------- */ 73f7018c21STomi Valkeinen #ifdef CONFIG_FB_SIS_300 74f7018c21STomi Valkeinen static void 75f7018c21STomi Valkeinen SiS300Sync(struct sis_video_info *ivideo) 76f7018c21STomi Valkeinen { 77f7018c21STomi Valkeinen SiS300Idle 78f7018c21STomi Valkeinen } 79f7018c21STomi Valkeinen 80f7018c21STomi Valkeinen static void 81f7018c21STomi Valkeinen SiS300SetupForScreenToScreenCopy(struct sis_video_info *ivideo, int xdir, int ydir, 82f7018c21STomi Valkeinen int rop, int trans_color) 83f7018c21STomi Valkeinen { 84f7018c21STomi Valkeinen SiS300SetupDSTColorDepth(ivideo->DstColor); 85f7018c21STomi Valkeinen SiS300SetupSRCPitch(ivideo->video_linelength) 86f7018c21STomi Valkeinen SiS300SetupDSTRect(ivideo->video_linelength, 0xffff) 87f7018c21STomi Valkeinen 88f7018c21STomi Valkeinen if(trans_color != -1) { 89f7018c21STomi Valkeinen SiS300SetupROP(0x0A) 90f7018c21STomi Valkeinen SiS300SetupSRCTrans(trans_color) 91f7018c21STomi Valkeinen SiS300SetupCMDFlag(TRANSPARENT_BITBLT) 92f7018c21STomi Valkeinen } else { 93f7018c21STomi Valkeinen SiS300SetupROP(sisALUConv[rop]) 94f7018c21STomi Valkeinen } 95f7018c21STomi Valkeinen if(xdir > 0) { 96f7018c21STomi Valkeinen SiS300SetupCMDFlag(X_INC) 97f7018c21STomi Valkeinen } 98f7018c21STomi Valkeinen if(ydir > 0) { 99f7018c21STomi Valkeinen SiS300SetupCMDFlag(Y_INC) 100f7018c21STomi Valkeinen } 101f7018c21STomi Valkeinen } 102f7018c21STomi Valkeinen 103f7018c21STomi Valkeinen static void 104f7018c21STomi Valkeinen SiS300SubsequentScreenToScreenCopy(struct sis_video_info *ivideo, int src_x, 105f7018c21STomi Valkeinen int src_y, int dst_x, int dst_y, int width, int height) 106f7018c21STomi Valkeinen { 107f7018c21STomi Valkeinen u32 srcbase = 0, dstbase = 0; 108f7018c21STomi Valkeinen 109f7018c21STomi Valkeinen if(src_y >= 2048) { 110f7018c21STomi Valkeinen srcbase = ivideo->video_linelength * src_y; 111f7018c21STomi Valkeinen src_y = 0; 112f7018c21STomi Valkeinen } 113f7018c21STomi Valkeinen if(dst_y >= 2048) { 114f7018c21STomi Valkeinen dstbase = ivideo->video_linelength * dst_y; 115f7018c21STomi Valkeinen dst_y = 0; 116f7018c21STomi Valkeinen } 117f7018c21STomi Valkeinen 118f7018c21STomi Valkeinen SiS300SetupSRCBase(srcbase); 119f7018c21STomi Valkeinen SiS300SetupDSTBase(dstbase); 120f7018c21STomi Valkeinen 121f7018c21STomi Valkeinen if(!(ivideo->CommandReg & X_INC)) { 122f7018c21STomi Valkeinen src_x += width-1; 123f7018c21STomi Valkeinen dst_x += width-1; 124f7018c21STomi Valkeinen } 125f7018c21STomi Valkeinen if(!(ivideo->CommandReg & Y_INC)) { 126f7018c21STomi Valkeinen src_y += height-1; 127f7018c21STomi Valkeinen dst_y += height-1; 128f7018c21STomi Valkeinen } 129f7018c21STomi Valkeinen SiS300SetupRect(width, height) 130f7018c21STomi Valkeinen SiS300SetupSRCXY(src_x, src_y) 131f7018c21STomi Valkeinen SiS300SetupDSTXY(dst_x, dst_y) 132f7018c21STomi Valkeinen SiS300DoCMD 133f7018c21STomi Valkeinen } 134f7018c21STomi Valkeinen 135f7018c21STomi Valkeinen static void 136f7018c21STomi Valkeinen SiS300SetupForSolidFill(struct sis_video_info *ivideo, u32 color, int rop) 137f7018c21STomi Valkeinen { 138f7018c21STomi Valkeinen SiS300SetupPATFG(color) 139f7018c21STomi Valkeinen SiS300SetupDSTRect(ivideo->video_linelength, 0xffff) 140f7018c21STomi Valkeinen SiS300SetupDSTColorDepth(ivideo->DstColor); 141f7018c21STomi Valkeinen SiS300SetupROP(sisPatALUConv[rop]) 142f7018c21STomi Valkeinen SiS300SetupCMDFlag(PATFG) 143f7018c21STomi Valkeinen } 144f7018c21STomi Valkeinen 145f7018c21STomi Valkeinen static void 146f7018c21STomi Valkeinen SiS300SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w, int h) 147f7018c21STomi Valkeinen { 148f7018c21STomi Valkeinen u32 dstbase = 0; 149f7018c21STomi Valkeinen 150f7018c21STomi Valkeinen if(y >= 2048) { 151f7018c21STomi Valkeinen dstbase = ivideo->video_linelength * y; 152f7018c21STomi Valkeinen y = 0; 153f7018c21STomi Valkeinen } 154f7018c21STomi Valkeinen SiS300SetupDSTBase(dstbase) 155f7018c21STomi Valkeinen SiS300SetupDSTXY(x,y) 156f7018c21STomi Valkeinen SiS300SetupRect(w,h) 157f7018c21STomi Valkeinen SiS300SetupCMDFlag(X_INC | Y_INC | BITBLT) 158f7018c21STomi Valkeinen SiS300DoCMD 159f7018c21STomi Valkeinen } 160f7018c21STomi Valkeinen #endif 161f7018c21STomi Valkeinen 162f7018c21STomi Valkeinen /* 315/330/340 series ---------------------------------------------- */ 163f7018c21STomi Valkeinen 164f7018c21STomi Valkeinen #ifdef CONFIG_FB_SIS_315 165f7018c21STomi Valkeinen static void 166f7018c21STomi Valkeinen SiS310Sync(struct sis_video_info *ivideo) 167f7018c21STomi Valkeinen { 168f7018c21STomi Valkeinen SiS310Idle 169f7018c21STomi Valkeinen } 170f7018c21STomi Valkeinen 171f7018c21STomi Valkeinen static void 172f7018c21STomi Valkeinen SiS310SetupForScreenToScreenCopy(struct sis_video_info *ivideo, int rop, int trans_color) 173f7018c21STomi Valkeinen { 174f7018c21STomi Valkeinen SiS310SetupDSTColorDepth(ivideo->DstColor); 175f7018c21STomi Valkeinen SiS310SetupSRCPitch(ivideo->video_linelength) 176f7018c21STomi Valkeinen SiS310SetupDSTRect(ivideo->video_linelength, 0x0fff) 177f7018c21STomi Valkeinen if(trans_color != -1) { 178f7018c21STomi Valkeinen SiS310SetupROP(0x0A) 179f7018c21STomi Valkeinen SiS310SetupSRCTrans(trans_color) 180f7018c21STomi Valkeinen SiS310SetupCMDFlag(TRANSPARENT_BITBLT) 181f7018c21STomi Valkeinen } else { 182f7018c21STomi Valkeinen SiS310SetupROP(sisALUConv[rop]) 183f7018c21STomi Valkeinen /* Set command - not needed, both 0 */ 184f7018c21STomi Valkeinen /* SiSSetupCMDFlag(BITBLT | SRCVIDEO) */ 185f7018c21STomi Valkeinen } 186f7018c21STomi Valkeinen SiS310SetupCMDFlag(ivideo->SiS310_AccelDepth) 187f7018c21STomi Valkeinen /* The chip is smart enough to know the direction */ 188f7018c21STomi Valkeinen } 189f7018c21STomi Valkeinen 190f7018c21STomi Valkeinen static void 191f7018c21STomi Valkeinen SiS310SubsequentScreenToScreenCopy(struct sis_video_info *ivideo, int src_x, int src_y, 192f7018c21STomi Valkeinen int dst_x, int dst_y, int width, int height) 193f7018c21STomi Valkeinen { 194f7018c21STomi Valkeinen u32 srcbase = 0, dstbase = 0; 195f7018c21STomi Valkeinen int mymin = min(src_y, dst_y); 196f7018c21STomi Valkeinen int mymax = max(src_y, dst_y); 197f7018c21STomi Valkeinen 198f7018c21STomi Valkeinen /* Although the chip knows the direction to use 199f7018c21STomi Valkeinen * if the source and destination areas overlap, 200f7018c21STomi Valkeinen * that logic fails if we fiddle with the bitmap 201f7018c21STomi Valkeinen * addresses. Therefore, we check if the source 202f7018c21STomi Valkeinen * and destination blitting areas overlap and 203f7018c21STomi Valkeinen * adapt the bitmap addresses synchronously 204f7018c21STomi Valkeinen * if the coordinates exceed the valid range. 205*a4f7fcd7SJilin Yuan * The areas do not overlap, we do our 206f7018c21STomi Valkeinen * normal check. 207f7018c21STomi Valkeinen */ 208f7018c21STomi Valkeinen if((mymax - mymin) < height) { 209f7018c21STomi Valkeinen if((src_y >= 2048) || (dst_y >= 2048)) { 210f7018c21STomi Valkeinen srcbase = ivideo->video_linelength * mymin; 211f7018c21STomi Valkeinen dstbase = ivideo->video_linelength * mymin; 212f7018c21STomi Valkeinen src_y -= mymin; 213f7018c21STomi Valkeinen dst_y -= mymin; 214f7018c21STomi Valkeinen } 215f7018c21STomi Valkeinen } else { 216f7018c21STomi Valkeinen if(src_y >= 2048) { 217f7018c21STomi Valkeinen srcbase = ivideo->video_linelength * src_y; 218f7018c21STomi Valkeinen src_y = 0; 219f7018c21STomi Valkeinen } 220f7018c21STomi Valkeinen if(dst_y >= 2048) { 221f7018c21STomi Valkeinen dstbase = ivideo->video_linelength * dst_y; 222f7018c21STomi Valkeinen dst_y = 0; 223f7018c21STomi Valkeinen } 224f7018c21STomi Valkeinen } 225f7018c21STomi Valkeinen 226f7018c21STomi Valkeinen srcbase += ivideo->video_offset; 227f7018c21STomi Valkeinen dstbase += ivideo->video_offset; 228f7018c21STomi Valkeinen 229f7018c21STomi Valkeinen SiS310SetupSRCBase(srcbase); 230f7018c21STomi Valkeinen SiS310SetupDSTBase(dstbase); 231f7018c21STomi Valkeinen SiS310SetupRect(width, height) 232f7018c21STomi Valkeinen SiS310SetupSRCXY(src_x, src_y) 233f7018c21STomi Valkeinen SiS310SetupDSTXY(dst_x, dst_y) 234f7018c21STomi Valkeinen SiS310DoCMD 235f7018c21STomi Valkeinen } 236f7018c21STomi Valkeinen 237f7018c21STomi Valkeinen static void 238f7018c21STomi Valkeinen SiS310SetupForSolidFill(struct sis_video_info *ivideo, u32 color, int rop) 239f7018c21STomi Valkeinen { 240f7018c21STomi Valkeinen SiS310SetupPATFG(color) 241f7018c21STomi Valkeinen SiS310SetupDSTRect(ivideo->video_linelength, 0x0fff) 242f7018c21STomi Valkeinen SiS310SetupDSTColorDepth(ivideo->DstColor); 243f7018c21STomi Valkeinen SiS310SetupROP(sisPatALUConv[rop]) 244f7018c21STomi Valkeinen SiS310SetupCMDFlag(PATFG | ivideo->SiS310_AccelDepth) 245f7018c21STomi Valkeinen } 246f7018c21STomi Valkeinen 247f7018c21STomi Valkeinen static void 248f7018c21STomi Valkeinen SiS310SubsequentSolidFillRect(struct sis_video_info *ivideo, int x, int y, int w, int h) 249f7018c21STomi Valkeinen { 250f7018c21STomi Valkeinen u32 dstbase = 0; 251f7018c21STomi Valkeinen 252f7018c21STomi Valkeinen if(y >= 2048) { 253f7018c21STomi Valkeinen dstbase = ivideo->video_linelength * y; 254f7018c21STomi Valkeinen y = 0; 255f7018c21STomi Valkeinen } 256f7018c21STomi Valkeinen dstbase += ivideo->video_offset; 257f7018c21STomi Valkeinen SiS310SetupDSTBase(dstbase) 258f7018c21STomi Valkeinen SiS310SetupDSTXY(x,y) 259f7018c21STomi Valkeinen SiS310SetupRect(w,h) 260f7018c21STomi Valkeinen SiS310SetupCMDFlag(BITBLT) 261f7018c21STomi Valkeinen SiS310DoCMD 262f7018c21STomi Valkeinen } 263f7018c21STomi Valkeinen #endif 264f7018c21STomi Valkeinen 265f7018c21STomi Valkeinen /* --------------------------------------------------------------------- */ 266f7018c21STomi Valkeinen 267f7018c21STomi Valkeinen /* The exported routines */ 268f7018c21STomi Valkeinen 269f7018c21STomi Valkeinen int sisfb_initaccel(struct sis_video_info *ivideo) 270f7018c21STomi Valkeinen { 271f7018c21STomi Valkeinen #ifdef SISFB_USE_SPINLOCKS 272f7018c21STomi Valkeinen spin_lock_init(&ivideo->lockaccel); 273f7018c21STomi Valkeinen #endif 274f7018c21STomi Valkeinen return 0; 275f7018c21STomi Valkeinen } 276f7018c21STomi Valkeinen 277f7018c21STomi Valkeinen void sisfb_syncaccel(struct sis_video_info *ivideo) 278f7018c21STomi Valkeinen { 279f7018c21STomi Valkeinen if(ivideo->sisvga_engine == SIS_300_VGA) { 280f7018c21STomi Valkeinen #ifdef CONFIG_FB_SIS_300 281f7018c21STomi Valkeinen SiS300Sync(ivideo); 282f7018c21STomi Valkeinen #endif 283f7018c21STomi Valkeinen } else { 284f7018c21STomi Valkeinen #ifdef CONFIG_FB_SIS_315 285f7018c21STomi Valkeinen SiS310Sync(ivideo); 286f7018c21STomi Valkeinen #endif 287f7018c21STomi Valkeinen } 288f7018c21STomi Valkeinen } 289f7018c21STomi Valkeinen 290f7018c21STomi Valkeinen int fbcon_sis_sync(struct fb_info *info) 291f7018c21STomi Valkeinen { 292f7018c21STomi Valkeinen struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 293f7018c21STomi Valkeinen CRITFLAGS 294f7018c21STomi Valkeinen 295f7018c21STomi Valkeinen if((!ivideo->accel) || (!ivideo->engineok)) 296f7018c21STomi Valkeinen return 0; 297f7018c21STomi Valkeinen 298f7018c21STomi Valkeinen CRITBEGIN 299f7018c21STomi Valkeinen sisfb_syncaccel(ivideo); 300f7018c21STomi Valkeinen CRITEND 301f7018c21STomi Valkeinen 302f7018c21STomi Valkeinen return 0; 303f7018c21STomi Valkeinen } 304f7018c21STomi Valkeinen 305f7018c21STomi Valkeinen void fbcon_sis_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 306f7018c21STomi Valkeinen { 307f7018c21STomi Valkeinen struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 308f7018c21STomi Valkeinen u32 col = 0; 309f7018c21STomi Valkeinen u32 vxres = info->var.xres_virtual; 310f7018c21STomi Valkeinen u32 vyres = info->var.yres_virtual; 311f7018c21STomi Valkeinen int width, height; 312f7018c21STomi Valkeinen CRITFLAGS 313f7018c21STomi Valkeinen 314f7018c21STomi Valkeinen if(info->state != FBINFO_STATE_RUNNING) 315f7018c21STomi Valkeinen return; 316f7018c21STomi Valkeinen 317f7018c21STomi Valkeinen if((!ivideo->accel) || (!ivideo->engineok)) { 318f7018c21STomi Valkeinen cfb_fillrect(info, rect); 319f7018c21STomi Valkeinen return; 320f7018c21STomi Valkeinen } 321f7018c21STomi Valkeinen 322f7018c21STomi Valkeinen if(!rect->width || !rect->height || rect->dx >= vxres || rect->dy >= vyres) 323f7018c21STomi Valkeinen return; 324f7018c21STomi Valkeinen 325f7018c21STomi Valkeinen /* Clipping */ 326f7018c21STomi Valkeinen width = ((rect->dx + rect->width) > vxres) ? (vxres - rect->dx) : rect->width; 327f7018c21STomi Valkeinen height = ((rect->dy + rect->height) > vyres) ? (vyres - rect->dy) : rect->height; 328f7018c21STomi Valkeinen 329f7018c21STomi Valkeinen switch(info->var.bits_per_pixel) { 330f7018c21STomi Valkeinen case 8: col = rect->color; 331f7018c21STomi Valkeinen break; 332f7018c21STomi Valkeinen case 16: 333f7018c21STomi Valkeinen case 32: col = ((u32 *)(info->pseudo_palette))[rect->color]; 334f7018c21STomi Valkeinen break; 335f7018c21STomi Valkeinen } 336f7018c21STomi Valkeinen 337f7018c21STomi Valkeinen if(ivideo->sisvga_engine == SIS_300_VGA) { 338f7018c21STomi Valkeinen #ifdef CONFIG_FB_SIS_300 339f7018c21STomi Valkeinen CRITBEGIN 340f7018c21STomi Valkeinen SiS300SetupForSolidFill(ivideo, col, myrops[rect->rop]); 341f7018c21STomi Valkeinen SiS300SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height); 342f7018c21STomi Valkeinen CRITEND 343f7018c21STomi Valkeinen #endif 344f7018c21STomi Valkeinen } else { 345f7018c21STomi Valkeinen #ifdef CONFIG_FB_SIS_315 346f7018c21STomi Valkeinen CRITBEGIN 347f7018c21STomi Valkeinen SiS310SetupForSolidFill(ivideo, col, myrops[rect->rop]); 348f7018c21STomi Valkeinen SiS310SubsequentSolidFillRect(ivideo, rect->dx, rect->dy, width, height); 349f7018c21STomi Valkeinen CRITEND 350f7018c21STomi Valkeinen #endif 351f7018c21STomi Valkeinen } 352f7018c21STomi Valkeinen 353f7018c21STomi Valkeinen sisfb_syncaccel(ivideo); 354f7018c21STomi Valkeinen } 355f7018c21STomi Valkeinen 356f7018c21STomi Valkeinen void fbcon_sis_copyarea(struct fb_info *info, const struct fb_copyarea *area) 357f7018c21STomi Valkeinen { 358f7018c21STomi Valkeinen struct sis_video_info *ivideo = (struct sis_video_info *)info->par; 359f7018c21STomi Valkeinen u32 vxres = info->var.xres_virtual; 360f7018c21STomi Valkeinen u32 vyres = info->var.yres_virtual; 361f7018c21STomi Valkeinen int width = area->width; 362f7018c21STomi Valkeinen int height = area->height; 363f7018c21STomi Valkeinen CRITFLAGS 364f7018c21STomi Valkeinen 365f7018c21STomi Valkeinen if(info->state != FBINFO_STATE_RUNNING) 366f7018c21STomi Valkeinen return; 367f7018c21STomi Valkeinen 368f7018c21STomi Valkeinen if((!ivideo->accel) || (!ivideo->engineok)) { 369f7018c21STomi Valkeinen cfb_copyarea(info, area); 370f7018c21STomi Valkeinen return; 371f7018c21STomi Valkeinen } 372f7018c21STomi Valkeinen 373f7018c21STomi Valkeinen if(!width || !height || 374f7018c21STomi Valkeinen area->sx >= vxres || area->sy >= vyres || 375f7018c21STomi Valkeinen area->dx >= vxres || area->dy >= vyres) 376f7018c21STomi Valkeinen return; 377f7018c21STomi Valkeinen 378f7018c21STomi Valkeinen /* Clipping */ 379f7018c21STomi Valkeinen if((area->sx + width) > vxres) width = vxres - area->sx; 380f7018c21STomi Valkeinen if((area->dx + width) > vxres) width = vxres - area->dx; 381f7018c21STomi Valkeinen if((area->sy + height) > vyres) height = vyres - area->sy; 382f7018c21STomi Valkeinen if((area->dy + height) > vyres) height = vyres - area->dy; 383f7018c21STomi Valkeinen 384f7018c21STomi Valkeinen if(ivideo->sisvga_engine == SIS_300_VGA) { 385f7018c21STomi Valkeinen #ifdef CONFIG_FB_SIS_300 386f7018c21STomi Valkeinen int xdir, ydir; 387f7018c21STomi Valkeinen 388f7018c21STomi Valkeinen if(area->sx < area->dx) xdir = 0; 389f7018c21STomi Valkeinen else xdir = 1; 390f7018c21STomi Valkeinen if(area->sy < area->dy) ydir = 0; 391f7018c21STomi Valkeinen else ydir = 1; 392f7018c21STomi Valkeinen 393f7018c21STomi Valkeinen CRITBEGIN 394f7018c21STomi Valkeinen SiS300SetupForScreenToScreenCopy(ivideo, xdir, ydir, 3, -1); 395f7018c21STomi Valkeinen SiS300SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy, 396f7018c21STomi Valkeinen area->dx, area->dy, width, height); 397f7018c21STomi Valkeinen CRITEND 398f7018c21STomi Valkeinen #endif 399f7018c21STomi Valkeinen } else { 400f7018c21STomi Valkeinen #ifdef CONFIG_FB_SIS_315 401f7018c21STomi Valkeinen CRITBEGIN 402f7018c21STomi Valkeinen SiS310SetupForScreenToScreenCopy(ivideo, 3, -1); 403f7018c21STomi Valkeinen SiS310SubsequentScreenToScreenCopy(ivideo, area->sx, area->sy, 404f7018c21STomi Valkeinen area->dx, area->dy, width, height); 405f7018c21STomi Valkeinen CRITEND 406f7018c21STomi Valkeinen #endif 407f7018c21STomi Valkeinen } 408f7018c21STomi Valkeinen 409f7018c21STomi Valkeinen sisfb_syncaccel(ivideo); 410f7018c21STomi Valkeinen } 411