Commit 857361ee authored by James Simmons's avatar James Simmons

Neomagic and HGA updates. MAde the software accel code modular. So code...

Neomagic and HGA updates. MAde the software accel code modular. So code cleanup in fbcon. More to go.
parent 112483d2
......@@ -210,7 +210,7 @@ static int tosh_emulate_fan(SMMRegisters *regs)
/*
* Put the laptop into System Management Mode
*/
static int tosh_smm(SMMRegisters *regs)
int tosh_smm(SMMRegisters *regs)
{
int eax;
......
......@@ -297,7 +297,7 @@ config FB_CT65550
config FB_IMSTT
bool "IMS Twin Turbo display support"
depends on FB && PPC
depends on FB && PCI
help
The IMS Twin Turbo is a PCI-based frame buffer card bundled with
many Macintosh and compatible computers.
......
......@@ -5,7 +5,8 @@
# All of the (potential) objects that export symbols.
# This list comes from 'grep -l EXPORT_SYMBOL *.[hc]'.
export-objs := fbmem.o fbcmap.o fbgen.o fbmon.o modedb.o cyber2000fb.o
export-objs := fbmem.o fbcmap.o fbgen.o fbmon.o modedb.o cfbfillrect.o \
cfbcopyarea.o cfbimgblt.o cyber2000fb.o
# Each configuration option enables a list of files.
......
......@@ -20,6 +20,8 @@
* the native cpu endians. I also need to deal with MSB position in the word.
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/fb.h>
......@@ -667,3 +669,10 @@ void cfb_copyarea(struct fb_info *p, struct fb_copyarea *area)
}
}
}
EXPORT_SYMBOL(cfb_copyarea);
MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
MODULE_DESCRIPTION("Generic software accelerated copyarea");
MODULE_LICENSE("GPL");
......@@ -17,6 +17,8 @@
* the native cpu endians. I also need to deal with MSB position in the word.
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <asm/types.h>
......@@ -224,3 +226,9 @@ void cfb_fillrect(struct fb_info *p, struct fb_fillrect *rect)
}
return;
}
EXPORT_SYMBOL(cfb_fillrect);
MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
MODULE_DESCRIPTION("Generic software accelerated fill rectangle");
MODULE_LICENSE("GPL");
......@@ -34,6 +34,8 @@
* the native cpu endians. I also need to deal with MSB position in the word.
*
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <asm/types.h>
......@@ -338,3 +340,10 @@ void cfb_imageblit(struct fb_info *p, struct fb_image *image)
end_mask = 0;
}
}
EXPORT_SYMBOL(cfb_imageblit);
MODULE_AUTHOR("James Simmons <jsimmons@users.sf.net>");
MODULE_DESCRIPTION("Generic software accelerated imaging drawing");
MODULE_LICENSE("GPL");
......@@ -121,8 +121,8 @@ config FBCON_ADVANCED
config FBCON_ACCEL
tristate "Hardware acceleration support" if FBCON_ADVANCED
depends on FB
default m if !FBCON_ADVANCED && FB_NEOMAGIC!=y && !FB_VESA && !FB_FM2 && FB_HIT!=y && !FB_HP300 && !FB_Q40 && !FB_ANAKIN && !FB_G364 && FB_VIRTUAL!=y && !FB_CLPS711X && !FB_PMAG_BA && !FB_PMAGB_B && FB_3DFX!=y && !FB_TX3912 && !FB_MAXINE && !FB_APOLLO && FB_ATY!=y && !FB_MAC && FB_RIVA!=y && !FB_OF && FB_SGIVW!=y && (FB_NEOMAGIC=m || FB_HIT=m || FB_VIRTUAL=m || FB_3DFX=m || FB_RIVA=m || FB_SGIVW=m)
default y if !FBCON_ADVANCED && (FB_NEOMAGIC=y || FB_VESA || FB_FM2 || FB_HIT=y || FB_HP300 || FB_Q40 || FB_ANAKIN || FB_G364 || FB_VIRTUAL=y || FB_CLPS711X || FB_PMAG_BA || FB_PMAGB_B || FB_3DFX=y || FB_TX3912 || FB_MAXINE || FB_APOLLO || FB_ATY=y || FB_MAC || FB_RIVA=y || FB_OF || FB_SGIVW=y)
default m if !FBCON_ADVANCED && FB_NEOMAGIC!=y && !FB_VESA && !FB_FM2 && FB_HIT!=y && !FB_HP300 && !FB_Q40 && !FB_ANAKIN && !FB_G364 && FB_VIRTUAL!=y && !FB_CLPS711X && !FB_PMAG_BA && !FB_PMAGB_B && FB_3DFX!=y && !FB_TX3912 && !FB_MAXINE && !FB_APOLLO && FB_ATY!=y && !FB_MAC && FB_RIVA!=y && FB_HGA!=y && !FB_OF && FB_SGIVW!=y && (FB_NEOMAGIC=m || FB_HIT=m || FB_VIRTUAL=m || FB_3DFX=m || FB_RIVA=m || FB_SGIVW=m || FB_HGA=m)
default y if !FBCON_ADVANCED && (FB_NEOMAGIC=y || FB_VESA || FB_FM2 || FB_HIT=y || FB_HP300 || FB_Q40 || FB_ANAKIN || FB_G364 || FB_VIRTUAL=y || FB_CLPS711X || FB_PMAG_BA || FB_PMAGB_B || FB_3DFX=y || FB_TX3912 || FB_MAXINE || FB_APOLLO || FB_ATY=y || FB_MAC || FB_RIVA=y || FB_OF || FB_SGIVW=y || FB_HGA=y)
config FBCON_AFB
tristate "Amiga bitplanes support" if FBCON_ADVANCED
......@@ -166,15 +166,6 @@ config FBCON_IPLAN2P8
This is the low level frame buffer console driver for 8 interleaved
bitplanes (256 colors) on Atari.
config FBCON_HGA
tristate "HGA monochrome support (EXPERIMENTAL)" if FBCON_ADVANCED
depends on FB
default m if !FBCON_ADVANCED && FB_HGA=m
default y if !FBCON_ADVANCED && FB_HGA=y
help
This is the low level frame buffer console driver for Hercules mono
graphics cards.
# Guess what we need
config FBCON_STI
tristate
......
......@@ -36,7 +36,6 @@ obj-$(CONFIG_FBCON_ILBM) += fbcon-ilbm.o
obj-$(CONFIG_FBCON_IPLAN2P2) += fbcon-iplan2p2.o
obj-$(CONFIG_FBCON_IPLAN2P4) += fbcon-iplan2p4.o
obj-$(CONFIG_FBCON_IPLAN2P8) += fbcon-iplan2p8.o
obj-$(CONFIG_FBCON_HGA) += fbcon-hga.o
obj-$(CONFIG_FBCON_STI) += fbcon-sti.o
obj-$(CONFIG_FBCON_ACCEL) += fbcon-accel.o
......
/*
* linux/drivers/video/fbcon-hga.c -- Low level frame buffer operations for
* the Hercules graphics adaptor
*
* Created 25 Nov 1999 by Ferenc Bakonyi (fero@drama.obuda.kando.hu)
* Based on fbcon-mfb.c by Geert Uytterhoeven
*
* History:
*
* - Revision 0.1.0 (6 Dec 1999): comment changes
* - First release (25 Nov 1999)
*
* 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/module.h>
#include <linux/tty.h>
#include <linux/console.h>
#include <linux/string.h>
#include <linux/fb.h>
#include <video/fbcon.h>
#include <video/fbcon-hga.h>
#if 0
#define DPRINTK(args...) printk(KERN_DEBUG __FILE__": " ##args)
#else
#define DPRINTK(args...)
#endif
#define HGA_ROWADDR(row) ((row%4)*8192 + (row>>2)*90)
/*
* Hercules monochrome
*/
static inline u8* rowaddr(struct display *p, u_int row)
{
return p->fb_info->screen_base + HGA_ROWADDR(row);
}
void fbcon_hga_setup(struct display *p)
{
DPRINTK("fbcon_hga_setup: ll:%d\n", (int)p->line_length);
p->next_line = p->fb_info->fix.line_length;
p->next_plane = 0;
}
void fbcon_hga_bmove(struct display *p, int sy, int sx, int dy, int dx,
int height, int width)
{
u8 *src, *dest;
u_int rows, y1, y2;
#if 0
if (sx == 0 && dx == 0 && width == p->next_line) {
src = p->fb_info->screen_base+sy*fontheight(p)*width;
dest = p->fb_info->screen_base+dy*fontheight(p)*width;
fb_memmove(dest, src, height*fontheight(p)*width);
} else
#endif
if (dy <= sy) {
y1 = sy*fontheight(p);
y2 = dy*fontheight(p);
for (rows = height*fontheight(p); rows--; ) {
src = rowaddr(p, y1)+sx;
dest = rowaddr(p, y2)+dx;
fb_memmove(dest, src, width);
y1++;
y2++;
}
} else {
y1 = (sy+height)*fontheight(p)-1;
y2 = (dy+height)*fontheight(p)-1;
for (rows = height*fontheight(p); rows--;) {
src = rowaddr(p, y1)+sx;
dest = rowaddr(p, y2)+dx;
fb_memmove(dest, src, width);
y1--;
y2--;
}
}
}
void fbcon_hga_clear(struct vc_data *conp, struct display *p, int sy, int sx,
int height, int width)
{
u8 *dest;
u_int rows, y;
int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
DPRINTK("fbcon_hga_clear: sx:%d, sy:%d, height:%d, width:%d\n", sx, sy, height, width);
y = sy*fontheight(p);
#if 0
if (sx == 0 && width == p->next_line) {
if (inverse) {
fb_memset255(dest, height*fontheight(p)*width);
} else {
fb_memclear(dest, height*fontheight(p)*width);
}
} else
#endif
for (rows = height*fontheight(p); rows--; y++) {
dest = rowaddr(p, y)+sx;
if (inverse) {
fb_memset255(dest, width);
} else {
fb_memclear(dest, width);
}
}
}
void fbcon_hga_putc(struct vc_data *conp, struct display *p, int c, int yy,
int xx)
{
u8 *dest, *cdat;
u_int rows, y, bold, revs, underl;
u8 d;
cdat = p->fontdata+(c&p->charmask)*fontheight(p);
bold = attr_bold(p, c);
revs = attr_reverse(p, c);
underl = attr_underline(p, c);
y = yy*fontheight(p);
for (rows = fontheight(p); rows--; y++) {
d = *cdat++;
if (underl && !rows)
d = 0xff;
else if (bold)
d |= d>>1;
if (revs)
d = ~d;
dest = rowaddr(p, y)+xx;
*dest = d;
}
}
void fbcon_hga_putcs(struct vc_data *conp, struct display *p,
const unsigned short *s, int count, int yy, int xx)
{
u8 *dest, *cdat;
u_int rows, y, y0, bold, revs, underl;
u8 d;
u16 c;
c = scr_readw(s);
bold = attr_bold(p, c);
revs = attr_reverse(p, c);
underl = attr_underline(p, c);
y0 = yy*fontheight(p);
while (count--) {
c = scr_readw(s++) & p->charmask;
cdat = p->fontdata+c*fontheight(p);
y = y0;
for (rows = fontheight(p); rows--; y++) {
d = *cdat++;
if (underl && !rows)
d = 0xff;
else if (bold)
d |= d>>1;
if (revs)
d = ~d;
dest = rowaddr(p, y)+xx;
*dest = d;
}
xx++;
}
}
void fbcon_hga_revc(struct display *p, int xx, int yy)
{
u8 *dest;
u_int rows, y;
y = yy*fontheight(p);
for (rows = fontheight(p); rows--; y++) {
dest = rowaddr(p, y)+xx;
*dest = ~*dest;
}
}
void fbcon_hga_clear_margins(struct vc_data *conp, struct display *p,
int bottom_only)
{
u8 *dest;
u_int height, y;
int inverse = conp ? attr_reverse(p,conp->vc_video_erase_char) : 0;
DPRINTK("fbcon_hga_clear_margins: enter\n");
/* No need to handle right margin. */
y = conp->vc_rows * fontheight(p);
for (height = p->var.yres - y; height-- > 0; y++) {
DPRINTK("fbcon_hga_clear_margins: y:%d, height:%d\n", y, height);
dest = rowaddr(p, y);
if (inverse) {
fb_memset255(dest, p->next_line);
} else {
fb_memclear(dest, p->next_line);
}
}
}
/*
* `switch' for the low level operations
*/
struct display_switch fbcon_hga = {
.setup = fbcon_hga_setup,
.bmove = fbcon_hga_bmove,
.clear = fbcon_hga_clear,
.putc = fbcon_hga_putc,
.putcs = fbcon_hga_putcs,
.revc = fbcon_hga_revc,
.clear_margins =fbcon_hga_clear_margins,
.fontwidthmask =FONTWIDTH(8)
};
#ifdef MODULE
MODULE_LICENSE("GPL");
int init_module(void)
{
return 0;
}
void cleanup_module(void)
{
}
#endif /* MODULE */
/*
* Visible symbols for modules
*/
EXPORT_SYMBOL(fbcon_hga);
EXPORT_SYMBOL(fbcon_hga_setup);
EXPORT_SYMBOL(fbcon_hga_bmove);
EXPORT_SYMBOL(fbcon_hga_clear);
EXPORT_SYMBOL(fbcon_hga_putc);
EXPORT_SYMBOL(fbcon_hga_putcs);
EXPORT_SYMBOL(fbcon_hga_revc);
EXPORT_SYMBOL(fbcon_hga_clear_margins);
This diff is collapsed.
......@@ -91,8 +91,6 @@ struct display {
extern struct display fb_display[MAX_NR_CONSOLES];
extern char con2fb_map[MAX_NR_CONSOLES];
extern void set_con2fb_map(int unit, int newidx);
extern int set_all_vcs(int fbidx, struct fb_ops *fb,
struct fb_var_screeninfo *var, struct fb_info *info);
#define fontheight(p) ((p)->_fontheight)
#define fontheightlog(p) ((p)->_fontheightlog)
......
......@@ -20,34 +20,6 @@
#include <asm/uaccess.h>
#include <asm/io.h>
int fb_set_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
int err;
if (memcmp(&info->var, var, sizeof(struct fb_var_screeninfo))) {
if (!info->fbops->fb_check_var) {
*var = info->var;
return 0;
}
if ((err = info->fbops->fb_check_var(var, info)))
return err;
if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
info->var = *var;
if (info->fbops->fb_set_par)
info->fbops->fb_set_par(info);
if (info->fbops->fb_pan_display)
info->fbops->fb_pan_display(&info->var,
info);
fb_set_cmap(&info->cmap, 1, info);
}
}
return 0;
}
int cfb_cursor(struct fb_info *info, struct fbcursor *cursor)
{
int i, size = ((cursor->size.x + 7) / 8) * cursor->size.y;
......@@ -143,7 +115,6 @@ int fb_blank(int blank, struct fb_info *info)
}
/* generic frame buffer operations */
EXPORT_SYMBOL(fb_set_var);
EXPORT_SYMBOL(cfb_cursor);
EXPORT_SYMBOL(fb_pan_display);
EXPORT_SYMBOL(fb_blank);
......
......@@ -464,6 +464,34 @@ static void try_to_load(int fb)
}
#endif /* CONFIG_KMOD */
int fb_set_var(struct fb_var_screeninfo *var, struct fb_info *info)
{
int err;
if (memcmp(&info->var, var, sizeof(struct fb_var_screeninfo))) {
if (!info->fbops->fb_check_var) {
*var = info->var;
return 0;
}
if ((err = info->fbops->fb_check_var(var, info)))
return err;
if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
info->var = *var;
if (info->fbops->fb_set_par)
info->fbops->fb_set_par(info);
if (info->fbops->fb_pan_display)
info->fbops->fb_pan_display(&info->var, info);
fb_set_cmap(&info->cmap, 1, info);
}
}
return 0;
}
static int
fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
unsigned long arg)
......@@ -488,11 +516,6 @@ fb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
case FBIOPUT_VSCREENINFO:
if (copy_from_user(&var, (void *) arg, sizeof(var)))
return -EFAULT;
#ifdef CONFIG_FRAMEBUFFER_CONSOLE
if (var.activate & FB_ACTIVATE_ALL)
i = set_all_vcs(fbidx, fb, &var, info);
else
#endif
i = fb_set_var(&var, info);
if (i) return i;
if (copy_to_user((void *) arg, &var, sizeof(var)))
......
......@@ -46,8 +46,6 @@
#include <linux/ioport.h>
#include <asm/io.h>
#include <asm/vga.h>
#include <video/fbcon.h>
#include <video/fbcon-hga.h>
#ifdef MODULE
......@@ -73,9 +71,15 @@
static unsigned long hga_vram_base; /* Base of video memory */
static unsigned long hga_vram_len; /* Size of video memory */
#define HGA_ROWADDR(row) ((row%4)*8192 + (row>>2)*90)
#define HGA_TXT 0
#define HGA_GFX 1
static inline u8* rowaddr(struct fb_info *info, u_int row)
{
return info->screen_base + HGA_ROWADDR(row);
}
static int hga_mode = -1; /* 0 = txt, 1 = gfx mode */
static enum { TYPE_HERC, TYPE_HERCPLUS, TYPE_HERCCOLOR } hga_type;
......@@ -137,7 +141,6 @@ static struct fb_fix_screeninfo hga_fix = {
};
static struct fb_info fb_info;
static struct display disp;
/* Don't assume that tty1 will be the initial current console. */
static int release_io_port = 0;
......@@ -189,7 +192,6 @@ static void hga_clear_screen(void)
isa_memset_io(hga_vram_base, fillchar, hga_vram_len);
}
#ifdef MODULE
static void hga_txt_mode(void)
{
......@@ -255,15 +257,13 @@ static void hga_gfx_mode(void)
}
#ifdef MODULE
static void hga_show_logo(void)
static void hga_show_logo(struct fb_info *info)
{
int x, y;
unsigned long dest = hga_vram_base;
char *logo = linux_logo_bw;
for (y = 134; y < 134 + 80 ; y++) /* this needs some cleanup */
for (x = 0; x < 10 ; x++)
isa_writeb(~*(logo++),
(dest + (y%4)*8192 + (y>>2)*90 + x + 40));
isa_writeb(~*(logo++),(dest + HGA_ROWADDR(y) + x + 40));
}
#endif /* MODULE */
......@@ -389,7 +389,6 @@ static int hgafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
/**
* hga_pan_display - pan or wrap the display
* @var:contains new xoffset, yoffset and vmode values
* @con:unused
* @info:pointer to fb_info object containing info for current hga board
*
* This function looks only at xoffset, yoffset and the %FB_VMODE_YWRAP
......@@ -398,12 +397,8 @@ static int hgafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
* A zero is returned on success and %-EINVAL for failure.
*/
int hga_pan_display(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
int hgafb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
{
CHKINFO(-EINVAL);
DPRINTK("pan_disp: con:%d, wrap:%d, xoff:%d, yoff:%d\n", con, var->vmode & FB_VMODE_YWRAP, var->xoffset, var->yoffset);
if (var->vmode & FB_VMODE_YWRAP) {
if (var->yoffset < 0 ||
var->yoffset >= info->var.yres_virtual ||
......@@ -442,24 +437,84 @@ int hga_pan_display(struct fb_var_screeninfo *var, int con,
static int hgafb_blank(int blank_mode, struct fb_info *info)
{
CHKINFO( );
DPRINTK("hgafb_blank: blank_mode:%d, info:%x, fb_info:%x\n", blank_mode, (unsigned)info, (unsigned)&fb_info);
hga_blank(blank_mode);
return 0;
}
static void hgafb_fillrect(struct fb_info *info, struct fb_fillrect *rect)
{
u_int rows, y;
u8 *dest;
y = rect->dy;
for (rows = rect->height; rows--; y++) {
dest = rowaddr(info, y) + (rect->dx >> 3);
switch (rect->rop) {
case ROP_COPY:
fb_memset(dest, rect->color, (rect->width >> 3));
break;
case ROP_XOR:
*dest = ~*dest;
break;
}
}
}
static void hgafb_copyarea(struct fb_info *info, struct fb_copyarea *area)
{
u_int rows, y1, y2;
u8 *src, *dest;
if (area->dy <= area->sy) {
y1 = area->sy;
y2 = area->dy;
for (rows = area->height; rows--; ) {
src = rowaddr(info, y1) + (area->sx >> 3);
dest = rowaddr(info, y2) + (area->dx >> 3);
fb_memmove(dest, src, (area->width >> 3));
y1++;
y2++;
}
} else {
y1 = area->sy + area->height - 1;
y2 = area->dy + area->height - 1;
for (rows = area->height; rows--;) {
src = rowaddr(info, y1) + (area->sx >> 3);
dest = rowaddr(info, y2) + (area->dx >> 3);
fb_memmove(dest, src, (area->width >> 3));
y1--;
y2--;
}
}
}
static void hgafb_imageblit(struct fb_info *info, struct fb_image *image)
{
u8 *dest, *cdat = image->data;
u_int rows, y = image->dy;
u8 d;
for (rows = image->height; rows--; y++) {
d = *cdat++;
dest = rowaddr(info, y) + (image->dx >> 3);
*dest = d;
}
}
static struct fb_ops hgafb_ops = {
.owner = THIS_MODULE,
.fb_set_var = gen_set_var,
.fb_get_cmap = gen_get_cmap,
.fb_set_cmap = gen_set_cmap,
.fb_setcolreg = hgafb_setcolreg,
.fb_pan_display = hga_pan_display,
.fb_pan_display = hgafb_pan_display,
.fb_blank = hgafb_blank,
.fb_fillrect = hgafb_fillrect,
.fb_copyarea = hgafb_copyarea,
.fb_imageblit = hgafb_imageblit,
};
/* ------------------------------------------------------------------------- *
*
* Functions in fb_info
......@@ -484,27 +539,10 @@ int __init hgafb_init(void)
hga_gfx_mode();
hga_clear_screen();
#ifdef MODULE
if (!nologo) hga_show_logo();
#endif /* MODULE */
hga_fix.smem_start = VGA_MAP_MEM(hga_vram_base);
hga_fix.smem_len = hga_vram_len;
disp.var = hga_default_var;
disp.can_soft_blank = 1;
disp.inverse = 0;
#ifdef FBCON_HAS_HGA
disp.dispsw = &fbcon_hga;
#else
#warning HGAFB will not work as a console!
disp.dispsw = &fbcon_dummy;
#endif
disp.dispsw_data = NULL;
disp.scrollmode = SCROLL_YREDRAW;
strcpy (fb_info.modename, hga_fix.id);
fb_info.node = NODEV;
fb_info.flags = FBINFO_FLAG_DEFAULT;
fb_info.var = hga_default_var;
......@@ -516,18 +554,16 @@ int __init hgafb_init(void)
fb_info.monspecs.dpms = 0;
fb_info.fbops = &hgafb_ops;
fb_info.screen_base = (char *)hga_fix.smem_start;
fb_info.disp = &disp;
fb_info.currcon = 1;
fb_info.changevar = NULL;
fb_info.switch_con = gen_switch;
fb_info.updatevar = gen_update_var;
if (register_framebuffer(&fb_info) < 0)
return -EINVAL;
printk(KERN_INFO "fb%d: %s frame buffer device\n",
minor(fb_info.node), fb_info.modename);
#ifdef MODULE
if (!nologo) hga_show_logo(&fb_info);
#endif /* MODULE */
printk(KERN_INFO "fb%d: %s frame buffer device\n",
minor(fb_info.node), fb_info.fix.id);
return 0;
}
......@@ -535,49 +571,21 @@ int __init hgafb_init(void)
* Setup
*/
#ifndef MODULE
int __init hgafb_setup(char *options)
{
/*
* Parse user speficied options
* `video=hga:font:VGA8x16' or
* `video=hga:font:SUN8x16' recommended
* Other supported fonts: VGA8x8, Acorn8x8, PEARL8x8
* More different fonts can be used with the `setfont' utility.
*/
char *this_opt;
fb_info.fontname[0] = '\0';
if (!options || !*options)
return 0;
while ((this_opt = strsep(&options, ","))) {
if (!strncmp(this_opt, "font:", 5))
strcpy(fb_info.fontname, this_opt+5);
}
return 0;
}
#endif /* !MODULE */
/*
* Cleanup
*/
#ifdef MODULE
static void hgafb_cleanup(struct fb_info *info)
static void __exit hgafb_exit(void)
{
hga_txt_mode();
hga_clear_screen();
unregister_framebuffer(info);
unregister_framebuffer(&fb_info);
if (release_io_ports) release_region(0x3b0, 12);
if (release_io_port) release_region(0x3bf, 1);
}
#endif /* MODULE */
#endif
/* -------------------------------------------------------------------------
*
......@@ -585,29 +593,14 @@ static void hgafb_cleanup(struct fb_info *info)
*
* ------------------------------------------------------------------------- */
#ifdef MODULE
int init_module(void)
{
if (font)
strncpy(fb_info.fontname, font, sizeof(fb_info.fontname)-1);
else
fb_info.fontname[0] = '\0';
return hgafb_init();
}
void cleanup_module(void)
{
hgafb_cleanup(&fb_info);
}
MODULE_AUTHOR("Ferenc Bakonyi (fero@drama.obuda.kando.hu)");
MODULE_DESCRIPTION("FBDev driver for Hercules Graphics Adaptor");
MODULE_LICENSE("GPL");
MODULE_PARM(font, "s");
MODULE_PARM_DESC(font, "Specifies one of the compiled-in fonts (VGA8x8, VGA8x16, SUN8x16, Acorn8x8, PEARL8x8) (default=none)");
MODULE_PARM(nologo, "i");
MODULE_PARM_DESC(nologo, "Disables startup logo if != 0 (default=0)");
#endif /* MODULE */
#ifdef MODULE
module_init(hgafb_init);
module_exit(hgafb_exit);
#endif
/*
* linux/drivers/video/neofb.c -- NeoMagic Framebuffer Driver
*
* Copyright (c) 2001 Denis Oliver Kropp <dok@convergence.de>
* Copyright (c) 2001-2002 Denis Oliver Kropp <dok@directfb.org>
*
*
* Card specific code is based on XFree86's neomagic driver.
......@@ -11,6 +11,16 @@
* Public License. See the file COPYING in the main directory of this
* archive for more details.
*
*
* 0.4.1
* - Cosmetic changes (dok)
*
* 0.4
* - Toshiba Libretto support, allow modes larger than LCD size if
* LCD is disabled, keep BIOS settings if internal/external display
* haven't been enabled explicitly
* (Thomas J. Moore <dark@mama.indstate.edu>)
*
* 0.3.3
* - Porting over to new fbdev api. (jsimmons)
*
......@@ -56,6 +66,10 @@
#include <linux/fb.h>
#include <linux/pci.h>
#include <linux/init.h>
#ifdef CONFIG_TOSHIBA
#include <linux/toshiba.h>
extern int tosh_smm(SMMRegisters *regs);
#endif
#include <asm/io.h>
#include <asm/irq.h>
......@@ -69,17 +83,18 @@
#include <video/neomagic.h>
#define NEOFB_VERSION "0.3.3"
#define NEOFB_VERSION "0.4.1"
struct neofb_par default_par;
/* --------------------------------------------------------------------- */
static int disabled = 0;
static int internal = 0;
static int external = 0;
static int nostretch = 0;
static int nopciburst = 0;
static int disabled;
static int internal;
static int external;
static int libretto;
static int nostretch;
static int nopciburst;
#ifdef MODULE
......@@ -93,6 +108,8 @@ MODULE_PARM(internal, "i");
MODULE_PARM_DESC(internal, "Enable output on internal LCD Display.");
MODULE_PARM(external, "i");
MODULE_PARM_DESC(external, "Enable output on external CRT.");
MODULE_PARM(libretto, "i");
MODULE_PARM_DESC(libretto, "Force Libretto 100/110 800x480 LCD.");
MODULE_PARM(nostretch, "i");
MODULE_PARM_DESC(nostretch,
"Disable stretching of modes smaller than LCD.");
......@@ -550,8 +567,9 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
timings.sync = var->sync;
/* Is the mode larger than the LCD panel? */
if ((var->xres > par->NeoPanelWidth) ||
(var->yres > par->NeoPanelHeight)) {
if (par->internal_display &&
((var->xres > par->NeoPanelWidth) ||
(var->yres > par->NeoPanelHeight))) {
printk(KERN_INFO
"Mode (%dx%d) larger than the LCD panel (%dx%d)\n",
var->xres, var->yres, par->NeoPanelWidth,
......@@ -560,6 +578,9 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
}
/* Is the mode one of the acceptable sizes? */
if (!par->internal_display)
mode_ok = 1;
else {
switch (var->xres) {
case 1280:
if (var->yres == 1024)
......@@ -570,7 +591,7 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
mode_ok = 1;
break;
case 800:
if (var->yres == 600)
if (var->yres == (par->libretto ? 480 : 600))
mode_ok = 1;
break;
case 640:
......@@ -578,6 +599,7 @@ neofb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
mode_ok = 1;
break;
}
}
if (!mode_ok) {
printk(KERN_INFO
......@@ -1259,6 +1281,17 @@ static int neofb_blank(int blank, struct fb_info *fb)
switch (blank) {
case 4: /* powerdown - both sync lines down */
#ifdef CONFIG_TOSHIBA
/* attempt to turn off backlight on toshiba; also turns off external */
{
SMMRegisters regs;
regs.eax = 0xff00; /* HCI_SET */
regs.ebx = 0x0002; /* HCI_BACKLIGHT */
regs.ecx = 0x0000; /* HCI_DISABLE */
tosh_smm(&regs);
}
#endif
break;
case 3: /* hsync off */
break;
......@@ -1267,6 +1300,17 @@ static int neofb_blank(int blank, struct fb_info *fb)
case 1: /* just software blanking of screen */
break;
default: /* case 0, or anything else: unblank */
#ifdef CONFIG_TOSHIBA
/* attempt to re-enable backlight/external on toshiba */
{
SMMRegisters regs;
regs.eax = 0xff00; /* HCI_SET */
regs.ebx = 0x0002; /* HCI_BACKLIGHT */
regs.ecx = 0x0001; /* HCI_ENABLE */
tosh_smm(&regs);
}
#endif
break;
}
return 0;
......@@ -1399,75 +1443,93 @@ static struct fb_ops neofb_ops = {
/* --------------------------------------------------------------------- */
static struct fb_var_screeninfo __devinitdata neofb_var640x480x8 = {
accel_flags: FB_ACCELF_TEXT,
xres: 640,
yres: 480,
xres_virtual: 640,
yres_virtual: 30000,
bits_per_pixel: 8,
pixclock: 39722,
left_margin: 48,
right_margin: 16,
upper_margin: 33,
lower_margin: 10,
hsync_len: 96,
vsync_len: 2,
vmode: FB_VMODE_NONINTERLACED
.accel_flags = FB_ACCELF_TEXT,
.xres = 640,
.yres = 480,
.xres_virtual = 640,
.yres_virtual = 30000,
.bits_per_pixel = 8,
.pixclock = 39722,
.left_margin = 48,
.right_margin = 16,
.upper_margin = 33,
.lower_margin = 10,
.hsync_len = 96,
.vsync_len = 2,
.vmode = FB_VMODE_NONINTERLACED
};
static struct fb_var_screeninfo __devinitdata neofb_var800x600x8 = {
accel_flags: FB_ACCELF_TEXT,
xres: 800,
yres: 600,
xres_virtual: 800,
yres_virtual: 30000,
bits_per_pixel: 8,
pixclock: 25000,
left_margin: 88,
right_margin: 40,
upper_margin: 23,
lower_margin: 1,
hsync_len: 128,
vsync_len: 4,
sync: FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
vmode: FB_VMODE_NONINTERLACED
.accel_flags = FB_ACCELF_TEXT,
.xres = 800,
.yres = 600,
.xres_virtual = 800,
.yres_virtual = 30000,
.bits_per_pixel = 8,
.pixclock = 25000,
.left_margin = 88,
.right_margin = 40,
.upper_margin = 23,
.lower_margin = 1,
.hsync_len = 128,
.vsync_len = 4,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED
};
static struct fb_var_screeninfo __devinitdata neofb_var800x480x8 = {
.accel_flags = FB_ACCELF_TEXT,
.xres = 800,
.yres = 480,
.xres_virtual = 800,
.yres_virtual = 30000,
.bits_per_pixel = 8,
.pixclock = 25000,
.left_margin = 88,
.right_margin = 40,
.upper_margin = 23,
.lower_margin = 1,
.hsync_len = 128,
.vsync_len = 4,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED
};
static struct fb_var_screeninfo __devinitdata neofb_var1024x768x8 = {
accel_flags: FB_ACCELF_TEXT,
xres: 1024,
yres: 768,
xres_virtual: 1024,
yres_virtual: 30000,
bits_per_pixel: 8,
pixclock: 15385,
left_margin: 160,
right_margin: 24,
upper_margin: 29,
lower_margin: 3,
hsync_len: 136,
vsync_len: 6,
sync: FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
vmode: FB_VMODE_NONINTERLACED
.accel_flags = FB_ACCELF_TEXT,
.xres = 1024,
.yres = 768,
.xres_virtual = 1024,
.yres_virtual = 30000,
.bits_per_pixel = 8,
.pixclock = 15385,
.left_margin = 160,
.right_margin = 24,
.upper_margin = 29,
.lower_margin = 3,
.hsync_len = 136,
.vsync_len = 6,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED
};
#ifdef NOT_DONE
static struct fb_var_screeninfo __devinitdata neofb_var1280x1024x8 = {
accel_flags: FB_ACCELF_TEXT,
xres: 1280,
yres: 1024,
xres_virtual: 1280,
yres_virtual: 30000,
bits_per_pixel: 8,
pixclock: 9260,
left_margin: 248,
right_margin: 48,
upper_margin: 38,
lower_margin: 1,
hsync_len: 112,
vsync_len: 3,
sync: FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
vmode: FB_VMODE_NONINTERLACED
.accel_flags = FB_ACCELF_TEXT,
.xres = 1280,
.yres = 1024,
.xres_virtual = 1280,
.yres_virtual = 30000,
.bits_per_pixel = 8,
.pixclock = 9260,
.left_margin = 248,
.right_margin = 48,
.upper_margin = 38,
.lower_margin = 1,
.hsync_len = 112,
.vsync_len = 3,
.sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
.vmode = FB_VMODE_NONINTERLACED
};
#endif
......@@ -1605,6 +1667,13 @@ static int __devinit neo_init_hw(struct fb_info *info)
VGAwGR(0x09, 0x26);
type = VGArGR(0x21);
display = VGArGR(0x20);
if (!par->internal_display && !par->external_display) {
par->internal_display = display & 2 || !(display & 3) ? 1 : 0;
par->external_display = display & 1;
printk (KERN_INFO "Autodetected %s display\n",
par->internal_display && par->external_display ? "simultaneous" :
par->internal_display ? "internal" : "external");
}
/* Determine panel width -- used in NeoValidMode. */
w = VGArGR(0x20);
......@@ -1617,8 +1686,8 @@ static int __devinit neo_init_hw(struct fb_info *info)
break;
case 0x01:
par->NeoPanelWidth = 800;
par->NeoPanelHeight = 600;
neofb_var = &neofb_var800x600x8;
par->NeoPanelHeight = par->libretto ? 480 : 600;
neofb_var = par->libretto ? &neofb_var800x480x8 : &neofb_var800x600x8;
break;
case 0x02:
par->NeoPanelWidth = 1024;
......@@ -1634,7 +1703,7 @@ static int __devinit neo_init_hw(struct fb_info *info)
break;
#else
printk(KERN_ERR
"neofb: Only 640x480, 800x600 and 1024x768 panels are currently supported\n");
"neofb: Only 640x480, 800x600/480 and 1024x768 panels are currently supported\n");
return -1;
#endif
default:
......@@ -1761,14 +1830,10 @@ static struct fb_info *__devinit neo_alloc_fb_info(struct pci_dev *dev, const st
par->pci_burst = !nopciburst;
par->lcd_stretch = !nostretch;
par->libretto = libretto;
if (!internal && !external) {
par->internal_display = 1;
par->external_display = 0;
} else {
par->internal_display = internal;
par->external_display = external;
}
switch (info->fix.accel) {
case FB_ACCEL_NEOMAGIC_NM2070:
......@@ -2024,6 +2089,8 @@ int __init neofb_setup(char *options)
nostretch = 1;
if (!strncmp(this_opt, "nopciburst", 10))
nopciburst = 1;
if (!strncmp(this_opt, "libretto", 8))
libretto = 1;
}
return 0;
......
......@@ -1155,8 +1155,6 @@ static void __exit tdfxfb_exit(void)
MODULE_AUTHOR("Hannu Mallat <hmallat@cc.hut.fi>");
MODULE_DESCRIPTION("3Dfx framebuffer device driver");
MODULE_LICENSE("GPL");
MODULE_PARM(noaccel, "i");
MODULE_PARM_DESC(noaccel, "Disable hardware acceleration (1 = disabled), enabled by default.");
#ifdef MODULE
module_init(tdfxfb_init);
......
......@@ -176,6 +176,7 @@ struct neofb_par {
int lcd_stretch;
int internal_display;
int external_display;
int libretto;
};
typedef struct {
......
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