Commit 6c369b2b authored by James Simmons's avatar James Simmons

Merge heisenberg.transvirtual.com:/tmp/linus-2.5

into heisenberg.transvirtual.com:/tmp/fbdev-2.5
parents e6d19c6a c90d7cc5
...@@ -265,7 +265,7 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -265,7 +265,7 @@ if [ "$CONFIG_FB" = "y" ]; then
if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_ATARI" = "y" -o \ if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_ATARI" = "y" -o \
"$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_MAC" = "y" -o \ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
"$CONFIG_FB_OF" = "y" -o "$CONFIG_FB_TGA" = "y" -o \ "$CONFIG_FB_OF" = "y" -o "$CONFIG_FB_TGA" = "y" -o \
"$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ "$CONFIG_FB_NEOMAGIC" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
"$CONFIG_FB_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "y" -o \ "$CONFIG_FB_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "y" -o \
"$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
"$CONFIG_FB_CGFOURTEEN" = "y" -o "$CONFIG_FB_G364" = "y" -o \ "$CONFIG_FB_CGFOURTEEN" = "y" -o "$CONFIG_FB_G364" = "y" -o \
...@@ -279,13 +279,13 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -279,13 +279,13 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_SA1100" = "y" -o "$CONFIG_FB_3DFX" = "y" -o \ "$CONFIG_FB_SA1100" = "y" -o "$CONFIG_FB_3DFX" = "y" -o \
"$CONFIG_FB_PMAG_BA" = "y" -o "$CONFIG_FB_PMAGB_B" = "y" -o \ "$CONFIG_FB_PMAG_BA" = "y" -o "$CONFIG_FB_PMAGB_B" = "y" -o \
"$CONFIG_FB_MAXINE" = "y" -o "$CONFIG_FB_TX3912" = "y" -o \ "$CONFIG_FB_MAXINE" = "y" -o "$CONFIG_FB_TX3912" = "y" -o \
"$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_NEOMAGIC" = "y" ]; then "$CONFIG_FB_SIS" = "y" ]; then
define_tristate CONFIG_FBCON_CFB8 y define_tristate CONFIG_FBCON_CFB8 y
else else
if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \ if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
"$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_MAC" = "m" -o \ "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_MAC" = "m" -o \
"$CONFIG_FB_OF" = "m" -o "$CONFIG_FB_TGA" = "m" -o \ "$CONFIG_FB_OF" = "m" -o "$CONFIG_FB_TGA" = "m" -o \
"$CONFIG_FB_VESA" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ "$CONFIG_FB_NEOMAGIC" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
"$CONFIG_FB_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "m" -o \ "$CONFIG_FB_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "m" -o \
"$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
"$CONFIG_FB_CGFOURTEEN" = "m" -o "$CONFIG_FB_G364" = "m" -o \ "$CONFIG_FB_CGFOURTEEN" = "m" -o "$CONFIG_FB_G364" = "m" -o \
...@@ -299,12 +299,12 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -299,12 +299,12 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_PMAG_BA" = "m" -o "$CONFIG_FB_PMAGB_B" = "m" -o \ "$CONFIG_FB_PMAG_BA" = "m" -o "$CONFIG_FB_PMAGB_B" = "m" -o \
"$CONFIG_FB_MAXINE" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \ "$CONFIG_FB_MAXINE" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
"$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_SIS" = "m" -o \ "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
"$CONFIG_FB_TX3912" = "m" -o "$CONFIG_FB_NEOMAGIC" = "m" ]; then "$CONFIG_FB_TX3912" = "m" ]; then
define_tristate CONFIG_FBCON_CFB8 m define_tristate CONFIG_FBCON_CFB8 m
fi fi
fi fi
if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \ if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \
"$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_VESA" = "y" -o \ "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_NEOMAGIC" = "y" -o \
"$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \ "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \
"$CONFIG_FB_Q40" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \ "$CONFIG_FB_Q40" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \
"$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
...@@ -315,12 +315,11 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -315,12 +315,11 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \ "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \
"$CONFIG_FB_CYBER2000" = "y" -o "$CONFIG_FB_3DFX" = "y" -o \ "$CONFIG_FB_CYBER2000" = "y" -o "$CONFIG_FB_3DFX" = "y" -o \
"$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SA1100" = "y" -o \ "$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SA1100" = "y" -o \
"$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_VOODOO1" = "y" -o \ "$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_VOODOO1" = "y" ]; then
"$CONFIG_FB_NEOMAGIC" = "y" ]; then
define_tristate CONFIG_FBCON_CFB16 y define_tristate CONFIG_FBCON_CFB16 y
else else
if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
"$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VESA" = "m" -o \ "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_NEOMAGIC" = "m" -o \
"$CONFIG_FB_VIRTUAL" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \ "$CONFIG_FB_VIRTUAL" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \
"$CONFIG_FB_Q40" = "m" -o "$CONFIG_FB_3DFX" = "m" -o \ "$CONFIG_FB_Q40" = "m" -o "$CONFIG_FB_3DFX" = "m" -o \
"$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
...@@ -331,8 +330,7 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -331,8 +330,7 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \ "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \
"$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_SIS" = "m" -o \ "$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
"$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \ "$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
"$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" -o \ "$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" ]; then
"$CONFIG_FB_NEOMAGIC" = "m" ]; then
define_tristate CONFIG_FBCON_CFB16 m define_tristate CONFIG_FBCON_CFB16 m
fi fi
fi fi
...@@ -354,29 +352,31 @@ if [ "$CONFIG_FB" = "y" ]; then ...@@ -354,29 +352,31 @@ if [ "$CONFIG_FB" = "y" ]; then
fi fi
fi fi
if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \ if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \
"$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \ "$CONFIG_FB_VOODOO1" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
"$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \ "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
"$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \ "$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \ "$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
"$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \ "$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \
"$CONFIG_FB_FM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \ "$CONFIG_FB_FM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \
"$CONFIG_FB_RADEON" = "y" -o "$CONFIG_FB_PVR2" = "y" -o \ "$CONFIG_FB_RADEON" = "y" -o "$CONFIG_FB_PVR2" = "y" -o \
"$CONFIG_FB_3DFX" = "y" -o "$CONFIG_FB_SIS" = "y" -o \ "$CONFIG_FB_3DFX" = "y" -o "$CONFIG_FB_SIS" = "y" ]; then
"$CONFIG_FB_VOODOO1" = "y" ]; then
define_tristate CONFIG_FBCON_CFB32 y define_tristate CONFIG_FBCON_CFB32 y
else else
if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \ if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
"$CONFIG_FB_VESA" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \ "$CONFIG_FB_VOODOO1" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
"$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \ "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
"$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \ "$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \ "$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
"$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \ "$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \
"$CONFIG_FB_3DFX" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \ "$CONFIG_FB_3DFX" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
"$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_SIS" = "m" -o \ "$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
"$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" ]; then "$CONFIG_FB_PVR2" = "m" ]; then
define_tristate CONFIG_FBCON_CFB32 m define_tristate CONFIG_FBCON_CFB32 m
fi fi
fi fi
if [ "$CONFIG_FB_VESA" = "y" ]; then
define_tristate CONFIG_FBCON_ACCEL y
fi
if [ "$CONFIG_FB_AMIGA" = "y" ]; then if [ "$CONFIG_FB_AMIGA" = "y" ]; then
define_tristate CONFIG_FBCON_AFB y define_tristate CONFIG_FBCON_AFB y
define_tristate CONFIG_FBCON_ILBM y define_tristate CONFIG_FBCON_ILBM y
......
...@@ -69,7 +69,7 @@ obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o ...@@ -69,7 +69,7 @@ obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o
obj-$(CONFIG_FB_CLGEN) += clgenfb.o obj-$(CONFIG_FB_CLGEN) += clgenfb.o
obj-$(CONFIG_FB_S3TRIO) += S3triofb.o obj-$(CONFIG_FB_S3TRIO) += S3triofb.o
obj-$(CONFIG_FB_TGA) += tgafb.o obj-$(CONFIG_FB_TGA) += tgafb.o
obj-$(CONFIG_FB_VESA) += vesafb.o obj-$(CONFIG_FB_VESA) += vesafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_VGA16) += vga16fb.o fbcon-vga-planes.o obj-$(CONFIG_FB_VGA16) += vga16fb.o fbcon-vga-planes.o
obj-$(CONFIG_FB_VIRGE) += virgefb.o obj-$(CONFIG_FB_VIRGE) += virgefb.o
obj-$(CONFIG_FB_G364) += g364fb.o obj-$(CONFIG_FB_G364) += g364fb.o
...@@ -138,6 +138,7 @@ obj-$(CONFIG_FBCON_MFB) += fbcon-mfb.o ...@@ -138,6 +138,7 @@ obj-$(CONFIG_FBCON_MFB) += fbcon-mfb.o
obj-$(CONFIG_FBCON_VGA) += fbcon-vga.o obj-$(CONFIG_FBCON_VGA) += fbcon-vga.o
obj-$(CONFIG_FBCON_HGA) += fbcon-hga.o obj-$(CONFIG_FBCON_HGA) += fbcon-hga.o
obj-$(CONFIG_FBCON_STI) += fbcon-sti.o obj-$(CONFIG_FBCON_STI) += fbcon-sti.o
obj-$(CONFIG_FBCON_ACCEL) += fbcon-accel.o
include $(TOPDIR)/Rules.make include $(TOPDIR)/Rules.make
......
/*
* Generic function for frame buffer with packed pixels of any depth.
*
* Copyright (C) June 1999 James Simmons
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*
* NOTES:
*
* This is for cfb packed pixels. Iplan and such are incorporated in the
* drivers that need them.
*
* FIXME
* The code for 24 bit is horrible. It copies byte by byte size instead of
* longs like the other sizes. Needs to be optimized.
*
* Also need to add code to deal with cards endians that are different than
* the native cpu endians. I also need to deal with MSB position in the word.
*
*/
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <linux/slab.h>
#include <asm/types.h>
#include <asm/io.h>
#include <video/fbcon.h>
void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
{
int x2, y2, lineincr, shift, shift_right, shift_left, old_dx, old_dy;
int n, j, linesize = p->fix.line_length, bpl = sizeof(unsigned long);
unsigned long start_index, end_index, start_mask, end_mask, last;
unsigned long *dst = NULL, *src = NULL;
char *src1, *dst1;
int tmp, height;
/* clip the destination */
old_dx = area->dx;
old_dy = area->dy;
/*
* We could use hardware clipping but on many cards you get around
* hardware clipping by writing to framebuffer directly.
*/
x2 = area->dx + area->width;
y2 = area->dy + area->height;
area->dx = area->dx > 0 ? area->dx : 0;
area->dy = area->dy > 0 ? area->dy : 0;
x2 = x2 < p->var.xres_virtual ? x2 : p->var.xres_virtual;
y2 = y2 < p->var.yres_virtual ? y2 : p->var.yres_virtual;
area->width = x2 - area->dx;
area->height = y2 - area->dy;
/* update sx1,sy1 */
area->sx += (area->dx - old_dx);
area->sy += (area->dy - old_dy);
height = area->height;
/* the source must be completely inside the virtual screen */
if (area->sx < 0 || area->sy < 0 ||
(area->sx + area->width) > p->var.xres_virtual ||
(area->sy + area->height) > p->var.yres_virtual)
return;
if (area->dy < area->sy
|| (area->dy == area->sy && area->dx < area->sx)) {
/* start at the top */
src1 = p->screen_base + area->sy * linesize +
((area->sx * p->var.bits_per_pixel) >> 3);
dst1 = p->screen_base + area->dy * linesize +
((area->dx * p->var.bits_per_pixel) >> 3);
lineincr = linesize;
} else {
/* start at the bottom */
src1 = p->screen_base + (area->sy + area->height-1) * linesize
+ (((area->sx + area->width - 1) * p->var.bits_per_pixel) >> 3);
dst1 = p->screen_base + (area->dy + area->height-1) * linesize
+ (((area->dx + area->width - 1) * p->var.bits_per_pixel) >> 3);
lineincr = -linesize;
}
if ((BITS_PER_LONG % p->var.bits_per_pixel) == 0) {
int ppw = BITS_PER_LONG / p->var.bits_per_pixel;
int n = ((area->width * p->var.bits_per_pixel) >> 3);
start_index = ((unsigned long) src1 & (bpl - 1));
end_index = ((unsigned long) (src1 + n) & (bpl - 1));
shift = ((unsigned long) dst1 & (bpl - 1)) -
((unsigned long) src1 & (bpl - 1));
start_mask = end_mask = 0;
if (start_index) {
start_mask = -1 >> (start_index << 3);
n -= (bpl - start_index);
}
if (end_index) {
end_mask = -1 << ((bpl - end_index) << 3);
n -= end_index;
}
n = n / bpl;
if (n <= 0) {
if (start_mask) {
if (end_mask)
end_mask &= start_mask;
else
end_mask = start_mask;
start_mask = 0;
}
n = 0;
}
if (shift) {
if (shift > 0) {
/* dest is over to right more */
shift_right =
shift * p->var.bits_per_pixel;
shift_left =
(ppw - shift) * p->var.bits_per_pixel;
} else {
/* source is to the right more */
shift_right =
(ppw + shift) * p->var.bits_per_pixel;
shift_left =
-shift * p->var.bits_per_pixel;
}
/* general case, positive increment */
if (lineincr > 0) {
if (shift < 0)
n++;
do {
dst = (unsigned long *) dst1;
src = (unsigned long *) src1;
last = (fb_readl(src) & start_mask);
if (shift > 0)
fb_writel(fb_readl(dst) | (last >> shift_right), dst);
for (j = 0; j < n; j++) {
dst++;
tmp = fb_readl(src);
src++;
fb_writel((last << shift_left) | (tmp >> shift_right), dst);
last = tmp;
src++;
}
fb_writel(fb_readl(dst) | (last << shift_left), dst);
src1 += lineincr;
dst1 += lineincr;
} while (--height);
} else {
/* general case, negative increment */
if (shift > 0)
n++;
do {
dst = (unsigned long *) dst1;
src = (unsigned long *) src1;
last = (fb_readl(src) & end_mask);
if (shift < 0)
fb_writel(fb_readl(dst) | (last >> shift_right), dst);
for (j = 0; j < n; j++) {
dst--;
tmp = fb_readl(src);
src--;
fb_writel((tmp << shift_left) | (last >> shift_right), dst);
last = tmp;
src--;
}
fb_writel(fb_readl(dst) | (last >> shift_right), dst);
src1 += lineincr;
dst1 += lineincr;
} while (--height);
}
} else {
/* no shift needed */
if (lineincr > 0) {
/* positive increment */
do {
dst = (unsigned long *) (dst1 - start_index);
src = (unsigned long *) (src1 - start_index);
if (start_mask)
fb_writel(fb_readl(src) | start_mask, dst);
for (j = 0; j < n; j++) {
fb_writel(fb_readl(src), dst);
dst++;
src++;
}
if (end_mask)
fb_writel(fb_readl(src) | end_mask, dst);
src1 += lineincr;
dst1 += lineincr;
} while (--height);
} else {
/* negative increment */
do {
dst = (unsigned long *) dst1;
src = (unsigned long *) src1;
if (start_mask)
fb_writel(fb_readl(src) | start_mask, dst);
for (j = 0; j < n; j++) {
fb_writel(fb_readl(src), dst);
dst--;
src--;
}
src1 += lineincr;
dst1 += lineincr;
} while (--height);
}
}
}
}
/*
* Generic fillrect for frame buffers with packed pixels of any depth.
*
* Copyright (C) 2000 James Simmons (jsimmons@linux-fbdev.org)
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*
* NOTES:
*
* The code for depths like 24 that don't have integer number of pixels per
* long is broken and needs to be fixed. For now I turned these types of
* mode off.
*
* Also need to add code to deal with cards endians that are different than
* the native cpu endians. I also need to deal with MSB position in the word.
*
*/
#include <linux/string.h>
#include <linux/fb.h>
#include <asm/types.h>
#include <video/fbcon.h>
void cfb_fillrect(struct fb_info *p, struct fb_fillrect *rect)
{
unsigned long start_index, end_index, start_mask = 0, end_mask = 0;
unsigned long height, ppw, fg, fgcolor;
int i, n, x2, y2, linesize = p->fix.line_length;
int bpl = sizeof(unsigned long);
unsigned long *dst;
char *dst1;
if (!rect->width || !rect->height)
return;
/* We could use hardware clipping but on many cards you get around
* hardware clipping by writing to framebuffer directly. */
x2 = rect->dx + rect->width;
y2 = rect->dy + rect->height;
x2 = x2 < p->var.xres_virtual ? x2 : p->var.xres_virtual;
y2 = y2 < p->var.yres_virtual ? y2 : p->var.yres_virtual;
rect->width = x2 - rect->dx;
height = y2 - rect->dy;
/* Size of the scanline in bytes */
n = (rect->width * (p->var.bits_per_pixel >> 3));
ppw = BITS_PER_LONG / p->var.bits_per_pixel;
dst1 = p->screen_base + (rect->dy * linesize) +
(rect->dx * (p->var.bits_per_pixel >> 3));
start_index = ((unsigned long) dst1 & (bpl - 1));
end_index = ((unsigned long) (dst1 + n) & (bpl - 1));
if (p->fix.visual == FB_VISUAL_TRUECOLOR)
fg = fgcolor = ((u32 *) (p->pseudo_palette))[rect->color];
else
fg = fgcolor = rect->color;
for (i = 0; i < ppw - 1; i++) {
fg <<= p->var.bits_per_pixel;
fg |= fgcolor;
}
if (start_index) {
start_mask = fg << (start_index << 3);
n -= (bpl - start_index);
}
if (end_index) {
end_mask = fg >> ((bpl - end_index) << 3);
n -= end_index;
}
n = n / bpl;
if (n <= 0) {
if (start_mask) {
if (end_mask)
end_mask &= start_mask;
else
end_mask = start_mask;
start_mask = 0;
}
n = 0;
}
if ((BITS_PER_LONG % p->var.bits_per_pixel) == 0) {
switch (rect->rop) {
case ROP_COPY:
do {
/* Word align to increases performace :-) */
dst = (unsigned long *) (dst1 - start_index);
if (start_mask) {
#if BITS_PER_LONG == 32
fb_writel(fb_readl(dst) |
start_mask, dst);
#else
fb_writeq(fb_readq(dst) |
start_mask, dst);
#endif
dst++;
}
for (i = 0; i < n; i++) {
#if BITS_PER_LONG == 32
fb_writel(fg, dst);
#else
fb_writeq(fg, dst);
#endif
dst++;
}
if (end_mask)
#if BITS_PER_LONG == 32
fb_writel(fb_readl(dst) | end_mask,
dst);
#else
fb_writeq(fb_readq(dst) | end_mask,
dst);
#endif
dst1 += linesize;
} while (--height);
break;
case ROP_XOR:
do {
dst = (unsigned long *) (dst1 - start_index);
if (start_mask) {
#if BITS_PER_LONG == 32
fb_writel(fb_readl(dst) ^
start_mask, dst);
#else
fb_writeq(fb_readq(dst) ^
start_mask, dst);
#endif
dst++;
}
for (i = 0; i < n; i++) {
#if BITS_PER_LONG == 32
fb_writel(fb_readl(dst) ^ fg, dst);
#else
fb_writeq(fb_readq(dst) ^ fg, dst);
#endif
dst++;
}
if (end_mask) {
#if BITS_PER_LONG == 32
fb_writel(fb_readl(dst) ^ end_mask,
dst);
#else
fb_writeq(fb_readq(dst) ^ end_mask,
dst);
#endif
}
dst1 += linesize;
} while (--height);
break;
}
} else {
/* Odd modes like 24 or 80 bits per pixel */
start_mask = fg >> (start_index * p->var.bits_per_pixel);
end_mask = fg << (end_index * p->var.bits_per_pixel);
/* start_mask =& PFILL24(x1,fg);
end_mask_or = end_mask & PFILL24(x1+width-1,fg); */
n = (rect->width - start_index - end_index) / ppw;
switch (rect->rop) {
case ROP_COPY:
do {
dst = (unsigned long *) dst1;
if (start_mask)
*dst |= start_mask;
if ((start_index + rect->width) > ppw)
dst++;
/* XXX: slow */
for (i = 0; i < n; i++) {
*dst++ = fg;
}
if (end_mask)
*dst |= end_mask;
dst1 += linesize;
} while (--height);
break;
case ROP_XOR:
do {
dst = (unsigned long *) dst1;
if (start_mask)
*dst ^= start_mask;
if ((start_mask + rect->width) > ppw)
dst++;
for (i = 0; i < n; i++) {
*dst++ ^= fg; /* PFILL24(fg,x1+i); */
}
if (end_mask)
*dst ^= end_mask;
dst1 += linesize;
} while (--height);
break;
}
}
return;
}
/*
* Generic BitBLT function for frame buffer with packed pixels of any depth.
*
* Copyright (C) June 1999 James Simmons
*
* This file is subject to the terms and conditions of the GNU General Public
* License. See the file COPYING in the main directory of this archive for
* more details.
*
* NOTES:
*
* This function copys a image from system memory to video memory. The
* image can be a bitmap where each 0 represents the background color and
* each 1 represents the foreground color. Great for font handling. It can
* also be a color image. This is determined by image_depth. The color image
* must be laid out exactly in the same format as the framebuffer. Yes I know
* their are cards with hardware that coverts images of various depths to the
* framebuffer depth. But not every card has this. All images must be rounded
* up to the nearest byte. For example a bitmap 12 bits wide must be two
* bytes width.
*
* FIXME
* The code for 24 bit is horrible. It copies byte by byte size instead of
* longs like the other sizes. Needs to be optimized.
*
* Also need to add code to deal with cards endians that are different than
* the native cpu endians. I also need to deal with MSB position in the word.
*
*/
#include <linux/string.h>
#include <linux/fb.h>
#include <asm/types.h>
#include <video/fbcon.h>
#define DEBUG
#ifdef DEBUG
#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt,__FUNCTION__,## args)
#else
#define DPRINTK(fmt, args...)
#endif
void cfb_imageblit(struct fb_info *p, struct fb_image *image)
{
int pad, ppw, shift, shift_right, shift_left, x2, y2, n, i, j, k, l = 7;
unsigned long tmp = ~0 << (BITS_PER_LONG - p->var.bits_per_pixel);
unsigned long fgx, bgx, fgcolor, bgcolor, eorx;
unsigned long end_index, end_mask, mask;
unsigned long *dst = NULL;
u8 *dst1, *src;
/*
* We could use hardware clipping but on many cards you get around hardware
* clipping by writing to framebuffer directly like we are doing here.
*/
x2 = image->dx + image->width;
y2 = image->dy + image->height;
image->dx = image->dx > 0 ? image->dx : 0;
image->dy = image->dy > 0 ? image->dy : 0;
x2 = x2 < p->var.xres_virtual ? x2 : p->var.xres_virtual;
y2 = y2 < p->var.yres_virtual ? y2 : p->var.yres_virtual;
image->width = x2 - image->dx;
image->height = y2 - image->dy;
dst1 = p->screen_base + image->dy * p->fix.line_length +
((image->dx * p->var.bits_per_pixel) >> 3);
ppw = BITS_PER_LONG/p->var.bits_per_pixel;
src = image->data;
if (p->fix.visual == FB_VISUAL_TRUECOLOR) {
fgx = fgcolor = ((u32 *)(p->pseudo_palette))[image->fg_color];
bgx = bgcolor = ((u32 *)(p->pseudo_palette))[image->bg_color];
} else {
fgx = fgcolor = image->fg_color;
bgx = bgcolor = image->bg_color;
}
for (i = 0; i < ppw-1; i++) {
fgx <<= p->var.bits_per_pixel;
bgx <<= p->var.bits_per_pixel;
fgx |= fgcolor;
bgx |= bgcolor;
}
eorx = fgx ^ bgx;
n = ((image->width + 7) >> 3);
pad = (n << 3) - image->width;
for (i = 0; i < image->height; i++) {
dst = (unsigned long *) dst1;
for (j = image->width/ppw; j > 0; j--) {
mask = 0;
for (k = ppw; k > 0; k--) {
if (test_bit(l, src))
mask |= (tmp >> (p->var.bits_per_pixel*(k-1)));
l--;
if (l < 0) { l = 7; src++; }
}
fb_writel((mask & eorx)^bgx, dst);
dst++;
}
l =- pad;
dst1 += p->fix.line_length;
}
}
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment