Commit 4118216f authored by James Simmons's avatar James Simmons

Merge

parents c43626f4 d645f0e0
Tridentfb is a framebuffer driver for some Trident chip based cards.
The following list of chips is thought to be supported although not all are
tested:
those from the Image series with Cyber in their names - accelerated
those with Blade in their names (Blade3D,CyberBlade...) - accelerated
the newer CyberBladeXP family - nonaccelerated
Only PCI/AGP based cards are supported, none of the older Tridents.
How to use it?
==============
Just do your usual console work :)
When booting you can pass the following parameters
==================================================
noaccel - turns off acceleration (when it doesn't work for your card)
accel - force text acceleration (for boards which by default are noacceled)
fp - use flat panel related stuff
crt - assume monitor is present instead of fp
center - for flat panels and resolutions smaller than native size center the
image, otherwise use
stretch
memsize - integer value in Kb, use if your card's memory size is misdetected.
look at the driver output to see what it says when initializing.
memdiff - integer value in Kb,should be nonzero if your card reports
more memory than it actually has.For instance mine is 192K less than
detection says in all three BIOS selectable situations 2M, 4M, 8M.
Only use if your video memory is taken from main memory hence of
configurable size.Otherwise use memsize.
If in some modes which barely fit the memory you see garbage at the bottom
this might help by not letting change to that mode anymore.
nativex - the width in pixels of the flat panel.If you know it (usually 1024
800 or 1280) and it is not what the driver seems to detect use it.
bpp - bits per pixel (8,16 or 32)
mode - a mode name like 800x600 (as described in Documentation/fb/modedb.txt)
Using insane values for the above parameters will probably result in driver
misbehaviour so take care(for instance memsize=12345678 or memdiff=23784 or
nativex=93)
Contact: jani@astechnix.ro
......@@ -10,9 +10,6 @@ bool 'Support for frame buffer devices (EXPERIMENTAL)' CONFIG_FB
if [ "$CONFIG_FB" = "y" ]; then
define_bool CONFIG_DUMMY_CONSOLE y
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
if [ "$CONFIG_PCI" = "y" ]; then
tristate ' nVidia Riva support (EXPERIMENTAL)' CONFIG_FB_RIVA
fi
if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_PCI" = "y" ]; then
tristate ' Cirrus Logic support (EXPERIMENTAL)' CONFIG_FB_CLGEN
tristate ' Permedia2 support (EXPERIMENTAL)' CONFIG_FB_PM2
......@@ -127,6 +124,7 @@ if [ "$CONFIG_FB" = "y" ]; then
fi
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
if [ "$CONFIG_PCI" != "n" ]; then
tristate ' nVidia Riva support (EXPERIMENTAL)' CONFIG_FB_RIVA
tristate ' Matrox acceleration (EXPERIMENTAL)' CONFIG_FB_MATROX
if [ "$CONFIG_FB_MATROX" != "n" ]; then
bool ' Millennium I/II support' CONFIG_FB_MATROX_MILLENIUM
......@@ -156,6 +154,8 @@ if [ "$CONFIG_FB" = "y" ]; then
tristate ' NeoMagic display support (EXPERIMENTAL)' CONFIG_FB_NEOMAGIC
tristate ' 3Dfx Banshee/Voodoo3 display support (EXPERIMENTAL)' CONFIG_FB_3DFX
tristate ' 3Dfx Voodoo Graphics (sst1) support (EXPERIMENTAL)' CONFIG_FB_VOODOO1
tristate ' Trident support (EXPERIMENTAL)' CONFIG_FB_TRIDENT
tristate ' Permedia3 support (EXPERIMENTAL)' CONFIG_FB_PM3
fi
fi
if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then
......@@ -220,6 +220,7 @@ if [ "$CONFIG_FB" = "y" ]; then
tristate ' 16 bpp packed pixels support' CONFIG_FBCON_CFB16
tristate ' 24 bpp packed pixels support' CONFIG_FBCON_CFB24
tristate ' 32 bpp packed pixels support' CONFIG_FBCON_CFB32
tristate ' Hardware acceleration support' CONFIG_FBCON_ACCEL
tristate ' Amiga bitplanes support' CONFIG_FBCON_AFB
tristate ' Amiga interleaved bitplanes support' CONFIG_FBCON_ILBM
tristate ' Atari interleaved bitplanes (2 planes) support' CONFIG_FBCON_IPLAN2P2
......@@ -265,10 +266,10 @@ if [ "$CONFIG_FB" = "y" ]; then
if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_ATARI" = "y" -o \
"$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_MAC" = "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_PM3" = "y" -o \
"$CONFIG_FB_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "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_TRIDENT" = "y" -o \
"$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \
"$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
......@@ -279,16 +280,16 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_SA1100" = "y" -o "$CONFIG_FB_3DFX" = "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_SIS" = "y" -o "$CONFIG_FB_NEOMAGIC" = "y" ]; then
"$CONFIG_FB_SIS" = "y" ]; then
define_tristate CONFIG_FBCON_CFB8 y
else
if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
"$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_MAC" = "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_PM3" = "m" -o \
"$CONFIG_FB_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "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_TRIDENT" = "m" -o \
"$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
"$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
......@@ -299,14 +300,14 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_PMAG_BA" = "m" -o "$CONFIG_FB_PMAGB_B" = "m" -o \
"$CONFIG_FB_MAXINE" = "m" -o "$CONFIG_FB_RADEON" = "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
fi
fi
if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \
"$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_VESA" = "y" -o \
"$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \
"$CONFIG_FB_Q40" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \
"$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_NEOMAGIC" = "y" -o \
"$CONFIG_FB_TRIDENT" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \
"$CONFIG_FB_VOODOO1" = "y" -o "$CONFIG_FB_RADEON" = "y" -o \
"$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
"$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \
"$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
......@@ -315,14 +316,13 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \
"$CONFIG_FB_CYBER2000" = "y" -o "$CONFIG_FB_3DFX" = "y" -o \
"$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SA1100" = "y" -o \
"$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_VOODOO1" = "y" -o \
"$CONFIG_FB_NEOMAGIC" = "y" ]; then
"$CONFIG_FB_PVR2" = "y" -o "$CONFIG_FB_PM3" = "y" ]; then
define_tristate CONFIG_FBCON_CFB16 y
else
if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
"$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VESA" = "m" -o \
"$CONFIG_FB_VIRTUAL" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \
"$CONFIG_FB_Q40" = "m" -o "$CONFIG_FB_3DFX" = "m" -o \
"$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_NEOMAGIC" = "m" -o \
"$CONFIG_FB_TRIDENT" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \
"$CONFIG_FB_VOODOO1" = "m" -o "$CONFIG_FB_3DFX" = "m" -o \
"$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
"$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
"$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
......@@ -331,8 +331,7 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \
"$CONFIG_FB_CYBER2000" = "m" -o "$CONFIG_FB_SIS" = "m" -o \
"$CONFIG_FB_SA1100" = "m" -o "$CONFIG_FB_RADEON" = "m" -o \
"$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_VOODOO1" = "m" -o \
"$CONFIG_FB_NEOMAGIC" = "m" ]; then
"$CONFIG_FB_PVR2" = "m" -o "$CONFIG_FB_PM3" = "m" ]; then
define_tristate CONFIG_FBCON_CFB16 m
fi
fi
......@@ -354,29 +353,39 @@ if [ "$CONFIG_FB" = "y" ]; then
fi
fi
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_TRIDENT" = "y" -o \
"$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" -o \
"$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_MATROX" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
"$CONFIG_FB_RIVA" = "y" -o "$CONFIG_FB_ATY128" = "y" -o \
"$CONFIG_FB_FM2" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \
"$CONFIG_FB_SIS" = "y" -o "$CONFIG_FB_SGIVW" = "y" -o \
"$CONFIG_FB_RADEON" = "y" -o "$CONFIG_FB_PVR2" = "y" -o \
"$CONFIG_FB_3DFX" = "y" -o "$CONFIG_FB_SIS" = "y" -o \
"$CONFIG_FB_VOODOO1" = "y" ]; then
"$CONFIG_FB_3DFX" = "y" -o "$CONFIG_FB_PM3" = "y" ]; then
define_tristate CONFIG_FBCON_CFB32 y
else
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_TRIDENT" = "m" -o \
"$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" -o \
"$CONFIG_FB_TGA" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_MATROX" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
"$CONFIG_FB_RIVA" = "m" -o "$CONFIG_FB_ATY128" = "m" -o \
"$CONFIG_FB_3DFX" = "m" -o "$CONFIG_FB_RADEON" = "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" -o "$CONFIG_FB_PM3" = "y" ]; then
define_tristate CONFIG_FBCON_CFB32 m
fi
fi
if [ "$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_Q40" = "y" -o \
"$CONFIG_FB_FM2" = "y" -o "$CONFIG_FB_HIT" = "y" -o \
"$CONFIG_FB_ANAKIN" = "y" -o "$CONFIG_FB_G364" = "y" -o \
"$CONFIG_FB_VIRTUAL" = "y" ]; then
define_tristate CONFIG_FBCON_ACCEL y
else
if [ "$CONFIG_FB_HIT" = "m" -o "$CONFIG_FB_G364" = "m" -o \
"$CONFIG_FB_VIRTUAL" = "m" ]; then
define_tristate CONFIG_FBCON_ACCEL m
fi
fi
if [ "$CONFIG_FB_AMIGA" = "y" ]; then
define_tristate CONFIG_FBCON_AFB y
define_tristate CONFIG_FBCON_ILBM y
......@@ -399,10 +408,10 @@ if [ "$CONFIG_FB" = "y" ]; then
# define_tristate CONFIG_FBCON_IPLAN2P16 m
fi
fi
if [ "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" ]; then
if [ "$CONFIG_FB_MAC" = "y" ]; then
define_tristate CONFIG_FBCON_MAC y
else
if [ "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
if [ "$CONFIG_FB_MAC" = "m" ]; then
define_tristate CONFIG_FBCON_MAC m
fi
fi
......
......@@ -44,8 +44,9 @@ endif
obj-$(CONFIG_FB_ACORN) += acornfb.o
obj-$(CONFIG_FB_AMIGA) += amifb.o
obj-$(CONFIG_FB_PM2) += pm2fb.o
obj-$(CONFIG_FB_PM3) += pm3fb.o
obj-$(CONFIG_FB_APOLLO) += dnfb.o
obj-$(CONFIG_FB_Q40) += q40fb.o
obj-$(CONFIG_FB_Q40) += q40fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_ATARI) += atafb.o
obj-$(CONFIG_FB_ATY128) += aty128fb.o
obj-$(CONFIG_FB_RADEON) += radeonfb.o
......@@ -67,13 +68,14 @@ obj-$(CONFIG_FB_OF) += offb.o
obj-$(CONFIG_FB_IMSTT) += imsttfb.o
obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o
obj-$(CONFIG_FB_CLGEN) += clgenfb.o
obj-$(CONFIG_FB_TRIDENT) += tridentfb.o
obj-$(CONFIG_FB_S3TRIO) += S3triofb.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_VIRGE) += virgefb.o
obj-$(CONFIG_FB_G364) += g364fb.o
obj-$(CONFIG_FB_FM2) += fm2fb.o
obj-$(CONFIG_FB_FM2) += fm2fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_CREATOR) += creatorfb.o sbusfb.o
obj-$(CONFIG_FB_CGSIX) += cgsixfb.o sbusfb.o
obj-$(CONFIG_FB_BWTWO) += bwtwofb.o sbusfb.o
......@@ -98,7 +100,7 @@ obj-$(CONFIG_FB_BWTWO) += bwtwofb.o
obj-$(CONFIG_FB_HGA) += hgafb.o
obj-$(CONFIG_FB_SA1100) += sa1100fb.o
obj-$(CONFIG_FB_VIRTUAL) += vfb.o
obj-$(CONFIG_FB_HIT) += hitfb.o
obj-$(CONFIG_FB_HIT) += hitfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_E1355) += epson1355fb.o
obj-$(CONFIG_FB_PVR2) += pvr2fb.o
obj-$(CONFIG_FB_VOODOO1) += sstfb.o
......@@ -122,6 +124,7 @@ obj-$(CONFIG_FBCON_MFB) += fbcon-mfb.o
obj-$(CONFIG_FBCON_VGA) += fbcon-vga.o
obj-$(CONFIG_FBCON_HGA) += fbcon-hga.o
obj-$(CONFIG_FBCON_STI) += fbcon-sti.o
obj-$(CONFIG_FBCON_ACCEL) += fbcon-accel.o
include $(TOPDIR)/Rules.make
......
......@@ -23,23 +23,34 @@
#include <video/fbcon.h>
#include <video/fbcon-cfb16.h>
static u16 colreg[16];
static u32 colreg[16];
static struct fb_info fb_info;
static struct display display;
static int
anakinfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
u_int *transp, struct fb_info *info)
{
if (regno > 15)
return 1;
static struct fb_var_screeninfo anakinfb_var = {
xres: 400,
yres: 234,
xres_virtual: 400,
yres_virtual: 234,
bits_per_pixel: 16,
red: { 11, 5, 0 },
green: { 5, 6, 0 },
blue: { 0, 5, 0 },
activate: FB_ACTIVATE_NOW,
height: -1,
width: -1,
vmode: FB_VMODE_NONINTERLACED,
};
*red = colreg[regno] & 0xf800;
*green = colreg[regno] & 0x7e0 << 5;
*blue = colreg[regno] & 0x1f << 11;
*transp = 0;
return 0;
}
static struct fb_fix_screeninfo anakinfb_fix = {
id: "AnakinFB",
smem_start: VGA_START,
smem_len: VGA_SIZE,
type: FB_TYPE_PACKED_PIXELS,
visual: FB_VISUAL_TRUECOLOR,
line_length: 400*2,
accel: FB_ACCEL_NONE,
};
static int
anakinfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
......@@ -53,153 +64,48 @@ anakinfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
return 0;
}
static int
anakinfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
{
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id, "AnakinFB");
fix->smem_start = VGA_START;
fix->smem_len = VGA_SIZE;
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
fix->visual = FB_VISUAL_TRUECOLOR;
fix->xpanstep = 0;
fix->ypanstep = 0;
fix->ywrapstep = 0;
fix->line_length = 400 * 2;
fix->accel = FB_ACCEL_NONE;
return 0;
}
static int
anakinfb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
{
memset(var, 0, sizeof(struct fb_var_screeninfo));
var->xres = 400;
var->yres = 234;
var->xres_virtual = 400;
var->yres_virtual = 234;
var->xoffset = 0;
var->yoffset = 0;
var->bits_per_pixel = 16;
var->grayscale = 0;
var->red.offset = 11;
var->red.length = 5;
var->green.offset = 5;
var->green.length = 6;
var->blue.offset = 0;
var->blue.length = 5;
var->transp.offset = 0;
var->transp.length = 0;
var->nonstd = 0;
var->activate = FB_ACTIVATE_NOW;
var->height = -1;
var->width = -1;
var->pixclock = 0;
var->left_margin = 0;
var->right_margin = 0;
var->upper_margin = 0;
var->lower_margin = 0;
var->hsync_len = 0;
var->vsync_len = 0;
var->sync = 0;
var->vmode = FB_VMODE_NONINTERLACED;
return 0;
}
static int
anakinfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
{
return -EINVAL;
}
static int
anakinfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info)
{
if (con == info->currcon)
return fb_get_cmap(cmap, kspc, anakinfb_getcolreg, info);
else if (fb_display[con].cmap.len)
fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
else
fb_copy_cmap(fb_default_cmap(16), cmap, kspc ? 0 : 2);
return 0;
}
static int
anakinfb_switch_con(int con, struct fb_info *info)
{
info->currcon = con;
return 0;
}
static int
anakinfb_updatevar(int con, struct fb_info *info)
{
return 0;
}
static void
anakinfb_blank(int blank, struct fb_info *info)
{
/*
* TODO: use I2C to blank/unblank the screen
*/
}
static struct fb_ops anakinfb_ops = {
owner: THIS_MODULE,
fb_get_fix: anakinfb_get_fix,
fb_get_var: anakinfb_get_var,
fb_set_var: anakinfb_set_var,
fb_get_cmap: anakinfb_get_cmap,
fb_get_fix: gen_get_fix,
fb_get_var: gen_get_var,
fb_set_var: gen_set_var,
fb_get_cmap: gen_get_cmap,
fb_set_cmap: gen_set_cmap,
fb_setcolreg: anakinfb_setcolreg,
fb_blank: anakinfb_blank,
fb_fillrect: cfb_fillrect,
fb_copyarea: cfb_copyarea,
fb_imageblit: cfb_imageblit,
};
int __init
anakinfb_init(void)
{
memset(&fb_info, 0, sizeof(struct fb_info));
strcpy(fb_info.modename, "AnakinFB");
fb_info.node = NODEV;
memset(&display, 0, sizeof(struct display));
strcpy(fb_info.modename, anakinfb_fix.id);
fb_info.node = fb_info.currcon = -1;
fb_info.flags = FBINFO_FLAG_DEFAULT;
fb_info.fbops = &anakinfb_ops;
fb_info.currcon = -1;
fb_info.var = anakinfb_var;
fb_info.fix = anakinfb_fix;
fb_info.disp = &display;
strcpy(fb_info.fontname, "VGA8x16");
fb_info.changevar = NULL;
fb_info.switch_con = &anakinfb_switch_con;
fb_info.updatevar = &anakinfb_updatevar;
memset(&display, 0, sizeof(struct display));
anakinfb_get_var(&display.var, 0, &fb_info);
fb_info.switch_con = gen_switch_con;
fb_info.updatevar = gen_update_var;
if (!(request_mem_region(VGA_START, VGA_SIZE, "vga")))
return -ENOMEM;
if (!(fb_info.screen_base = ioremap(VGA_START, VGA_SIZE))) {
if (fb_info.screen_base = ioremap(VGA_START, VGA_SIZE)) {
release_mem_region(VGA_START, VGA_SIZE);
return -EIO;
}
display.visual = FB_VISUAL_TRUECOLOR;
display.type = FB_TYPE_PACKED_PIXELS;
display.type_aux = 0;
display.ypanstep = 0;
display.ywrapstep = 0;
display.line_length = 400 * 2;
display.can_soft_blank = 1;
display.inverse = 0;
#ifdef FBCON_HAS_CFB16
display.dispsw = &fbcon_cfb16;
display.dispsw_data = colreg;
#else
display.dispsw = &fbcon_dummy;
#endif
fb_alloc_cmap(&fb_info.cmap, 16, 0);
gen_set_disp(-1, &fb_info);
if (register_framebuffer(&fb_info) < 0) {
iounmap(fb_info.screen_base);
iounmap(display.screen_base);
release_mem_region(VGA_START, VGA_SIZE);
return -EINVAL;
}
......
/*
* 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 (image->depth == 1) {
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;
}
}
}
......@@ -74,10 +74,10 @@ struct fb_info_chips {
#define write_ind(num, val, ap, dp) do { \
outb((num), (ap)); outb((val), (dp)); \
} while (0);
} while (0)
#define read_ind(num, var, ap, dp) do { \
outb((num), (ap)); var = inb((dp)); \
} while (0);
} while (0)
/* extension registers */
#define write_xr(num, val) write_ind(num, val, 0x3d6, 0x3d7)
......
......@@ -1729,9 +1729,8 @@ static int cyberpro_pci_resume(struct pci_dev *dev)
}
static struct pci_device_id cyberpro_pci_table[] __devinitdata = {
// Not yet
// { PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682,
// PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_IGA_1682 },
{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_1682,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_IGA_1682 },
{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, ID_CYBERPRO_2000 },
{ PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010,
......
......@@ -152,7 +152,7 @@ void fb_copy_cmap(struct fb_cmap *from, struct fb_cmap *to, int fsfromto)
size = to->len-tooff;
if (size > from->len-fromoff)
size = from->len-fromoff;
if (size < 0)
if (size <= 0)
return;
size *= sizeof(u16);
......
......@@ -61,6 +61,8 @@ extern int cyberfb_init(void);
extern int cyberfb_setup(char*);
extern int pm2fb_init(void);
extern int pm2fb_setup(char*);
extern int pm3fb_init(void);
extern int pm3fb_setup(char*);
extern int clps711xfb_init(void);
extern int cyber2000fb_init(void);
extern int cyber2000fb_setup(char*);
......@@ -120,10 +122,16 @@ extern int rivafb_init(void);
extern int rivafb_setup(char*);
extern int tdfxfb_init(void);
extern int tdfxfb_setup(char*);
extern int tridentfb_init(void);
extern int tridentfb_setup(char*);
extern int sisfb_init(void);
extern int sisfb_setup(char*);
extern int stifb_init(void);
extern int stifb_setup(char*);
extern int pmagbafb_init(void);
extern int pmagbbfb_init(void);
extern void maxinefb_init(void);
extern int tx3912fb_init(void);
extern int radeonfb_init(void);
extern int radeonfb_setup(char*);
extern int e1355fb_init(void);
......@@ -172,6 +180,9 @@ static struct {
#ifdef CONFIG_FB_PM2
{ "pm2fb", pm2fb_init, pm2fb_setup },
#endif
#ifdef CONFIG_FB_PM3
{ "pm3fb", pm3fb_init, pm3fb_setup },
#endif
#ifdef CONFIG_FB_CLGEN
{ "clgen", clgenfb_init, clgenfb_setup },
#endif
......@@ -220,6 +231,9 @@ static struct {
#ifdef CONFIG_FB_SIS
{ "sisfb", sisfb_init, sisfb_setup },
#endif
#ifdef CONFIG_FB_TRIDENT
{ "trident", tridentfb_init, tridentfb_setup },
#endif
/*
* Generic drivers that are used as fallbacks
......@@ -285,12 +299,24 @@ static struct {
#ifdef CONFIG_FB_HIT
{ "hitfb", hitfb_init, NULL },
#endif
#ifdef CONFIG_FB_TX3912
{ "tx3912", tx3912fb_init, NULL },
#endif
#ifdef CONFIG_FB_E1355
{ "e1355fb", e1355fb_init, e1355fb_setup },
#endif
#ifdef CONFIG_FB_PVR2
{ "pvr2", pvr2fb_init, pvr2fb_setup },
#endif
#ifdef CONFIG_FB_PMAG_BA
{ "pmagbafb", pmagbafb_init, NULL },
#endif
#ifdef CONFIG_FB_PMAGB_B
{ "pmagbbfb", pmagbbfb_init, NULL },
#endif
#ifdef CONFIG_FB_MAXINE
{ "maxinefb", maxinefb_init, NULL },
#endif
#ifdef CONFIG_FB_VOODOO1
{ "sst", sstfb_init, sstfb_setup },
#endif
......
This diff is collapsed.
This diff is collapsed.
......@@ -386,44 +386,6 @@ static int __init hga_card_detect(void)
*
* ------------------------------------------------------------------------- */
/**
* hga_get_fix - get the fixed part of the display
* @fix:struct fb_fix_screeninfo to fill in
* @con:unused
* @info:pointer to fb_info object containing info for current hga board
*
* This wrapper function copies @info->fix to @fix.
* A zero is returned on success and %-EINVAL for failure.
*/
int hga_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
{
CHKINFO(-EINVAL);
DPRINTK("hga_get_fix: con:%d, info:%x, fb_info:%x\n", con, (unsigned)info, (unsigned)&fb_info);
*fix = info->fix;
return 0;
}
/**
* hga_get_var - get the user defined part of the display
* @var:struct fb_var_screeninfo to fill in
* @con:unused
* @info:pointer to fb_info object containing info for current hga board
*
* This wrapper function copies @info->var to @var.
* A zero is returned on success and %-EINVAL for failure.
*/
int hga_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
{
CHKINFO(-EINVAL);
DPRINTK("hga_get_var: con:%d, info:%x, fb_info:%x\n", con, (unsigned)info, (unsigned)&fb_info);
*var = info->var;
return 0;
}
/**
* hga_set_var - set the user defined part of the display
* @var:new video mode
......@@ -596,8 +558,8 @@ static int hgafb_blank(int blank_mode, struct fb_info *info)
static struct fb_ops hgafb_ops = {
owner: THIS_MODULE,
fb_get_fix: hga_get_fix,
fb_get_var: hga_get_var,
fb_get_fix: gen_get_fix,
fb_get_var: gen_get_var,
fb_set_var: hga_set_var,
fb_get_cmap: hga_get_cmap,
fb_set_cmap: gen_set_cmap,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
/*
* linux/drivers/video/q40fb.c -- Q40 frame buffer device
*
* Copyright (C) 2001
*
* Richard Zidlicky <Richard.Zidlicky@stud.informatik.uni-erlangen.de>
*
* 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.
*/
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
......@@ -9,181 +21,68 @@
#include <asm/uaccess.h>
#include <asm/setup.h>
#include <asm/segment.h>
#include <asm/system.h>
/*#include <asm/irq.h>*/
#include <asm/q40_master.h>
#include <linux/fb.h>
#include <linux/module.h>
#include <asm/pgtable.h>
#include <video/fbcon.h>
#include <video/fbcon-cfb16.h>
#define FBIOSETSCROLLMODE 0x4611
#define Q40_PHYS_SCREEN_ADDR 0xFE800000
static u16 fbcon_cmap_cfb16[16];
static u32 pseudo_palette[17];
static struct fb_info fb_info;
static struct display display;
static struct fb_fix_screeninfo q40fb_fix __initdata = {
id: "Q40",
smem_len: 1024*1024,
type: FB_TYPE_PACKED_PIXELS,
visual: FB_VISUAL_TRUECOLOR,
line_length: 1024*2,
accel_flags: FB_ACCEL_NONE,
};
static struct fb_var_screeninfo q40fb_var __initdata = {
xres: 1024,
yres: 512,
xres_virtual: 1024,
yres_virtual: 512,
bits_per_pixel: 16,
red: {6, 5, 0},
green: {11, 5, 0},
blue: {0, 6, 0},
activate: FB_ACTIVATE_NOW,
height: 230,
width: 300,
vmode: FB_VMODE_NONINTERLACED,
};
/* frame buffer operations */
int q40fb_init(void);
static int q40fb_get_fix(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info);
static int q40fb_get_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info);
static int q40fb_set_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info);
static int q40fb_get_cmap(struct fb_cmap *cmap,int kspc,int con,
struct fb_info *info);
static int q40fb_set_cmap(struct fb_cmap *cmap,int kspc,int con,
struct fb_info *info);
static int q40fb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp,
const struct fb_info *info);
static int q40con_switch(int con, struct fb_info *info);
static int q40con_updatevar(int con, struct fb_info *info);
static void q40fb_set_disp(int con, struct fb_info *info);
struct fb_info *info);
static struct display disp[MAX_NR_CONSOLES];
static struct fb_info fb_info;
static struct fb_ops q40fb_ops = {
owner: THIS_MODULE,
fb_get_fix: q40fb_get_fix,
fb_get_var: q40fb_get_var,
fb_set_var: q40fb_set_var,
fb_get_cmap: q40fb_get_cmap,
fb_set_cmap: q40fb_set_cmap,
fb_get_fix: gen_get_fix,
fb_get_var: gen_get_var,
fb_set_var: gen_set_var,
fb_get_cmap: gen_get_cmap,
fb_set_cmap: gen_set_cmap,
fb_setcolreg: q40fb_setcolreg,
fb_fillrect: cfb_fillrect,
fb_copyarea: cfb_copyarea,
fb_imageblit: cfb_imageblit,
};
static char q40fb_name[]="Q40";
static int q40fb_get_fix(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info)
{
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id,"Q40");
fix->smem_start = info->screen_base;
fix->smem_len=1024*1024;
fix->type=FB_TYPE_PACKED_PIXELS;
fix->type_aux=0;
fix->visual=FB_VISUAL_TRUECOLOR; /* good approximation so far ..*/;
fix->xpanstep=0;
fix->ypanstep=0;
fix->ywrapstep=0;
fix->line_length=1024*2;
/* no mmio,accel ...*/
return 0;
}
static int q40fb_get_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
memset(var, 0, sizeof(struct fb_var_screeninfo));
var->xres=1024;
var->yres=512;
var->xres_virtual=1024;
var->yres_virtual=512;
var->xoffset=0;
var->yoffset=0;
var->bits_per_pixel=16;
var->grayscale=0;
var->nonstd=0;
var->activate=FB_ACTIVATE_NOW;
var->height=230; /* approx for my 17" monitor, more important */
var->width=300; /* than the absolute values is the unusual aspect ratio*/
var->red.offset=6; /*6*/
var->red.length=5;
var->green.offset=11; /*11*/
var->green.length=5;
var->blue.offset=0;
var->blue.length=6;
var->transp.length=0;
var->pixclock=0;
var->left_margin=0;
var->right_margin=0;
var->hsync_len=0;
var->vsync_len=0;
var->sync=0;
var->vmode=FB_VMODE_NONINTERLACED;
return 0;
}
static int q40fb_set_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
if(var->xres!=1024)
return -EINVAL;
if(var->yres!=512)
return -EINVAL;
if(var->xres_virtual!=1024)
return -EINVAL;
if(var->yres_virtual!=512)
return -EINVAL;
if(var->xoffset!=0)
return -EINVAL;
if(var->yoffset!=0)
return -EINVAL;
if(var->bits_per_pixel!=16)
return -EINVAL;
if(var->grayscale!=0)
return -EINVAL;
if(var->nonstd!=0)
return -EINVAL;
if(var->activate!=FB_ACTIVATE_NOW)
return -EINVAL;
if(var->pixclock!=0)
return -EINVAL;
if(var->left_margin!=0)
return -EINVAL;
if(var->right_margin!=0)
return -EINVAL;
if(var->hsync_len!=0)
return -EINVAL;
if(var->vsync_len!=0)
return -EINVAL;
if(var->sync!=0)
return -EINVAL;
if(var->vmode!=FB_VMODE_NONINTERLACED)
return -EINVAL;
return 0;
}
static int q40_getcolreg(unsigned regno, unsigned *red, unsigned *green,
unsigned *blue, unsigned *transp,
struct fb_info *info)
{
/*
* Read a single color register and split it into colors/transparent.
* The return values must have a 16 bit magnitude.
* Return != 0 for invalid regno.
*/
if (regno>=16) return 1;
*transp=0;
*green = ((fbcon_cmap_cfb16[regno]>>11) & 31)<<11;
*red = ((fbcon_cmap_cfb16[regno]>>6) & 31)<<11;
*blue = ((fbcon_cmap_cfb16[regno]) & 63)<<10;
return 0;
}
static int q40fb_setcolreg(unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp,
const struct fb_info *info)
struct fb_info *info)
{
/*
* Set a single color register. The values supplied have a 16 bit
......@@ -196,119 +95,43 @@ static int q40fb_setcolreg(unsigned regno, unsigned red, unsigned green,
blue>>=10;
if (regno < 16) {
fbcon_cmap_cfb16[regno] = ((red & 31) <<6) |
info->pseudo_palette[regno] = ((red & 31) <<6) |
((green & 31) << 11) |
(blue & 63);
}
return 0;
}
static int q40fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info)
{
#if 1
if (con == info->currcon) /* current console? */
return fb_get_cmap(cmap, kspc, q40_getcolreg, info);
else if (fb_display[con].cmap.len) /* non default colormap? */
fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
else
fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
cmap, kspc ? 0 : 2);
return 0;
#else
printk(KERN_ERR "get cmap not supported\n");
return -EINVAL;
#endif
}
static int q40fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info)
int q40fb_init(void)
{
#if 1
int err;
if (!fb_display[con].cmap.len) { /* no colormap allocated? */
if ((err = fb_alloc_cmap(&fb_display[con].cmap,
1<<fb_display[con].var.bits_per_pixel,
0)))
return err;
}
if (con == info->currcon) /* current console? */
return fb_set_cmap(cmap, kspc, info);
else
fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
return 0;
#else
printk(KERN_ERR "set cmap not supported\n");
return -EINVAL;
#endif
}
static void q40fb_set_disp(int con, struct fb_info *info)
{
struct fb_fix_screeninfo fix;
struct display *display;
q40fb_get_fix(&fix, con, info);
if (con>=0)
display = &fb_display[con];
else
display = &disp[0];
if (con<0) con=0;
display->visual = fix.visual;
display->type = fix.type;
display->type_aux = fix.type_aux;
display->ypanstep = fix.ypanstep;
display->ywrapstep = fix.ywrapstep;
display->can_soft_blank = 0;
display->inverse = 0;
display->line_length = fix.line_length;
display->scrollmode = SCROLL_YREDRAW;
#ifdef FBCON_HAS_CFB16
display->dispsw = &fbcon_cfb16;
disp->dispsw_data = fbcon_cmap_cfb16;
#else
display->dispsw = &fbcon_dummy;
#endif
}
int __init q40fb_init(void)
{
if ( !MACH_IS_Q40)
return -ENXIO;
#if 0
fb_info.screen_base = kernel_map(Q40_PHYS_SCREEN_ADDR, 1024*1024,
KERNELMAP_NO_COPYBACK, NULL);
#else
fb_info.screen_base = Q40_PHYS_SCREEN_ADDR; /* mapped in q40/config.c */
#endif
fb_info.changevar=NULL;
strcpy(&fb_info.modename[0],q40fb_name);
fb_info.fontname[0]=0;
fb_info.disp=disp;
fb_info.currcon = -1;
fb_info.switch_con=&q40con_switch;
fb_info.updatevar=&q40con_updatevar;
/* mapped in q40/config.c */
q40fb_fix.smem_start = Q40_PHYS_SCREEN_ADDR;
fb_info.var = q40fb_var;
fb_info.fix = q40fb_fix;
fb_info.node = NODEV;
fb_info.fbops = &q40fb_ops;
fb_info.flags = FBINFO_FLAG_DEFAULT; /* not as module for now */
fb_info.pseudo_palette = pseudo_palette;
fb_info.screen_base = (char *) q40fb_fix.smem_start;
/* The below feilds will go away !!!! */
fb_info.currcon = -1;
strcpy(fb_info.modename, fb_info.fix.id);
fb_info.disp = &display;
fb_info.switch_con = gen_switch;
fb_info.updatevar = gen_update_var;
fb_alloc_cmap(&fb_info.cmap, 16, 0);
master_outb(3,DISPLAY_CONTROL_REG);
gen_set_disp(-1, &fb_info);
q40fb_get_var(&disp[0].var, 0, &fb_info);
q40fb_set_disp(-1, &fb_info);
master_outb(3, DISPLAY_CONTROL_REG);
if (register_framebuffer(&fb_info) < 0) {
printk(KERN_ERR "unable to register Q40 frame buffer\n");
printk(KERN_ERR "Unable to register Q40 frame buffer\n");
return -EINVAL;
}
......@@ -317,16 +140,4 @@ int __init q40fb_init(void)
return 0;
}
static int q40con_switch(int con, struct fb_info *info)
{
info->currcon=con;
return 0;
}
static int q40con_updatevar(int con, struct fb_info *info)
{
return 0;
}
MODULE_LICENSE("GPL");
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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