Commit a49ac33b authored by James Simmons's avatar James Simmons

More changes for new fbdev subsytem.

parent 4038102c
...@@ -57,13 +57,13 @@ obj-$(CONFIG_FB_PLATINUM) += platinumfb.o ...@@ -57,13 +57,13 @@ obj-$(CONFIG_FB_PLATINUM) += platinumfb.o
obj-$(CONFIG_FB_VALKYRIE) += valkyriefb.o obj-$(CONFIG_FB_VALKYRIE) += valkyriefb.o
obj-$(CONFIG_FB_CT65550) += chipsfb.o obj-$(CONFIG_FB_CT65550) += chipsfb.o
obj-$(CONFIG_FB_ANAKIN) += anakinfb.o obj-$(CONFIG_FB_ANAKIN) += anakinfb.o
obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_CYBER) += cyberfb.o obj-$(CONFIG_FB_CYBER) += cyberfb.o
obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o
obj-$(CONFIG_FB_SGIVW) += sgivwfb.o obj-$(CONFIG_FB_SGIVW) += sgivwfb.o
obj-$(CONFIG_FB_3DFX) += tdfxfb.o obj-$(CONFIG_FB_3DFX) += tdfxfb.o
obj-$(CONFIG_FB_MAC) += macfb.o macmodes.o obj-$(CONFIG_FB_MAC) += macfb.o macmodes.o
obj-$(CONFIG_FB_HP300) += hpfb.o obj-$(CONFIG_FB_HP300) += hpfb.o cfbfillrect.o cfbimgblt.o
obj-$(CONFIG_FB_OF) += offb.o obj-$(CONFIG_FB_OF) += offb.o
obj-$(CONFIG_FB_IMSTT) += imsttfb.o obj-$(CONFIG_FB_IMSTT) += imsttfb.o
obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o obj-$(CONFIG_FB_RETINAZ3) += retz3fb.o
...@@ -74,7 +74,7 @@ obj-$(CONFIG_FB_TGA) += tgafb.o ...@@ -74,7 +74,7 @@ obj-$(CONFIG_FB_TGA) += tgafb.o
obj-$(CONFIG_FB_VESA) += vesafb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.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 cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_FM2) += fm2fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_FM2) += fm2fb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_CREATOR) += creatorfb.o sbusfb.o obj-$(CONFIG_FB_CREATOR) += creatorfb.o sbusfb.o
obj-$(CONFIG_FB_CGSIX) += cgsixfb.o sbusfb.o obj-$(CONFIG_FB_CGSIX) += cgsixfb.o sbusfb.o
...@@ -99,7 +99,7 @@ obj-$(CONFIG_FB_SUN3) += sun3fb.o ...@@ -99,7 +99,7 @@ obj-$(CONFIG_FB_SUN3) += sun3fb.o
obj-$(CONFIG_FB_BWTWO) += bwtwofb.o obj-$(CONFIG_FB_BWTWO) += bwtwofb.o
obj-$(CONFIG_FB_HGA) += hgafb.o obj-$(CONFIG_FB_HGA) += hgafb.o
obj-$(CONFIG_FB_SA1100) += sa1100fb.o obj-$(CONFIG_FB_SA1100) += sa1100fb.o
obj-$(CONFIG_FB_VIRTUAL) += vfb.o obj-$(CONFIG_FB_VIRTUAL) += vfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_HIT) += hitfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o obj-$(CONFIG_FB_HIT) += hitfb.o cfbfillrect.o cfbcopyarea.o cfbimgblt.o
obj-$(CONFIG_FB_E1355) += epson1355fb.o obj-$(CONFIG_FB_E1355) += epson1355fb.o
obj-$(CONFIG_FB_PVR2) += pvr2fb.o obj-$(CONFIG_FB_PVR2) += pvr2fb.o
......
...@@ -158,7 +158,7 @@ struct display_switch fbcon_accel = { ...@@ -158,7 +158,7 @@ struct display_switch fbcon_accel = {
putcs: fbcon_accel_putcs, putcs: fbcon_accel_putcs,
revc: fbcon_accel_revc, revc: fbcon_accel_revc,
clear_margins: fbcon_accel_clear_margins, clear_margins: fbcon_accel_clear_margins,
fontwidthmask: FONTWIDTHRANGE(1, 32) fontwidthmask: FONTWIDTHRANGE(1, 16)
}; };
#ifdef MODULE #ifdef MODULE
......
...@@ -67,9 +67,6 @@ ...@@ -67,9 +67,6 @@
#define DPRINTK(a,b...) #define DPRINTK(a,b...)
#endif #endif
#define PICOS2KHZ(a) (1000000000UL/(a))
#define KHZ2PICOS(a) (1000000000UL/(a))
/* /*
* The _DEFINITIVE_ memory mapping/unmapping functions. * The _DEFINITIVE_ memory mapping/unmapping functions.
* This is due to the fact that they're changing soooo often... * This is due to the fact that they're changing soooo often...
......
...@@ -1154,8 +1154,6 @@ ...@@ -1154,8 +1154,6 @@
/* permedia3 -specific definitions */ /* permedia3 -specific definitions */
#define PM3_SCALE_TO_CLOCK(pr, fe, po) ((2 * PM3_REF_CLOCK * fe) / (pr * (1 << (po)))) #define PM3_SCALE_TO_CLOCK(pr, fe, po) ((2 * PM3_REF_CLOCK * fe) / (pr * (1 << (po))))
#define PICOS2KHZ(a) (1000000000UL/(a))
#define KHZ2PICOS(a) (1000000000UL/(a))
/* in case it's not in linux/pci.h */ /* in case it's not in linux/pci.h */
#ifndef PCI_DEVICE_ID_3DLABS_PERMEDIA3 #ifndef PCI_DEVICE_ID_3DLABS_PERMEDIA3
......
...@@ -43,6 +43,8 @@ ...@@ -43,6 +43,8 @@
* *
* Version history: * Version history:
* *
* 0.1.4 (released 2002-05-28) ported over to new fbdev api by James Simmons
*
* 0.1.3 (released 1999-11-02) added Attila's panning support, code * 0.1.3 (released 1999-11-02) added Attila's panning support, code
* reorg, hwcursor address page size alignment * reorg, hwcursor address page size alignment
* (for mmaping both frame buffer and regs), * (for mmaping both frame buffer and regs),
...@@ -64,174 +66,32 @@ ...@@ -64,174 +66,32 @@
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/tty.h> #include <linux/tty.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/interrupt.h> #include <linux/interrupt.h>
#include <linux/fb.h> #include <linux/fb.h>
#include <linux/selection.h>
#include <linux/console.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/nvram.h> #include <linux/nvram.h>
#include <linux/kd.h>
#include <linux/vt_kern.h>
#include <asm/io.h> #include <asm/io.h>
#include <linux/timer.h> #include <linux/timer.h>
#include <linux/spinlock.h>
#include <linux/kd.h>
#include <linux/console.h>
#include <linux/selection.h>
#include <linux/vt_kern.h>
#ifdef CONFIG_MTRR #ifdef CONFIG_MTRR
#include <asm/mtrr.h> #include <asm/mtrr.h>
#endif #endif
#include <video/tdfx.h>
#include <video/fbcon.h> #include <video/fbcon.h>
#include <video/fbcon-cfb8.h>
#include <video/fbcon-cfb16.h>
#include <video/fbcon-cfb24.h>
#include <video/fbcon-cfb32.h>
#include <linux/spinlock.h>
#ifndef PCI_DEVICE_ID_3DFX_VOODOO5 #ifndef PCI_DEVICE_ID_3DFX_VOODOO5
#define PCI_DEVICE_ID_3DFX_VOODOO5 0x0009 #define PCI_DEVICE_ID_3DFX_VOODOO5 0x0009
#endif #endif
/* membase0 register offsets */
#define STATUS 0x00
#define PCIINIT0 0x04
#define SIPMONITOR 0x08
#define LFBMEMORYCONFIG 0x0c
#define MISCINIT0 0x10
#define MISCINIT1 0x14
#define DRAMINIT0 0x18
#define DRAMINIT1 0x1c
#define AGPINIT 0x20
#define TMUGBEINIT 0x24
#define VGAINIT0 0x28
#define VGAINIT1 0x2c
#define DRAMCOMMAND 0x30
#define DRAMDATA 0x34
/* reserved 0x38 */
/* reserved 0x3c */
#define PLLCTRL0 0x40
#define PLLCTRL1 0x44
#define PLLCTRL2 0x48
#define DACMODE 0x4c
#define DACADDR 0x50
#define DACDATA 0x54
#define RGBMAXDELTA 0x58
#define VIDPROCCFG 0x5c
#define HWCURPATADDR 0x60
#define HWCURLOC 0x64
#define HWCURC0 0x68
#define HWCURC1 0x6c
#define VIDINFORMAT 0x70
#define VIDINSTATUS 0x74
#define VIDSERPARPORT 0x78
#define VIDINXDELTA 0x7c
#define VIDININITERR 0x80
#define VIDINYDELTA 0x84
#define VIDPIXBUFTHOLD 0x88
#define VIDCHRMIN 0x8c
#define VIDCHRMAX 0x90
#define VIDCURLIN 0x94
#define VIDSCREENSIZE 0x98
#define VIDOVRSTARTCRD 0x9c
#define VIDOVRENDCRD 0xa0
#define VIDOVRDUDX 0xa4
#define VIDOVRDUDXOFF 0xa8
#define VIDOVRDVDY 0xac
/* ... */
#define VIDOVRDVDYOFF 0xe0
#define VIDDESKSTART 0xe4
#define VIDDESKSTRIDE 0xe8
#define VIDINADDR0 0xec
#define VIDINADDR1 0xf0
#define VIDINADDR2 0xf4
#define VIDINSTRIDE 0xf8
#define VIDCUROVRSTART 0xfc
#define INTCTRL (0x00100000 + 0x04)
#define CLIP0MIN (0x00100000 + 0x08)
#define CLIP0MAX (0x00100000 + 0x0c)
#define DSTBASE (0x00100000 + 0x10)
#define DSTFORMAT (0x00100000 + 0x14)
#define SRCBASE (0x00100000 + 0x34)
#define COMMANDEXTRA_2D (0x00100000 + 0x38)
#define CLIP1MIN (0x00100000 + 0x4c)
#define CLIP1MAX (0x00100000 + 0x50)
#define SRCFORMAT (0x00100000 + 0x54)
#define SRCSIZE (0x00100000 + 0x58)
#define SRCXY (0x00100000 + 0x5c)
#define COLORBACK (0x00100000 + 0x60)
#define COLORFORE (0x00100000 + 0x64)
#define DSTSIZE (0x00100000 + 0x68)
#define DSTXY (0x00100000 + 0x6c)
#define COMMAND_2D (0x00100000 + 0x70)
#define LAUNCH_2D (0x00100000 + 0x80)
#define COMMAND_3D (0x00200000 + 0x120)
/* register bitfields (not all, only as needed) */
#define BIT(x) (1UL << (x))
/* COMMAND_2D reg. values */
#define TDFX_ROP_COPY 0xcc // src
#define TDFX_ROP_INVERT 0x55 // NOT dst
#define TDFX_ROP_XOR 0x66 // src XOR dst
#define AUTOINC_DSTX BIT(10)
#define AUTOINC_DSTY BIT(11)
#define COMMAND_2D_FILLRECT 0x05
#define COMMAND_2D_S2S_BITBLT 0x01 // screen to screen
#define COMMAND_2D_H2S_BITBLT 0x03 // host to screen
#define COMMAND_3D_NOP 0x00
#define STATUS_RETRACE BIT(6)
#define STATUS_BUSY BIT(9)
#define MISCINIT1_CLUT_INV BIT(0)
#define MISCINIT1_2DBLOCK_DIS BIT(15)
#define DRAMINIT0_SGRAM_NUM BIT(26)
#define DRAMINIT0_SGRAM_TYPE BIT(27)
#define DRAMINIT1_MEM_SDRAM BIT(30)
#define VGAINIT0_VGA_DISABLE BIT(0)
#define VGAINIT0_EXT_TIMING BIT(1)
#define VGAINIT0_8BIT_DAC BIT(2)
#define VGAINIT0_EXT_ENABLE BIT(6)
#define VGAINIT0_WAKEUP_3C3 BIT(8)
#define VGAINIT0_LEGACY_DISABLE BIT(9)
#define VGAINIT0_ALT_READBACK BIT(10)
#define VGAINIT0_FAST_BLINK BIT(11)
#define VGAINIT0_EXTSHIFTOUT BIT(12)
#define VGAINIT0_DECODE_3C6 BIT(13)
#define VGAINIT0_SGRAM_HBLANK_DISABLE BIT(22)
#define VGAINIT1_MASK 0x1fffff
#define VIDCFG_VIDPROC_ENABLE BIT(0)
#define VIDCFG_CURS_X11 BIT(1)
#define VIDCFG_HALF_MODE BIT(4)
#define VIDCFG_DESK_ENABLE BIT(7)
#define VIDCFG_CLUT_BYPASS BIT(10)
#define VIDCFG_2X BIT(26)
#define VIDCFG_HWCURSOR_ENABLE BIT(27)
#define VIDCFG_PIXFMT_SHIFT 18
#define DACMODE_2X BIT(0)
/* VGA rubbish, need to change this for multihead support */
#define MISC_W 0x3c2
#define MISC_R 0x3cc
#define SEQ_I 0x3c4
#define SEQ_D 0x3c5
#define CRT_I 0x3d4
#define CRT_D 0x3d5
#define ATT_IW 0x3c0
#define IS1_R 0x3da
#define GRA_I 0x3ce
#define GRA_D 0x3cf
#ifndef FB_ACCEL_3DFX_BANSHEE
#define FB_ACCEL_3DFX_BANSHEE 31
#endif
#define TDFXF_HSYNC_ACT_HIGH 0x01 #define TDFXF_HSYNC_ACT_HIGH 0x01
#define TDFXF_HSYNC_ACT_LOW 0x02 #define TDFXF_HSYNC_ACT_LOW 0x02
#define TDFXF_VSYNC_ACT_HIGH 0x04 #define TDFXF_VSYNC_ACT_HIGH 0x04
...@@ -249,46 +109,10 @@ ...@@ -249,46 +109,10 @@
#define DPRINTK(a,b...) #define DPRINTK(a,b...)
#endif #endif
#define PICOS2KHZ(a) (1000000000UL/(a))
#define KHZ2PICOS(a) (1000000000UL/(a))
#define BANSHEE_MAX_PIXCLOCK 270000.0 #define BANSHEE_MAX_PIXCLOCK 270000.0
#define VOODOO3_MAX_PIXCLOCK 300000.0 #define VOODOO3_MAX_PIXCLOCK 300000.0
#define VOODOO5_MAX_PIXCLOCK 350000.0 #define VOODOO5_MAX_PIXCLOCK 350000.0
struct banshee_reg {
/* VGA rubbish */
unsigned char att[21];
unsigned char crt[25];
unsigned char gra[ 9];
unsigned char misc[1];
unsigned char seq[ 5];
/* Banshee extensions */
unsigned char ext[2];
unsigned long vidcfg;
unsigned long vidpll;
unsigned long mempll;
unsigned long gfxpll;
unsigned long dacmode;
unsigned long vgainit0;
unsigned long vgainit1;
unsigned long screensize;
unsigned long stride;
unsigned long cursloc;
unsigned long curspataddr;
unsigned long cursc0;
unsigned long cursc1;
unsigned long startaddr;
unsigned long clip0min;
unsigned long clip0max;
unsigned long clip1min;
unsigned long clip1max;
unsigned long srcbase;
unsigned long dstbase;
unsigned long miscinit0;
};
struct tdfxfb_par { struct tdfxfb_par {
u32 pixclock; u32 pixclock;
...@@ -331,7 +155,9 @@ struct fb_info_tdfx { ...@@ -331,7 +155,9 @@ struct fb_info_tdfx {
unsigned long bufbase_size; unsigned long bufbase_size;
unsigned long iobase; unsigned long iobase;
struct { unsigned red, green, blue, pad; } palette[256]; struct {
unsigned red, green, blue, pad;
} palette[256];
struct tdfxfb_par default_par; struct tdfxfb_par default_par;
struct tdfxfb_par current_par; struct tdfxfb_par current_par;
struct display disp; struct display disp;
...@@ -351,9 +177,9 @@ struct fb_info_tdfx { ...@@ -351,9 +177,9 @@ struct fb_info_tdfx {
struct { struct {
int type; int type;
int state; int state;
int w,u,d; int w, u, d;
int x,y,redraw; int x, y, redraw;
unsigned long enable,disable; unsigned long enable, disable;
unsigned long cursorimage; unsigned long cursorimage;
struct timer_list timer; struct timer_list timer;
} cursor; } cursor;
...@@ -367,152 +193,136 @@ struct fb_info_tdfx { ...@@ -367,152 +193,136 @@ struct fb_info_tdfx {
/* /*
* Frame buffer device API * Frame buffer device API
*/ */
static int tdfxfb_get_fix(struct fb_fix_screeninfo* fix, static int tdfxfb_get_fix(struct fb_fix_screeninfo *fix,
int con, int con, struct fb_info *fb);
struct fb_info* fb); static int tdfxfb_get_var(struct fb_var_screeninfo *var,
static int tdfxfb_get_var(struct fb_var_screeninfo* var, int con, struct fb_info *fb);
int con, static int tdfxfb_set_var(struct fb_var_screeninfo *var,
struct fb_info* fb); int con, struct fb_info *fb);
static int tdfxfb_set_var(struct fb_var_screeninfo* var,
int con,
struct fb_info* fb);
static int tdfxfb_setcolreg(u_int regno, static int tdfxfb_setcolreg(u_int regno,
u_int red, u_int red,
u_int green, u_int green,
u_int blue, u_int blue, u_int transp, struct fb_info *fb);
u_int transp, static int tdfxfb_pan_display(struct fb_var_screeninfo *var,
struct fb_info* fb); int con, struct fb_info *fb);
static int tdfxfb_pan_display(struct fb_var_screeninfo* var,
int con,
struct fb_info* fb);
static int tdfxfb_get_cmap(struct fb_cmap *cmap, static int tdfxfb_get_cmap(struct fb_cmap *cmap,
int kspc, int kspc, int con, struct fb_info *info);
int con, static int tdfxfb_set_cmap(struct fb_cmap *cmap,
struct fb_info* info); int kspc, int con, struct fb_info *info);
static int tdfxfb_set_cmap(struct fb_cmap* cmap,
int kspc,
int con,
struct fb_info* info);
/* /*
* Interface to the low level console driver * Interface to the low level console driver
*/ */
static int tdfxfb_switch_con(int con, static int tdfxfb_switch_con(int con, struct fb_info *fb);
struct fb_info* fb); static int tdfxfb_updatevar(int con, struct fb_info *fb);
static int tdfxfb_updatevar(int con, static int tdfxfb_blank(int blank, struct fb_info *fb);
struct fb_info* fb);
static int tdfxfb_blank(int blank,
struct fb_info* fb);
/* /*
* Internal routines * Internal routines
*/ */
static void tdfxfb_set_par(const struct tdfxfb_par* par, static void tdfxfb_set_par(const struct tdfxfb_par *par,
struct fb_info_tdfx* struct fb_info_tdfx *info);
info);
static int tdfxfb_decode_var(const struct fb_var_screeninfo *var, static int tdfxfb_decode_var(const struct fb_var_screeninfo *var,
struct tdfxfb_par *par, struct tdfxfb_par *par,
const struct fb_info_tdfx *info); const struct fb_info_tdfx *info);
static int tdfxfb_encode_var(struct fb_var_screeninfo* var, static int tdfxfb_encode_var(struct fb_var_screeninfo *var,
const struct tdfxfb_par* par, const struct tdfxfb_par *par,
const struct fb_info_tdfx* info); const struct fb_info_tdfx *info);
static int tdfxfb_encode_fix(struct fb_fix_screeninfo* fix, static int tdfxfb_encode_fix(struct fb_fix_screeninfo *fix,
const struct tdfxfb_par* par, const struct tdfxfb_par *par,
const struct fb_info_tdfx* info); const struct fb_info_tdfx *info);
static void tdfxfb_set_dispsw(struct display* disp, static void tdfxfb_set_dispsw(struct display *disp,
struct fb_info_tdfx* info, struct fb_info_tdfx *info,
int bpp, int bpp, int accel);
int accel);
static int tdfxfb_getcolreg(u_int regno, static int tdfxfb_getcolreg(u_int regno,
u_int* red, u_int * red,
u_int* green, u_int * green,
u_int* blue, u_int * blue,
u_int* transp, u_int * transp, struct fb_info *fb);
struct fb_info* fb);
static void tdfxfb_hwcursor_init(void); static void tdfxfb_hwcursor_init(void);
static void tdfxfb_createcursorshape(struct display* p); static void tdfxfb_createcursorshape(struct display *p);
static void tdfxfb_createcursor(struct display * p); static void tdfxfb_createcursor(struct display *p);
/* /*
* do_xxx: Hardware-specific functions * do_xxx: Hardware-specific functions
*/ */
static void do_pan_var(struct fb_var_screeninfo* var, struct fb_info_tdfx *i); static void do_pan_var(struct fb_var_screeninfo *var,
struct fb_info_tdfx *i);
static void do_flashcursor(unsigned long ptr); static void do_flashcursor(unsigned long ptr);
static void do_bitblt(u32 curx, u32 cury, u32 dstx,u32 dsty, static void do_bitblt(u32 curx, u32 cury, u32 dstx, u32 dsty,
u32 width, u32 height,u32 stride,u32 bpp); u32 width, u32 height, u32 stride, u32 bpp);
static void do_fillrect(u32 x, u32 y, u32 w,u32 h, static void do_fillrect(u32 x, u32 y, u32 w, u32 h,
u32 color,u32 stride,u32 bpp,u32 rop); u32 color, u32 stride, u32 bpp, u32 rop);
static void do_putc(u32 fgx, u32 bgx,struct display *p, static void do_putc(u32 fgx, u32 bgx, struct display *p,
int c, int yy,int xx); int c, int yy, int xx);
static void do_putcs(u32 fgx, u32 bgx,struct display *p, static void do_putcs(u32 fgx, u32 bgx, struct display *p,
const unsigned short *s,int count, int yy,int xx); const unsigned short *s, int count, int yy, int xx);
static u32 do_calc_pll(int freq, int* freq_out); static u32 do_calc_pll(int freq, int *freq_out);
static void do_write_regs(struct banshee_reg* reg); static void do_write_regs(struct banshee_reg *reg);
static unsigned long do_lfb_size(void); static unsigned long do_lfb_size(void);
/* /*
* Interface used by the world * Interface used by the world
*/ */
int tdfxfb_init(void); int tdfxfb_init(void);
void tdfxfb_setup(char *options, void tdfxfb_setup(char *options, int *ints);
int *ints);
/* /*
* PCI driver prototypes * PCI driver prototypes
*/ */
static int tdfxfb_probe(struct pci_dev *pdev, const struct pci_device_id *id); static int tdfxfb_probe(struct pci_dev *pdev,
const struct pci_device_id *id);
static void tdfxfb_remove(struct pci_dev *pdev); static void tdfxfb_remove(struct pci_dev *pdev);
static struct fb_ops tdfxfb_ops = { static struct fb_ops tdfxfb_ops = {
owner: THIS_MODULE, owner:THIS_MODULE,
fb_get_fix: tdfxfb_get_fix, fb_get_fix:tdfxfb_get_fix,
fb_get_var: tdfxfb_get_var, fb_get_var:tdfxfb_get_var,
fb_set_var: tdfxfb_set_var, fb_set_var:tdfxfb_set_var,
fb_get_cmap: tdfxfb_get_cmap, fb_get_cmap:tdfxfb_get_cmap,
fb_set_cmap: tdfxfb_set_cmap, fb_set_cmap:tdfxfb_set_cmap,
fb_setcolreg: tdfxfb_setcolreg, fb_setcolreg:tdfxfb_setcolreg,
fb_pan_display: tdfxfb_pan_display, fb_pan_display:tdfxfb_pan_display,
fb_blank: tdfxfb_blank, fb_blank:tdfxfb_blank,
}; };
static struct pci_device_id tdfxfb_id_table[] __devinitdata = { static struct pci_device_id tdfxfb_id_table[] __devinitdata = {
{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_BANSHEE, {PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_BANSHEE,
PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
0xff0000, 0 }, 0xff0000, 0},
{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO3, {PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO3,
PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
0xff0000, 0 }, 0xff0000, 0},
{ PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO5, {PCI_VENDOR_ID_3DFX, PCI_DEVICE_ID_3DFX_VOODOO5,
PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
0xff0000, 0 }, 0xff0000, 0},
{ 0, } {0,}
}; };
static struct pci_driver tdfxfb_driver = { static struct pci_driver tdfxfb_driver = {
name: "tdfxfb", name:"tdfxfb",
id_table: tdfxfb_id_table, id_table:tdfxfb_id_table,
probe: tdfxfb_probe, probe:tdfxfb_probe,
remove: __devexit_p(tdfxfb_remove), remove:__devexit_p(tdfxfb_remove),
}; };
MODULE_DEVICE_TABLE(pci, tdfxfb_id_table); MODULE_DEVICE_TABLE(pci, tdfxfb_id_table);
struct mode { struct mode {
char* name; char *name;
struct fb_var_screeninfo var; struct fb_var_screeninfo var;
} mode; } mode;
/* 2.3.x kernels have a fb mode database, so supply only one backup default */ /* 2.3.x kernels have a fb mode database, so supply only one backup default */
struct mode default_mode[] = { struct mode default_mode[] = {
{ "640x480-8@60", /* @ 60 Hz */ {"640x480-8@60", /* @ 60 Hz */
{ {
640, 480, 640, 1024, 0, 0, 8, 0, 640, 480, 640, 1024, 0, 0, 8, 0,
{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0}, {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
0, FB_ACTIVATE_NOW, -1, -1, FB_ACCELF_TEXT, 0, FB_ACTIVATE_NOW, -1, -1, FB_ACCELF_TEXT,
39722, 40, 24, 32, 11, 96, 2, 39722, 40, 24, 32, 11, 96, 2,
0, FB_VMODE_NONINTERLACED 0, FB_VMODE_NONINTERLACED}
}
} }
}; };
...@@ -534,74 +344,113 @@ static char *mode_option __initdata = NULL; ...@@ -534,74 +344,113 @@ static char *mode_option __initdata = NULL;
* ------------------------------------------------------------------------- */ * ------------------------------------------------------------------------- */
#ifdef VGA_REG_IO #ifdef VGA_REG_IO
static inline u8 vga_inb(u32 reg) { return inb(reg); } static inline u8 vga_inb(u32 reg)
static inline u16 vga_inw(u32 reg) { return inw(reg); } {
static inline u16 vga_inl(u32 reg) { return inl(reg); } return inb(reg);
}
static inline u16 vga_inw(u32 reg)
{
return inw(reg);
}
static inline u16 vga_inl(u32 reg)
{
return inl(reg);
}
static inline void vga_outb(u32 reg, u8 val) { outb(val, reg); } static inline void vga_outb(u32 reg, u8 val)
static inline void vga_outw(u32 reg, u16 val) { outw(val, reg); } {
static inline void vga_outl(u32 reg, u32 val) { outl(val, reg); } outb(val, reg);
}
static inline void vga_outw(u32 reg, u16 val)
{
outw(val, reg);
}
static inline void vga_outl(u32 reg, u32 val)
{
outl(val, reg);
}
#else #else
static inline u8 vga_inb(u32 reg) { static inline u8 vga_inb(u32 reg)
{
return inb(fb_info.iobase + reg - 0x300); return inb(fb_info.iobase + reg - 0x300);
} }
static inline u16 vga_inw(u32 reg) { static inline u16 vga_inw(u32 reg)
{
return inw(fb_info.iobase + reg - 0x300); return inw(fb_info.iobase + reg - 0x300);
} }
static inline u16 vga_inl(u32 reg) { static inline u16 vga_inl(u32 reg)
{
return inl(fb_info.iobase + reg - 0x300); return inl(fb_info.iobase + reg - 0x300);
} }
static inline void vga_outb(u32 reg, u8 val) { static inline void vga_outb(u32 reg, u8 val)
{
outb(val, fb_info.iobase + reg - 0x300); outb(val, fb_info.iobase + reg - 0x300);
} }
static inline void vga_outw(u32 reg, u16 val) { static inline void vga_outw(u32 reg, u16 val)
{
outw(val, fb_info.iobase + reg - 0x300); outw(val, fb_info.iobase + reg - 0x300);
} }
static inline void vga_outl(u32 reg, u32 val) { static inline void vga_outl(u32 reg, u32 val)
{
outl(val, fb_info.iobase + reg - 0x300); outl(val, fb_info.iobase + reg - 0x300);
} }
#endif #endif
static inline void gra_outb(u32 idx, u8 val) { static inline void gra_outb(u32 idx, u8 val)
vga_outb(GRA_I, idx); vga_outb(GRA_D, val); {
vga_outb(GRA_I, idx);
vga_outb(GRA_D, val);
} }
static inline u8 gra_inb(u32 idx) { static inline u8 gra_inb(u32 idx)
vga_outb(GRA_I, idx); return vga_inb(GRA_D); {
vga_outb(GRA_I, idx);
return vga_inb(GRA_D);
} }
static inline void seq_outb(u32 idx, u8 val) { static inline void seq_outb(u32 idx, u8 val)
vga_outb(SEQ_I, idx); vga_outb(SEQ_D, val); {
vga_outb(SEQ_I, idx);
vga_outb(SEQ_D, val);
} }
static inline u8 seq_inb(u32 idx) { static inline u8 seq_inb(u32 idx)
vga_outb(SEQ_I, idx); return vga_inb(SEQ_D); {
vga_outb(SEQ_I, idx);
return vga_inb(SEQ_D);
} }
static inline void crt_outb(u32 idx, u8 val) { static inline void crt_outb(u32 idx, u8 val)
vga_outb(CRT_I, idx); vga_outb(CRT_D, val); {
vga_outb(CRT_I, idx);
vga_outb(CRT_D, val);
} }
static inline u8 crt_inb(u32 idx) { static inline u8 crt_inb(u32 idx)
vga_outb(CRT_I, idx); return vga_inb(CRT_D); {
vga_outb(CRT_I, idx);
return vga_inb(CRT_D);
} }
static inline void att_outb(u32 idx, u8 val) { static inline void att_outb(u32 idx, u8 val)
{
unsigned char tmp; unsigned char tmp;
tmp = vga_inb(IS1_R); tmp = vga_inb(IS1_R);
vga_outb(ATT_IW, idx); vga_outb(ATT_IW, idx);
vga_outb(ATT_IW, val); vga_outb(ATT_IW, val);
} }
static inline u8 att_inb(u32 idx) { static inline u8 att_inb(u32 idx)
{
unsigned char tmp; unsigned char tmp;
tmp = vga_inb(IS1_R); tmp = vga_inb(IS1_R);
vga_outb(ATT_IW, idx); vga_outb(ATT_IW, idx);
return vga_inb(ATT_IW); return vga_inb(ATT_IW);
} }
static inline void vga_disable_video(void) { static inline void vga_disable_video(void)
{
unsigned char s; unsigned char s;
s = seq_inb(0x01) | 0x20; s = seq_inb(0x01) | 0x20;
seq_outb(0x00, 0x01); seq_outb(0x00, 0x01);
...@@ -609,7 +458,8 @@ static inline void vga_disable_video(void) { ...@@ -609,7 +458,8 @@ static inline void vga_disable_video(void) {
seq_outb(0x00, 0x03); seq_outb(0x00, 0x03);
} }
static inline void vga_enable_video(void) { static inline void vga_enable_video(void)
{
unsigned char s; unsigned char s;
s = seq_inb(0x01) & 0xdf; s = seq_inb(0x01) & 0xdf;
seq_outb(0x00, 0x01); seq_outb(0x00, 0x01);
...@@ -617,52 +467,65 @@ static inline void vga_enable_video(void) { ...@@ -617,52 +467,65 @@ static inline void vga_enable_video(void) {
seq_outb(0x00, 0x03); seq_outb(0x00, 0x03);
} }
static inline void vga_disable_palette(void) { static inline void vga_disable_palette(void)
{
vga_inb(IS1_R); vga_inb(IS1_R);
vga_outb(ATT_IW, 0x00); vga_outb(ATT_IW, 0x00);
} }
static inline void vga_enable_palette(void) { static inline void vga_enable_palette(void)
{
vga_inb(IS1_R); vga_inb(IS1_R);
vga_outb(ATT_IW, 0x20); vga_outb(ATT_IW, 0x20);
} }
static inline u32 tdfx_inl(unsigned int reg) { static inline u32 tdfx_inl(unsigned int reg)
{
return readl(fb_info.regbase_virt + reg); return readl(fb_info.regbase_virt + reg);
} }
static inline void tdfx_outl(unsigned int reg, u32 val) { static inline void tdfx_outl(unsigned int reg, u32 val)
{
writel(val, fb_info.regbase_virt + reg); writel(val, fb_info.regbase_virt + reg);
} }
static inline void banshee_make_room(int size) { static inline void banshee_make_room(int size)
while((tdfx_inl(STATUS) & 0x1f) < size); {
while ((tdfx_inl(STATUS) & 0x1f) < size);
} }
static inline void banshee_wait_idle(void) { static inline void banshee_wait_idle(void)
{
int i = 0; int i = 0;
banshee_make_room(1); banshee_make_room(1);
tdfx_outl(COMMAND_3D, COMMAND_3D_NOP); tdfx_outl(COMMAND_3D, COMMAND_3D_NOP);
while(1) { while (1) {
i = (tdfx_inl(STATUS) & STATUS_BUSY) ? 0 : i + 1; i = (tdfx_inl(STATUS) & STATUS_BUSY) ? 0 : i + 1;
if(i == 3) break; if (i == 3)
break;
} }
} }
/* /*
* Set the color of a palette entry in 8bpp mode * Set the color of a palette entry in 8bpp mode
*/ */
static inline void do_setpalentry(unsigned regno, u32 c) { static inline void do_setpalentry(unsigned regno, u32 c)
banshee_make_room(2); tdfx_outl(DACADDR, regno); tdfx_outl(DACDATA, c); } {
banshee_make_room(2);
tdfx_outl(DACADDR, regno);
tdfx_outl(DACDATA, c);
}
/* /*
* Set the starting position of the visible screen to var->yoffset * Set the starting position of the visible screen to var->yoffset
*/ */
static void do_pan_var(struct fb_var_screeninfo* var, struct fb_info_tdfx *i) static void do_pan_var(struct fb_var_screeninfo *var,
struct fb_info_tdfx *i)
{ {
u32 addr; u32 addr;
addr = var->yoffset*i->current_par.lpitch; addr = var->yoffset * i->current_par.lpitch;
banshee_make_room(1); banshee_make_room(1);
tdfx_outl(VIDDESKSTART, addr); tdfx_outl(VIDDESKSTART, addr);
} }
...@@ -672,13 +535,14 @@ static void do_pan_var(struct fb_var_screeninfo* var, struct fb_info_tdfx *i) ...@@ -672,13 +535,14 @@ static void do_pan_var(struct fb_var_screeninfo* var, struct fb_info_tdfx *i)
*/ */
static void do_flashcursor(unsigned long ptr) static void do_flashcursor(unsigned long ptr)
{ {
struct fb_info_tdfx* i=(struct fb_info_tdfx *)ptr; struct fb_info_tdfx *i = (struct fb_info_tdfx *) ptr;
unsigned long flags; unsigned long flags;
spin_lock_irqsave(&i->DAClock, flags); spin_lock_irqsave(&i->DAClock, flags);
banshee_make_room(1); banshee_make_room(1);
tdfx_outl( VIDPROCCFG, tdfx_inl(VIDPROCCFG) ^ VIDCFG_HWCURSOR_ENABLE ); tdfx_outl(VIDPROCCFG,
i->cursor.timer.expires=jiffies+HZ/2; tdfx_inl(VIDPROCCFG) ^ VIDCFG_HWCURSOR_ENABLE);
i->cursor.timer.expires = jiffies + HZ / 2;
add_timer(&i->cursor.timer); add_timer(&i->cursor.timer);
spin_unlock_irqrestore(&i->DAClock, flags); spin_unlock_irqrestore(&i->DAClock, flags);
} }
...@@ -687,9 +551,10 @@ static void do_flashcursor(unsigned long ptr) ...@@ -687,9 +551,10 @@ static void do_flashcursor(unsigned long ptr)
* FillRect 2D command (solidfill or invert (via ROP_XOR)) * FillRect 2D command (solidfill or invert (via ROP_XOR))
*/ */
static void do_fillrect(u32 x, u32 y, u32 w, u32 h, static void do_fillrect(u32 x, u32 y, u32 w, u32 h,
u32 color, u32 stride, u32 bpp, u32 rop) { u32 color, u32 stride, u32 bpp, u32 rop)
{
u32 fmt= stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); u32 fmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
banshee_make_room(5); banshee_make_room(5);
tdfx_outl(DSTFORMAT, fmt); tdfx_outl(DSTFORMAT, fmt);
...@@ -707,26 +572,23 @@ static void do_fillrect(u32 x, u32 y, u32 w, u32 h, ...@@ -707,26 +572,23 @@ static void do_fillrect(u32 x, u32 y, u32 w, u32 h,
static void do_bitblt(u32 curx, static void do_bitblt(u32 curx,
u32 cury, u32 cury,
u32 dstx, u32 dstx,
u32 dsty, u32 dsty, u32 width, u32 height, u32 stride, u32 bpp)
u32 width, {
u32 height,
u32 stride,
u32 bpp) {
u32 blitcmd = COMMAND_2D_S2S_BITBLT | (TDFX_ROP_COPY << 24); u32 blitcmd = COMMAND_2D_S2S_BITBLT | (TDFX_ROP_COPY << 24);
u32 fmt= stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); u32 fmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
if (curx <= dstx) { if (curx <= dstx) {
//-X //-X
blitcmd |= BIT(14); blitcmd |= BIT(14);
curx += width-1; curx += width - 1;
dstx += width-1; dstx += width - 1;
} }
if (cury <= dsty) { if (cury <= dsty) {
//-Y //-Y
blitcmd |= BIT(15); blitcmd |= BIT(15);
cury += height-1; cury += height - 1;
dsty += height-1; dsty += height - 1;
} }
banshee_make_room(6); banshee_make_room(6);
...@@ -741,56 +603,67 @@ static void do_bitblt(u32 curx, ...@@ -741,56 +603,67 @@ static void do_bitblt(u32 curx,
} }
static void do_putc(u32 fgx, u32 bgx, static void do_putc(u32 fgx, u32 bgx,
struct display *p, struct display *p, int c, int yy, int xx)
int c, int yy,int xx)
{ {
int i; int i;
int stride=fb_info.current_par.lpitch; int stride = fb_info.current_par.lpitch;
u32 bpp=fb_info.current_par.bpp; u32 bpp = fb_info.current_par.bpp;
int fw=(fontwidth(p)+7)>>3; int fw = (fontwidth(p) + 7) >> 3;
u8 *chardata=p->fontdata+(c&p->charmask)*fontheight(p)*fw; u8 *chardata =
u32 fmt= stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); p->fontdata + (c & p->charmask) * fontheight(p) * fw;
u32 fmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
xx *= fontwidth(p); xx *= fontwidth(p);
yy *= fontheight(p); yy *= fontheight(p);
banshee_make_room(8+((fontheight(p)*fw+3)>>2) ); banshee_make_room(8 + ((fontheight(p) * fw + 3) >> 2));
tdfx_outl(COLORFORE, fgx); tdfx_outl(COLORFORE, fgx);
tdfx_outl(COLORBACK, bgx); tdfx_outl(COLORBACK, bgx);
tdfx_outl(SRCXY, 0); tdfx_outl(SRCXY, 0);
tdfx_outl(DSTXY, xx | (yy << 16)); tdfx_outl(DSTXY, xx | (yy << 16));
tdfx_outl(COMMAND_2D, COMMAND_2D_H2S_BITBLT | (TDFX_ROP_COPY << 24)); tdfx_outl(COMMAND_2D,
COMMAND_2D_H2S_BITBLT | (TDFX_ROP_COPY << 24));
tdfx_outl(SRCFORMAT, 0x400000); tdfx_outl(SRCFORMAT, 0x400000);
tdfx_outl(DSTFORMAT, fmt); tdfx_outl(DSTFORMAT, fmt);
tdfx_outl(DSTSIZE, fontwidth(p) | (fontheight(p) << 16)); tdfx_outl(DSTSIZE, fontwidth(p) | (fontheight(p) << 16));
i=fontheight(p); i = fontheight(p);
switch (fw) { switch (fw) {
case 1: case 1:
while (i>=4) { while (i >= 4) {
tdfx_outl(LAUNCH_2D,*(u32*)chardata); tdfx_outl(LAUNCH_2D, *(u32 *) chardata);
chardata+=4; chardata += 4;
i-=4; i -= 4;
} }
switch (i) { switch (i) {
case 0: break; case 0:
case 1: tdfx_outl(LAUNCH_2D,*chardata); break; break;
case 2: tdfx_outl(LAUNCH_2D,*(u16*)chardata); break; case 1:
case 3: tdfx_outl(LAUNCH_2D,*(u16*)chardata | ((chardata[3]) << 24)); break; tdfx_outl(LAUNCH_2D, *chardata);
break;
case 2:
tdfx_outl(LAUNCH_2D, *(u16 *) chardata);
break;
case 3:
tdfx_outl(LAUNCH_2D,
*(u16 *) chardata | ((chardata[3]) <<
24));
break;
} }
break; break;
case 2: case 2:
while (i>=2) { while (i >= 2) {
tdfx_outl(LAUNCH_2D,*(u32*)chardata); tdfx_outl(LAUNCH_2D, *(u32 *) chardata);
chardata+=4; chardata += 4;
i-=2; i -= 2;
} }
if (i) tdfx_outl(LAUNCH_2D,*(u16*)chardata); if (i)
tdfx_outl(LAUNCH_2D, *(u16 *) chardata);
break; break;
default: default:
// Is there a font with width more that 16 pixels ? // Is there a font with width more that 16 pixels ?
for (i=fontheight(p);i>0;i--) { for (i = fontheight(p); i > 0; i--) {
tdfx_outl(LAUNCH_2D,*(u32*)chardata); tdfx_outl(LAUNCH_2D, *(u32 *) chardata);
chardata+=4; chardata += 4;
} }
break; break;
} }
...@@ -799,20 +672,19 @@ static void do_putc(u32 fgx, u32 bgx, ...@@ -799,20 +672,19 @@ static void do_putc(u32 fgx, u32 bgx,
static void do_putcs(u32 fgx, u32 bgx, static void do_putcs(u32 fgx, u32 bgx,
struct display *p, struct display *p,
const unsigned short *s, const unsigned short *s, int count, int yy, int xx)
int count, int yy,int xx)
{ {
int i; int i;
int stride=fb_info.current_par.lpitch; int stride = fb_info.current_par.lpitch;
u32 bpp=fb_info.current_par.bpp; u32 bpp = fb_info.current_par.bpp;
int fw=(fontwidth(p)+7)>>3; int fw = (fontwidth(p) + 7) >> 3;
int w=fontwidth(p); int w = fontwidth(p);
int h=fontheight(p); int h = fontheight(p);
int regsneed=1+((h*fw+3)>>2); int regsneed = 1 + ((h * fw + 3) >> 2);
u32 fmt= stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); u32 fmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
xx *= w; xx *= w;
yy = (yy*h) << 16; yy = (yy * h) << 16;
banshee_make_room(8); banshee_make_room(8);
tdfx_outl(COMMAND_3D, COMMAND_3D_NOP); tdfx_outl(COMMAND_3D, COMMAND_3D_NOP);
...@@ -822,43 +694,55 @@ static void do_putcs(u32 fgx, u32 bgx, ...@@ -822,43 +694,55 @@ static void do_putcs(u32 fgx, u32 bgx,
tdfx_outl(DSTFORMAT, fmt); tdfx_outl(DSTFORMAT, fmt);
tdfx_outl(DSTSIZE, w | (h << 16)); tdfx_outl(DSTSIZE, w | (h << 16));
tdfx_outl(SRCXY, 0); tdfx_outl(SRCXY, 0);
tdfx_outl(COMMAND_2D, COMMAND_2D_H2S_BITBLT | (TDFX_ROP_COPY << 24)); tdfx_outl(COMMAND_2D,
COMMAND_2D_H2S_BITBLT | (TDFX_ROP_COPY << 24));
while (count--) { while (count--) {
u8 *chardata=p->fontdata+(scr_readw(s++) & p->charmask)*h*fw; u8 *chardata =
p->fontdata + (scr_readw(s++) & p->charmask) * h * fw;
banshee_make_room(regsneed); banshee_make_room(regsneed);
tdfx_outl(DSTXY, xx | yy); tdfx_outl(DSTXY, xx | yy);
xx+=w; xx += w;
i=h; i = h;
switch (fw) { switch (fw) {
case 1: case 1:
while (i>=4) { while (i >= 4) {
tdfx_outl(LAUNCH_2D,*(u32*)chardata); tdfx_outl(LAUNCH_2D, *(u32 *) chardata);
chardata+=4; chardata += 4;
i-=4; i -= 4;
} }
switch (i) { switch (i) {
case 0: break; case 0:
case 1: tdfx_outl(LAUNCH_2D,*chardata); break; break;
case 2: tdfx_outl(LAUNCH_2D,*(u16*)chardata); break; case 1:
case 3: tdfx_outl(LAUNCH_2D,*(u16*)chardata | ((chardata[3]) << 24)); break; tdfx_outl(LAUNCH_2D, *chardata);
break;
case 2:
tdfx_outl(LAUNCH_2D, *(u16 *) chardata);
break;
case 3:
tdfx_outl(LAUNCH_2D,
*(u16 *) chardata |
((chardata[3]) << 24));
break;
} }
break; break;
case 2: case 2:
while (i>=2) { while (i >= 2) {
tdfx_outl(LAUNCH_2D,*(u32*)chardata); tdfx_outl(LAUNCH_2D, *(u32 *) chardata);
chardata+=4; chardata += 4;
i-=2; i -= 2;
} }
if (i) tdfx_outl(LAUNCH_2D,*(u16*)chardata); if (i)
tdfx_outl(LAUNCH_2D, *(u16 *) chardata);
break; break;
default: default:
// Is there a font with width more that 16 pixels ? // Is there a font with width more that 16 pixels ?
for (;i>0;i--) { for (; i > 0; i--) {
tdfx_outl(LAUNCH_2D,*(u32*)chardata); tdfx_outl(LAUNCH_2D, *(u32 *) chardata);
chardata+=4; chardata += 4;
} }
break; break;
} }
...@@ -866,7 +750,8 @@ static void do_putcs(u32 fgx, u32 bgx, ...@@ -866,7 +750,8 @@ static void do_putcs(u32 fgx, u32 bgx,
banshee_wait_idle(); banshee_wait_idle();
} }
static u32 do_calc_pll(int freq, int* freq_out) { static u32 do_calc_pll(int freq, int *freq_out)
{
int m, n, k, best_m, best_n, best_k, f_cur, best_error; int m, n, k, best_m, best_n, best_k, f_cur, best_error;
int fref = 14318; int fref = 14318;
...@@ -874,12 +759,13 @@ static u32 do_calc_pll(int freq, int* freq_out) { ...@@ -874,12 +759,13 @@ static u32 do_calc_pll(int freq, int* freq_out) {
255*63*4 = 64260 iterations is silly */ 255*63*4 = 64260 iterations is silly */
best_error = freq; best_error = freq;
best_n = best_m = best_k = 0; best_n = best_m = best_k = 0;
for(n = 1; n < 256; n++) { for (n = 1; n < 256; n++) {
for(m = 1; m < 64; m++) { for (m = 1; m < 64; m++) {
for(k = 0; k < 4; k++) { for (k = 0; k < 4; k++) {
f_cur = fref*(n + 2)/(m + 2)/(1 << k); f_cur =
if(abs(f_cur - freq) < best_error) { fref * (n + 2) / (m + 2) / (1 << k);
best_error = abs(f_cur-freq); if (abs(f_cur - freq) < best_error) {
best_error = abs(f_cur - freq);
best_n = n; best_n = n;
best_m = m; best_m = m;
best_k = k; best_k = k;
...@@ -890,12 +776,13 @@ static u32 do_calc_pll(int freq, int* freq_out) { ...@@ -890,12 +776,13 @@ static u32 do_calc_pll(int freq, int* freq_out) {
n = best_n; n = best_n;
m = best_m; m = best_m;
k = best_k; k = best_k;
*freq_out = fref*(n + 2)/(m + 2)/(1 << k); *freq_out = fref * (n + 2) / (m + 2) / (1 << k);
return (n << 8) | (m << 2) | k; return (n << 8) | (m << 2) | k;
} }
static void do_write_regs(struct banshee_reg* reg) { static void do_write_regs(struct banshee_reg *reg)
{
int i; int i;
banshee_wait_idle(); banshee_wait_idle();
...@@ -915,16 +802,16 @@ static void do_write_regs(struct banshee_reg* reg) { ...@@ -915,16 +802,16 @@ static void do_write_regs(struct banshee_reg* reg) {
vga_outb(MISC_W, reg->misc[0x00] | 0x01); vga_outb(MISC_W, reg->misc[0x00] | 0x01);
for(i = 0; i < 5; i++) for (i = 0; i < 5; i++)
seq_outb(i, reg->seq[i]); seq_outb(i, reg->seq[i]);
for(i = 0; i < 25; i++) for (i = 0; i < 25; i++)
crt_outb(i, reg->crt[i]); crt_outb(i, reg->crt[i]);
for(i = 0; i < 9; i++) for (i = 0; i < 9; i++)
gra_outb(i, reg->gra[i]); gra_outb(i, reg->gra[i]);
for(i = 0; i < 21; i++) for (i = 0; i < 21; i++)
att_outb(i, reg->att[i]); att_outb(i, reg->att[i]);
crt_outb(0x1a, reg->ext[0]); crt_outb(0x1a, reg->ext[0]);
...@@ -965,7 +852,8 @@ static void do_write_regs(struct banshee_reg* reg) { ...@@ -965,7 +852,8 @@ static void do_write_regs(struct banshee_reg* reg) {
banshee_wait_idle(); banshee_wait_idle();
} }
static unsigned long do_lfb_size(void) { static unsigned long do_lfb_size(void)
{
u32 draminit0 = 0; u32 draminit0 = 0;
u32 draminit1 = 0; u32 draminit1 = 0;
u32 miscinit1 = 0; u32 miscinit1 = 0;
...@@ -981,8 +869,8 @@ static unsigned long do_lfb_size(void) { ...@@ -981,8 +869,8 @@ static unsigned long do_lfb_size(void) {
lfbsize = sgram_p ? lfbsize = sgram_p ?
(((draminit0 & DRAMINIT0_SGRAM_NUM) ? 2 : 1) * (((draminit0 & DRAMINIT0_SGRAM_NUM) ? 2 : 1) *
((draminit0 & DRAMINIT0_SGRAM_TYPE) ? 8 : 4) * 1024 * 1024) : ((draminit0 & DRAMINIT0_SGRAM_TYPE) ? 8 : 4) * 1024 *
16 * 1024 * 1024; 1024) : 16 * 1024 * 1024;
} else { } else {
/* Voodoo4/5 */ /* Voodoo4/5 */
u32 chips, psize, banks; u32 chips, psize, banks;
...@@ -1013,163 +901,153 @@ static unsigned long do_lfb_size(void) { ...@@ -1013,163 +901,153 @@ static unsigned long do_lfb_size(void) {
#define tdfx_cfb24_putcs tdfx_cfb32_putcs #define tdfx_cfb24_putcs tdfx_cfb32_putcs
#define tdfx_cfb24_clear tdfx_cfb32_clear #define tdfx_cfb24_clear tdfx_cfb32_clear
static void tdfx_cfbX_clear_margins(struct vc_data* conp, struct display* p, static void tdfx_cfbX_clear_margins(struct vc_data *conp,
int bottom_only) struct display *p, int bottom_only)
{ {
unsigned int cw=fontwidth(p); unsigned int cw = fontwidth(p);
unsigned int ch=fontheight(p); unsigned int ch = fontheight(p);
unsigned int rw=p->var.xres % cw; // it be in a non-standard mode or not? unsigned int rw = p->var.xres % cw; // it be in a non-standard mode or not?
unsigned int bh=p->var.yres % ch; unsigned int bh = p->var.yres % ch;
unsigned int rs=p->var.xres - rw; unsigned int rs = p->var.xres - rw;
unsigned int bs=p->var.yres - bh; unsigned int bs = p->var.yres - bh;
if (!bottom_only && rw) { if (!bottom_only && rw) {
do_fillrect( p->var.xoffset+rs, 0, do_fillrect(p->var.xoffset + rs, 0,
rw, p->var.yres_virtual, 0, rw, p->var.yres_virtual, 0,
fb_info.current_par.lpitch, fb_info.current_par.lpitch,
fb_info.current_par.bpp, TDFX_ROP_COPY); fb_info.current_par.bpp, TDFX_ROP_COPY);
} }
if (bh) { if (bh) {
do_fillrect( p->var.xoffset, p->var.yoffset+bs, do_fillrect(p->var.xoffset, p->var.yoffset + bs,
rs, bh, 0, rs, bh, 0,
fb_info.current_par.lpitch, fb_info.current_par.lpitch,
fb_info.current_par.bpp, TDFX_ROP_COPY); fb_info.current_par.bpp, TDFX_ROP_COPY);
} }
} }
static void tdfx_cfbX_bmove(struct display* p, static void tdfx_cfbX_bmove(struct display *p,
int sy, int sy,
int sx, int sx, int dy, int dx, int height, int width)
int dy,
int dx,
int height,
int width) {
do_bitblt(fontwidth(p)*sx,
fontheight(p)*sy,
fontwidth(p)*dx,
fontheight(p)*dy,
fontwidth(p)*width,
fontheight(p)*height,
fb_info.current_par.lpitch,
fb_info.current_par.bpp);
}
static void tdfx_cfb8_putc(struct vc_data* conp,
struct display* p,
int c, int yy,int xx)
{ {
u32 fgx,bgx; do_bitblt(fontwidth(p) * sx,
fgx=attr_fgcol(p, c); fontheight(p) * sy,
bgx=attr_bgcol(p, c); fontwidth(p) * dx,
do_putc( fgx,bgx,p,c,yy,xx ); fontheight(p) * dy,
fontwidth(p) * width,
fontheight(p) * height,
fb_info.current_par.lpitch, fb_info.current_par.bpp);
}
static void tdfx_cfb8_putc(struct vc_data *conp,
struct display *p, int c, int yy, int xx)
{
u32 fgx, bgx;
fgx = attr_fgcol(p, c);
bgx = attr_bgcol(p, c);
do_putc(fgx, bgx, p, c, yy, xx);
} }
static void tdfx_cfb16_putc(struct vc_data* conp, static void tdfx_cfb16_putc(struct vc_data *conp,
struct display* p, struct display *p, int c, int yy, int xx)
int c, int yy,int xx)
{ {
u32 fgx,bgx; u32 fgx, bgx;
fgx=((u16*)p->dispsw_data)[attr_fgcol(p,c)]; fgx = ((u16 *) p->dispsw_data)[attr_fgcol(p, c)];
bgx=((u16*)p->dispsw_data)[attr_bgcol(p,c)]; bgx = ((u16 *) p->dispsw_data)[attr_bgcol(p, c)];
do_putc( fgx,bgx,p,c,yy,xx ); do_putc(fgx, bgx, p, c, yy, xx);
} }
static void tdfx_cfb32_putc(struct vc_data* conp, static void tdfx_cfb32_putc(struct vc_data *conp,
struct display* p, struct display *p, int c, int yy, int xx)
int c, int yy,int xx)
{ {
u32 fgx,bgx; u32 fgx, bgx;
fgx=((u32*)p->dispsw_data)[attr_fgcol(p,c)]; fgx = ((u32 *) p->dispsw_data)[attr_fgcol(p, c)];
bgx=((u32*)p->dispsw_data)[attr_bgcol(p,c)]; bgx = ((u32 *) p->dispsw_data)[attr_bgcol(p, c)];
do_putc( fgx,bgx,p,c,yy,xx ); do_putc(fgx, bgx, p, c, yy, xx);
} }
static void tdfx_cfb8_putcs(struct vc_data* conp, static void tdfx_cfb8_putcs(struct vc_data *conp,
struct display* p, struct display *p,
const unsigned short *s,int count,int yy,int xx) const unsigned short *s, int count, int yy,
int xx)
{ {
u16 c = scr_readw(s); u16 c = scr_readw(s);
u32 fgx = attr_fgcol(p, c); u32 fgx = attr_fgcol(p, c);
u32 bgx = attr_bgcol(p, c); u32 bgx = attr_bgcol(p, c);
do_putcs( fgx,bgx,p,s,count,yy,xx ); do_putcs(fgx, bgx, p, s, count, yy, xx);
} }
static void tdfx_cfb16_putcs(struct vc_data* conp, static void tdfx_cfb16_putcs(struct vc_data *conp,
struct display* p, struct display *p,
const unsigned short *s,int count,int yy,int xx) const unsigned short *s, int count, int yy,
int xx)
{ {
u16 c = scr_readw(s); u16 c = scr_readw(s);
u32 fgx = ((u16*)p->dispsw_data)[attr_fgcol(p, c)]; u32 fgx = ((u16 *) p->dispsw_data)[attr_fgcol(p, c)];
u32 bgx = ((u16*)p->dispsw_data)[attr_bgcol(p, c)]; u32 bgx = ((u16 *) p->dispsw_data)[attr_bgcol(p, c)];
do_putcs( fgx,bgx,p,s,count,yy,xx ); do_putcs(fgx, bgx, p, s, count, yy, xx);
} }
static void tdfx_cfb32_putcs(struct vc_data* conp, static void tdfx_cfb32_putcs(struct vc_data *conp,
struct display* p, struct display *p,
const unsigned short *s,int count,int yy,int xx) const unsigned short *s, int count, int yy,
int xx)
{ {
u16 c = scr_readw(s); u16 c = scr_readw(s);
u32 fgx = ((u32*)p->dispsw_data)[attr_fgcol(p, c)]; u32 fgx = ((u32 *) p->dispsw_data)[attr_fgcol(p, c)];
u32 bgx = ((u32*)p->dispsw_data)[attr_bgcol(p, c)]; u32 bgx = ((u32 *) p->dispsw_data)[attr_bgcol(p, c)];
do_putcs( fgx,bgx,p,s,count,yy,xx ); do_putcs(fgx, bgx, p, s, count, yy, xx);
} }
static void tdfx_cfb8_clear(struct vc_data* conp, static void tdfx_cfb8_clear(struct vc_data *conp,
struct display* p, struct display *p,
int sy, int sy, int sx, int height, int width)
int sx, {
int height,
int width) {
u32 bg; u32 bg;
bg = attr_bgcol_ec(p,conp); bg = attr_bgcol_ec(p, conp);
do_fillrect(fontwidth(p)*sx, do_fillrect(fontwidth(p) * sx,
fontheight(p)*sy, fontheight(p) * sy,
fontwidth(p)*width, fontwidth(p) * width,
fontheight(p)*height, fontheight(p) * height,
bg, bg,
fb_info.current_par.lpitch, fb_info.current_par.lpitch,
fb_info.current_par.bpp, TDFX_ROP_COPY); fb_info.current_par.bpp, TDFX_ROP_COPY);
} }
static void tdfx_cfb16_clear(struct vc_data* conp, static void tdfx_cfb16_clear(struct vc_data *conp,
struct display* p, struct display *p,
int sy, int sy, int sx, int height, int width)
int sx, {
int height,
int width) {
u32 bg; u32 bg;
bg = ((u16*)p->dispsw_data)[attr_bgcol_ec(p,conp)]; bg = ((u16 *) p->dispsw_data)[attr_bgcol_ec(p, conp)];
do_fillrect(fontwidth(p)*sx, do_fillrect(fontwidth(p) * sx,
fontheight(p)*sy, fontheight(p) * sy,
fontwidth(p)*width, fontwidth(p) * width,
fontheight(p)*height, fontheight(p) * height,
bg, bg,
fb_info.current_par.lpitch, fb_info.current_par.lpitch,
fb_info.current_par.bpp, TDFX_ROP_COPY); fb_info.current_par.bpp, TDFX_ROP_COPY);
} }
static void tdfx_cfb32_clear(struct vc_data* conp, static void tdfx_cfb32_clear(struct vc_data *conp,
struct display* p, struct display *p,
int sy, int sy, int sx, int height, int width)
int sx, {
int height,
int width) {
u32 bg; u32 bg;
bg = ((u32*)p->dispsw_data)[attr_bgcol_ec(p,conp)]; bg = ((u32 *) p->dispsw_data)[attr_bgcol_ec(p, conp)];
do_fillrect(fontwidth(p)*sx, do_fillrect(fontwidth(p) * sx,
fontheight(p)*sy, fontheight(p) * sy,
fontwidth(p)*width, fontwidth(p) * width,
fontheight(p)*height, fontheight(p) * height,
bg, bg,
fb_info.current_par.lpitch, fb_info.current_par.lpitch,
fb_info.current_par.bpp, TDFX_ROP_COPY); fb_info.current_par.bpp, TDFX_ROP_COPY);
} }
static void tdfx_cfbX_revc(struct display *p, int xx, int yy) static void tdfx_cfbX_revc(struct display *p, int xx, int yy)
{ {
int bpp=fb_info.current_par.bpp; int bpp = fb_info.current_par.bpp;
do_fillrect( xx * fontwidth(p), yy * fontheight(p), do_fillrect(xx * fontwidth(p), yy * fontheight(p),
fontwidth(p), fontheight(p), fontwidth(p), fontheight(p),
(bpp==8) ? 0x0f : 0xffffffff, (bpp == 8) ? 0x0f : 0xffffffff,
fb_info.current_par.lpitch, bpp, TDFX_ROP_XOR); fb_info.current_par.lpitch, bpp, TDFX_ROP_XOR);
} }
...@@ -1177,16 +1055,16 @@ static void tdfx_cfbX_cursor(struct display *p, int mode, int x, int y) ...@@ -1177,16 +1055,16 @@ static void tdfx_cfbX_cursor(struct display *p, int mode, int x, int y)
{ {
unsigned long flags; unsigned long flags;
int tip; int tip;
struct fb_info_tdfx *info=(struct fb_info_tdfx *)p->fb_info; struct fb_info_tdfx *info = (struct fb_info_tdfx *) p->fb_info;
tip=p->conp->vc_cursor_type & CUR_HWMASK; tip = p->conp->vc_cursor_type & CUR_HWMASK;
if (mode==CM_ERASE) { if (mode == CM_ERASE) {
if (info->cursor.state != CM_ERASE) { if (info->cursor.state != CM_ERASE) {
spin_lock_irqsave(&info->DAClock,flags); spin_lock_irqsave(&info->DAClock, flags);
info->cursor.state=CM_ERASE; info->cursor.state = CM_ERASE;
del_timer(&(info->cursor.timer)); del_timer(&(info->cursor.timer));
tdfx_outl(VIDPROCCFG,info->cursor.disable); tdfx_outl(VIDPROCCFG, info->cursor.disable);
spin_unlock_irqrestore(&info->DAClock,flags); spin_unlock_irqrestore(&info->DAClock, flags);
} }
return; return;
} }
...@@ -1195,13 +1073,12 @@ static void tdfx_cfbX_cursor(struct display *p, int mode, int x, int y) ...@@ -1195,13 +1073,12 @@ static void tdfx_cfbX_cursor(struct display *p, int mode, int x, int y)
x *= fontwidth(p); x *= fontwidth(p);
y *= fontheight(p); y *= fontheight(p);
y -= p->var.yoffset; y -= p->var.yoffset;
spin_lock_irqsave(&info->DAClock,flags); spin_lock_irqsave(&info->DAClock, flags);
if ((x!=info->cursor.x) || if ((x != info->cursor.x) ||
(y!=info->cursor.y) || (y != info->cursor.y) || (info->cursor.redraw)) {
(info->cursor.redraw)) { info->cursor.x = x;
info->cursor.x=x; info->cursor.y = y;
info->cursor.y=y; info->cursor.redraw = 0;
info->cursor.redraw=0;
x += 63; x += 63;
y += 63; y += 63;
banshee_make_room(2); banshee_make_room(2);
...@@ -1212,70 +1089,72 @@ static void tdfx_cfbX_cursor(struct display *p, int mode, int x, int y) ...@@ -1212,70 +1089,72 @@ static void tdfx_cfbX_cursor(struct display *p, int mode, int x, int y)
tdfx_outl(HWCURC1, 0xffffff); tdfx_outl(HWCURC1, 0xffffff);
} }
info->cursor.state = CM_DRAW; info->cursor.state = CM_DRAW;
mod_timer(&info->cursor.timer,jiffies+HZ/2); mod_timer(&info->cursor.timer, jiffies + HZ / 2);
banshee_make_room(1); banshee_make_room(1);
tdfx_outl(VIDPROCCFG, info->cursor.enable); tdfx_outl(VIDPROCCFG, info->cursor.enable);
spin_unlock_irqrestore(&info->DAClock,flags); spin_unlock_irqrestore(&info->DAClock, flags);
return; return;
} }
#ifdef FBCON_HAS_CFB8 #ifdef FBCON_HAS_CFB8
static struct display_switch fbcon_banshee8 = { static struct display_switch fbcon_banshee8 = {
setup: fbcon_cfb8_setup, setup:fbcon_cfb8_setup,
bmove: tdfx_cfbX_bmove, bmove:tdfx_cfbX_bmove,
clear: tdfx_cfb8_clear, clear:tdfx_cfb8_clear,
putc: tdfx_cfb8_putc, putc:tdfx_cfb8_putc,
putcs: tdfx_cfb8_putcs, putcs:tdfx_cfb8_putcs,
revc: tdfx_cfbX_revc, revc:tdfx_cfbX_revc,
cursor: tdfx_cfbX_cursor, cursor:tdfx_cfbX_cursor,
clear_margins: tdfx_cfbX_clear_margins, clear_margins:tdfx_cfbX_clear_margins,
fontwidthmask: FONTWIDTHRANGE(8, 12) fontwidthmask:FONTWIDTHRANGE(8, 12)
}; };
#endif #endif
#ifdef FBCON_HAS_CFB16 #ifdef FBCON_HAS_CFB16
static struct display_switch fbcon_banshee16 = { static struct display_switch fbcon_banshee16 = {
setup: fbcon_cfb16_setup, setup:fbcon_cfb16_setup,
bmove: tdfx_cfbX_bmove, bmove:tdfx_cfbX_bmove,
clear: tdfx_cfb16_clear, clear:tdfx_cfb16_clear,
putc: tdfx_cfb16_putc, putc:tdfx_cfb16_putc,
putcs: tdfx_cfb16_putcs, putcs:tdfx_cfb16_putcs,
revc: tdfx_cfbX_revc, revc:tdfx_cfbX_revc,
cursor: tdfx_cfbX_cursor, cursor:tdfx_cfbX_cursor,
clear_margins: tdfx_cfbX_clear_margins, clear_margins:tdfx_cfbX_clear_margins,
fontwidthmask: FONTWIDTHRANGE(8, 12) fontwidthmask:FONTWIDTHRANGE(8, 12)
}; };
#endif #endif
#ifdef FBCON_HAS_CFB24 #ifdef FBCON_HAS_CFB24
static struct display_switch fbcon_banshee24 = { static struct display_switch fbcon_banshee24 = {
setup: fbcon_cfb24_setup, setup:fbcon_cfb24_setup,
bmove: tdfx_cfbX_bmove, bmove:tdfx_cfbX_bmove,
clear: tdfx_cfb24_clear, clear:tdfx_cfb24_clear,
putc: tdfx_cfb24_putc, putc:tdfx_cfb24_putc,
putcs: tdfx_cfb24_putcs, putcs:tdfx_cfb24_putcs,
revc: tdfx_cfbX_revc, revc:tdfx_cfbX_revc,
cursor: tdfx_cfbX_cursor, cursor:tdfx_cfbX_cursor,
clear_margins: tdfx_cfbX_clear_margins, clear_margins:tdfx_cfbX_clear_margins,
fontwidthmask: FONTWIDTHRANGE(8, 12) fontwidthmask:FONTWIDTHRANGE(8, 12)
}; };
#endif #endif
#ifdef FBCON_HAS_CFB32 #ifdef FBCON_HAS_CFB32
static struct display_switch fbcon_banshee32 = { static struct display_switch fbcon_banshee32 = {
setup: fbcon_cfb32_setup, setup:fbcon_cfb32_setup,
bmove: tdfx_cfbX_bmove, bmove:tdfx_cfbX_bmove,
clear: tdfx_cfb32_clear, clear:tdfx_cfb32_clear,
putc: tdfx_cfb32_putc, putc:tdfx_cfb32_putc,
putcs: tdfx_cfb32_putcs, putcs:tdfx_cfb32_putcs,
revc: tdfx_cfbX_revc, revc:tdfx_cfbX_revc,
cursor: tdfx_cfbX_cursor, cursor:tdfx_cfbX_cursor,
clear_margins: tdfx_cfbX_clear_margins, clear_margins:tdfx_cfbX_clear_margins,
fontwidthmask: FONTWIDTHRANGE(8, 12) fontwidthmask:FONTWIDTHRANGE(8, 12)
}; };
#endif #endif
/* ------------------------------------------------------------------------- */ /* ------------------------------------------------------------------------- */
static void tdfxfb_set_par(const struct tdfxfb_par* par, static void tdfxfb_set_par(const struct tdfxfb_par *par,
struct fb_info_tdfx* info) { struct fb_info_tdfx *info)
struct fb_info_tdfx* i = (struct fb_info_tdfx*)info; {
struct fb_info_tdfx *i = (struct fb_info_tdfx *) info;
struct banshee_reg reg; struct banshee_reg reg;
u32 cpp; u32 cpp;
u32 hd, hs, he, ht, hbs, hbe; u32 hd, hs, he, ht, hbs, hbe;
...@@ -1286,7 +1165,7 @@ static void tdfxfb_set_par(const struct tdfxfb_par* par, ...@@ -1286,7 +1165,7 @@ static void tdfxfb_set_par(const struct tdfxfb_par* par,
memset(&reg, 0, sizeof(reg)); memset(&reg, 0, sizeof(reg));
cpp = (par->bpp + 7)/8; cpp = (par->bpp + 7) / 8;
wd = (par->hdispend >> 3) - 1; wd = (par->hdispend >> 3) - 1;
...@@ -1354,9 +1233,7 @@ static void tdfxfb_set_par(const struct tdfxfb_par* par, ...@@ -1354,9 +1233,7 @@ static void tdfxfb_set_par(const struct tdfxfb_par* par,
reg.crt[0x02] = hbs; reg.crt[0x02] = hbs;
reg.crt[0x03] = 0x80 | (hbe & 0x1f); reg.crt[0x03] = 0x80 | (hbe & 0x1f);
reg.crt[0x04] = hs; reg.crt[0x04] = hs;
reg.crt[0x05] = reg.crt[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
((hbe & 0x20) << 2) |
(he & 0x1f);
reg.crt[0x06] = vt; reg.crt[0x06] = vt;
reg.crt[0x07] = reg.crt[0x07] =
((vs & 0x200) >> 2) | ((vs & 0x200) >> 2) |
...@@ -1365,12 +1242,9 @@ static void tdfxfb_set_par(const struct tdfxfb_par* par, ...@@ -1365,12 +1242,9 @@ static void tdfxfb_set_par(const struct tdfxfb_par* par,
0x10 | 0x10 |
((vbs & 0x100) >> 5) | ((vbs & 0x100) >> 5) |
((vs & 0x100) >> 6) | ((vs & 0x100) >> 6) |
((vd & 0x100) >> 7) | ((vd & 0x100) >> 7) | ((vt & 0x100) >> 8);
((vt & 0x100) >> 8);
reg.crt[0x08] = 0x00; reg.crt[0x08] = 0x00;
reg.crt[0x09] = reg.crt[0x09] = 0x40 | ((vbs & 0x200) >> 4);
0x40 |
((vbs & 0x200) >> 4);
reg.crt[0x0a] = 0x00; reg.crt[0x0a] = 0x00;
reg.crt[0x0b] = 0x00; reg.crt[0x0b] = 0x00;
reg.crt[0x0c] = 0x00; reg.crt[0x0c] = 0x00;
...@@ -1378,9 +1252,7 @@ static void tdfxfb_set_par(const struct tdfxfb_par* par, ...@@ -1378,9 +1252,7 @@ static void tdfxfb_set_par(const struct tdfxfb_par* par,
reg.crt[0x0e] = 0x00; reg.crt[0x0e] = 0x00;
reg.crt[0x0f] = 0x00; reg.crt[0x0f] = 0x00;
reg.crt[0x10] = vs; reg.crt[0x10] = vs;
reg.crt[0x11] = reg.crt[0x11] = (ve & 0x0f) | 0x20;
(ve & 0x0f) |
0x20;
reg.crt[0x12] = vd; reg.crt[0x12] = vd;
reg.crt[0x13] = wd; reg.crt[0x13] = wd;
reg.crt[0x14] = 0x00; reg.crt[0x14] = 0x00;
...@@ -1394,19 +1266,16 @@ static void tdfxfb_set_par(const struct tdfxfb_par* par, ...@@ -1394,19 +1266,16 @@ static void tdfxfb_set_par(const struct tdfxfb_par* par,
((hd & 0x100) >> 6) | ((hd & 0x100) >> 6) |
((hbs & 0x100) >> 4) | ((hbs & 0x100) >> 4) |
((hbe & 0x40) >> 1) | ((hbe & 0x40) >> 1) |
((hs & 0x100) >> 2) | ((hs & 0x100) >> 2) | ((he & 0x20) << 2));
((he & 0x20) << 2));
reg.ext[0x01] = (((vt & 0x400) >> 10) | reg.ext[0x01] = (((vt & 0x400) >> 10) |
((vd & 0x400) >> 8) | ((vd & 0x400) >> 8) |
((vbs & 0x400) >> 6) | ((vbs & 0x400) >> 6) | ((vbe & 0x400) >> 4));
((vbe & 0x400) >> 4));
reg.vgainit0 = reg.vgainit0 =
VGAINIT0_8BIT_DAC | VGAINIT0_8BIT_DAC |
VGAINIT0_EXT_ENABLE | VGAINIT0_EXT_ENABLE |
VGAINIT0_WAKEUP_3C3 | VGAINIT0_WAKEUP_3C3 |
VGAINIT0_ALT_READBACK | VGAINIT0_ALT_READBACK | VGAINIT0_EXTSHIFTOUT;
VGAINIT0_EXTSHIFTOUT;
reg.vgainit1 = tdfx_inl(VGAINIT1) & 0x1fffff; reg.vgainit1 = tdfx_inl(VGAINIT1) & 0x1fffff;
reg.vidcfg = reg.vidcfg =
...@@ -1416,10 +1285,10 @@ static void tdfxfb_set_par(const struct tdfxfb_par* par, ...@@ -1416,10 +1285,10 @@ static void tdfxfb_set_par(const struct tdfxfb_par* par,
((cpp - 1) << VIDCFG_PIXFMT_SHIFT) | ((cpp - 1) << VIDCFG_PIXFMT_SHIFT) |
(cpp != 1 ? VIDCFG_CLUT_BYPASS : 0); (cpp != 1 ? VIDCFG_CLUT_BYPASS : 0);
fb_info.cursor.enable=reg.vidcfg | VIDCFG_HWCURSOR_ENABLE; fb_info.cursor.enable = reg.vidcfg | VIDCFG_HWCURSOR_ENABLE;
fb_info.cursor.disable=reg.vidcfg; fb_info.cursor.disable = reg.vidcfg;
reg.stride = par->width*cpp; reg.stride = par->width * cpp;
reg.cursloc = 0; reg.cursloc = 0;
reg.cursc0 = 0; reg.cursc0 = 0;
...@@ -1427,7 +1296,7 @@ static void tdfxfb_set_par(const struct tdfxfb_par* par, ...@@ -1427,7 +1296,7 @@ static void tdfxfb_set_par(const struct tdfxfb_par* par,
reg.curspataddr = fb_info.cursor.cursorimage; reg.curspataddr = fb_info.cursor.cursorimage;
reg.startaddr = par->baseline*reg.stride; reg.startaddr = par->baseline * reg.stride;
reg.srcbase = reg.startaddr; reg.srcbase = reg.startaddr;
reg.dstbase = reg.startaddr; reg.dstbase = reg.startaddr;
...@@ -1436,7 +1305,7 @@ static void tdfxfb_set_par(const struct tdfxfb_par* par, ...@@ -1436,7 +1305,7 @@ static void tdfxfb_set_par(const struct tdfxfb_par* par,
reg.dacmode &= ~DACMODE_2X; reg.dacmode &= ~DACMODE_2X;
reg.vidcfg &= ~VIDCFG_2X; reg.vidcfg &= ~VIDCFG_2X;
if(freq > i->max_pixclock/2) { if (freq > i->max_pixclock / 2) {
freq = freq > i->max_pixclock ? i->max_pixclock : freq; freq = freq > i->max_pixclock ? i->max_pixclock : freq;
reg.dacmode |= DACMODE_2X; reg.dacmode |= DACMODE_2X;
reg.vidcfg |= VIDCFG_2X; reg.vidcfg |= VIDCFG_2X;
...@@ -1476,48 +1345,50 @@ static void tdfxfb_set_par(const struct tdfxfb_par* par, ...@@ -1476,48 +1345,50 @@ static void tdfxfb_set_par(const struct tdfxfb_par* par,
} }
static int tdfxfb_decode_var(const struct fb_var_screeninfo* var, static int tdfxfb_decode_var(const struct fb_var_screeninfo *var,
struct tdfxfb_par* par, struct tdfxfb_par *par,
const struct fb_info_tdfx* info) { const struct fb_info_tdfx *info)
struct fb_info_tdfx* i = (struct fb_info_tdfx*)info; {
struct fb_info_tdfx *i = (struct fb_info_tdfx *) info;
if(var->bits_per_pixel != 8 && if (var->bits_per_pixel != 8 &&
var->bits_per_pixel != 16 && var->bits_per_pixel != 16 &&
var->bits_per_pixel != 24 && var->bits_per_pixel != 24 && var->bits_per_pixel != 32) {
var->bits_per_pixel != 32) {
DPRINTK("depth not supported: %u\n", var->bits_per_pixel); DPRINTK("depth not supported: %u\n", var->bits_per_pixel);
return -EINVAL; return -EINVAL;
} }
if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) { if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
DPRINTK("interlace not supported\n"); DPRINTK("interlace not supported\n");
return -EINVAL; return -EINVAL;
} }
if(var->xoffset) { if (var->xoffset) {
DPRINTK("xoffset not supported\n"); DPRINTK("xoffset not supported\n");
return -EINVAL; return -EINVAL;
} }
if(var->xres != var->xres_virtual) { if (var->xres != var->xres_virtual) {
DPRINTK("virtual x resolution != physical x resolution not supported\n"); DPRINTK
("virtual x resolution != physical x resolution not supported\n");
return -EINVAL; return -EINVAL;
} }
if(var->yres > var->yres_virtual) { if (var->yres > var->yres_virtual) {
DPRINTK("virtual y resolution < physical y resolution not possible\n"); DPRINTK
("virtual y resolution < physical y resolution not possible\n");
return -EINVAL; return -EINVAL;
} }
/* fixme: does Voodoo3 support interlace? Banshee doesn't */ /* fixme: does Voodoo3 support interlace? Banshee doesn't */
if((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) { if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
DPRINTK("interlace not supported\n"); DPRINTK("interlace not supported\n");
return -EINVAL; return -EINVAL;
} }
memset(par, 0, sizeof(struct tdfxfb_par)); memset(par, 0, sizeof(struct tdfxfb_par));
switch(i->dev) { switch (i->dev) {
case PCI_DEVICE_ID_3DFX_BANSHEE: case PCI_DEVICE_ID_3DFX_BANSHEE:
case PCI_DEVICE_ID_3DFX_VOODOO3: case PCI_DEVICE_ID_3DFX_VOODOO3:
case PCI_DEVICE_ID_3DFX_VOODOO5: case PCI_DEVICE_ID_3DFX_VOODOO5:
...@@ -1527,27 +1398,28 @@ static int tdfxfb_decode_var(const struct fb_var_screeninfo* var, ...@@ -1527,27 +1398,28 @@ static int tdfxfb_decode_var(const struct fb_var_screeninfo* var,
par->height_virt = var->yres_virtual; par->height_virt = var->yres_virtual;
par->bpp = var->bits_per_pixel; par->bpp = var->bits_per_pixel;
par->ppitch = var->bits_per_pixel; par->ppitch = var->bits_per_pixel;
par->lpitch = par->width* ((par->ppitch+7)>>3); par->lpitch = par->width * ((par->ppitch + 7) >> 3);
par->cmap_len = (par->bpp == 8) ? 256 : 16; par->cmap_len = (par->bpp == 8) ? 256 : 16;
par->baseline = 0; par->baseline = 0;
if(par->width < 320 || par->width > 2048) { if (par->width < 320 || par->width > 2048) {
DPRINTK("width not supported: %u\n", par->width); DPRINTK("width not supported: %u\n", par->width);
return -EINVAL; return -EINVAL;
} }
if(par->height < 200 || par->height > 2048) { if (par->height < 200 || par->height > 2048) {
DPRINTK("height not supported: %u\n", par->height); DPRINTK("height not supported: %u\n", par->height);
return -EINVAL; return -EINVAL;
} }
if(par->lpitch*par->height_virt > i->bufbase_size) { if (par->lpitch * par->height_virt > i->bufbase_size) {
DPRINTK("no memory for screen (%ux%ux%u)\n", DPRINTK("no memory for screen (%ux%ux%u)\n",
par->width, par->height_virt, par->bpp); par->width, par->height_virt, par->bpp);
return -EINVAL; return -EINVAL;
} }
par->pixclock = PICOS2KHZ(var->pixclock); par->pixclock = PICOS2KHZ(var->pixclock);
if(par->pixclock > i->max_pixclock) { if (par->pixclock > i->max_pixclock) {
DPRINTK("pixclock too high (%uKHz)\n", par->pixclock); DPRINTK("pixclock too high (%uKHz)\n",
par->pixclock);
return -EINVAL; return -EINVAL;
} }
...@@ -1561,21 +1433,21 @@ static int tdfxfb_decode_var(const struct fb_var_screeninfo* var, ...@@ -1561,21 +1433,21 @@ static int tdfxfb_decode_var(const struct fb_var_screeninfo* var,
par->vsyncend = par->vsyncsta + var->vsync_len; par->vsyncend = par->vsyncsta + var->vsync_len;
par->vtotal = par->vsyncend + var->upper_margin; par->vtotal = par->vsyncend + var->upper_margin;
if(var->sync & FB_SYNC_HOR_HIGH_ACT) if (var->sync & FB_SYNC_HOR_HIGH_ACT)
par->video |= TDFXF_HSYNC_ACT_HIGH; par->video |= TDFXF_HSYNC_ACT_HIGH;
else else
par->video |= TDFXF_HSYNC_ACT_LOW; par->video |= TDFXF_HSYNC_ACT_LOW;
if(var->sync & FB_SYNC_VERT_HIGH_ACT) if (var->sync & FB_SYNC_VERT_HIGH_ACT)
par->video |= TDFXF_VSYNC_ACT_HIGH; par->video |= TDFXF_VSYNC_ACT_HIGH;
else else
par->video |= TDFXF_VSYNC_ACT_LOW; par->video |= TDFXF_VSYNC_ACT_LOW;
if((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) if ((var->vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
par->video |= TDFXF_LINE_DOUBLE; par->video |= TDFXF_LINE_DOUBLE;
if(var->activate == FB_ACTIVATE_NOW) if (var->activate == FB_ACTIVATE_NOW)
par->video |= TDFXF_VIDEO_ENABLE; par->video |= TDFXF_VIDEO_ENABLE;
} }
if(var->accel_flags & FB_ACCELF_TEXT) if (var->accel_flags & FB_ACCELF_TEXT)
par->accel_flags = FB_ACCELF_TEXT; par->accel_flags = FB_ACCELF_TEXT;
else else
par->accel_flags = 0; par->accel_flags = 0;
...@@ -1583,9 +1455,10 @@ static int tdfxfb_decode_var(const struct fb_var_screeninfo* var, ...@@ -1583,9 +1455,10 @@ static int tdfxfb_decode_var(const struct fb_var_screeninfo* var,
return 0; return 0;
} }
static int tdfxfb_encode_var(struct fb_var_screeninfo* var, static int tdfxfb_encode_var(struct fb_var_screeninfo *var,
const struct tdfxfb_par* par, const struct tdfxfb_par *par,
const struct fb_info_tdfx* info) { const struct fb_info_tdfx *info)
{
struct fb_var_screeninfo v; struct fb_var_screeninfo v;
memset(&v, 0, sizeof(struct fb_var_screeninfo)); memset(&v, 0, sizeof(struct fb_var_screeninfo));
...@@ -1600,7 +1473,7 @@ static int tdfxfb_encode_var(struct fb_var_screeninfo* var, ...@@ -1600,7 +1473,7 @@ static int tdfxfb_encode_var(struct fb_var_screeninfo* var,
v.vsync_len = par->vsyncend - par->vsyncsta; v.vsync_len = par->vsyncend - par->vsyncsta;
v.upper_margin = par->vtotal - par->vsyncend; v.upper_margin = par->vtotal - par->vsyncend;
v.bits_per_pixel = par->bpp; v.bits_per_pixel = par->bpp;
switch(par->bpp) { switch (par->bpp) {
case 8: case 8:
v.red.length = v.green.length = v.blue.length = 8; v.red.length = v.green.length = v.blue.length = 8;
break; break;
...@@ -1613,9 +1486,9 @@ static int tdfxfb_encode_var(struct fb_var_screeninfo* var, ...@@ -1613,9 +1486,9 @@ static int tdfxfb_encode_var(struct fb_var_screeninfo* var,
v.blue.length = 5; v.blue.length = 5;
break; break;
case 24: case 24:
v.red.offset=16; v.red.offset = 16;
v.green.offset=8; v.green.offset = 8;
v.blue.offset=0; v.blue.offset = 0;
v.red.length = v.green.length = v.blue.length = 8; v.red.length = v.green.length = v.blue.length = 8;
case 32: case 32:
v.red.offset = 16; v.red.offset = 16;
...@@ -1626,22 +1499,23 @@ static int tdfxfb_encode_var(struct fb_var_screeninfo* var, ...@@ -1626,22 +1499,23 @@ static int tdfxfb_encode_var(struct fb_var_screeninfo* var,
} }
v.height = v.width = -1; v.height = v.width = -1;
v.pixclock = KHZ2PICOS(par->pixclock); v.pixclock = KHZ2PICOS(par->pixclock);
if((par->video & TDFXF_HSYNC_MASK) == TDFXF_HSYNC_ACT_HIGH) if ((par->video & TDFXF_HSYNC_MASK) == TDFXF_HSYNC_ACT_HIGH)
v.sync |= FB_SYNC_HOR_HIGH_ACT; v.sync |= FB_SYNC_HOR_HIGH_ACT;
if((par->video & TDFXF_VSYNC_MASK) == TDFXF_VSYNC_ACT_HIGH) if ((par->video & TDFXF_VSYNC_MASK) == TDFXF_VSYNC_ACT_HIGH)
v.sync |= FB_SYNC_VERT_HIGH_ACT; v.sync |= FB_SYNC_VERT_HIGH_ACT;
if(par->video & TDFXF_LINE_DOUBLE) if (par->video & TDFXF_LINE_DOUBLE)
v.vmode = FB_VMODE_DOUBLE; v.vmode = FB_VMODE_DOUBLE;
*var = v; *var = v;
return 0; return 0;
} }
static int tdfxfb_encode_fix(struct fb_fix_screeninfo* fix, static int tdfxfb_encode_fix(struct fb_fix_screeninfo *fix,
const struct tdfxfb_par* par, const struct tdfxfb_par *par,
const struct fb_info_tdfx* info) { const struct fb_info_tdfx *info)
{
memset(fix, 0, sizeof(struct fb_fix_screeninfo)); memset(fix, 0, sizeof(struct fb_fix_screeninfo));
switch(info->dev) { switch (info->dev) {
case PCI_DEVICE_ID_3DFX_BANSHEE: case PCI_DEVICE_ID_3DFX_BANSHEE:
strcpy(fix->id, "3Dfx Banshee"); strcpy(fix->id, "3Dfx Banshee");
break; break;
...@@ -1664,8 +1538,7 @@ static int tdfxfb_encode_fix(struct fb_fix_screeninfo* fix, ...@@ -1664,8 +1538,7 @@ static int tdfxfb_encode_fix(struct fb_fix_screeninfo* fix,
fix->type_aux = 0; fix->type_aux = 0;
fix->line_length = par->lpitch; fix->line_length = par->lpitch;
fix->visual = (par->bpp == 8) fix->visual = (par->bpp == 8)
? FB_VISUAL_PSEUDOCOLOR ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
: FB_VISUAL_DIRECTCOLOR;
fix->xpanstep = 0; fix->xpanstep = 0;
fix->ypanstep = nopan ? 0 : 1; fix->ypanstep = nopan ? 0 : 1;
...@@ -1675,12 +1548,12 @@ static int tdfxfb_encode_fix(struct fb_fix_screeninfo* fix, ...@@ -1675,12 +1548,12 @@ static int tdfxfb_encode_fix(struct fb_fix_screeninfo* fix,
} }
static int tdfxfb_get_fix(struct fb_fix_screeninfo *fix, static int tdfxfb_get_fix(struct fb_fix_screeninfo *fix,
int con, int con, struct fb_info *fb)
struct fb_info *fb) { {
const struct fb_info_tdfx *info = (struct fb_info_tdfx*)fb; const struct fb_info_tdfx *info = (struct fb_info_tdfx *) fb;
struct tdfxfb_par par; struct tdfxfb_par par;
if(con == -1) if (con == -1)
par = info->default_par; par = info->default_par;
else else
tdfxfb_decode_var(&fb_display[con].var, &par, info); tdfxfb_decode_var(&fb_display[con].var, &par, info);
...@@ -1689,11 +1562,11 @@ static int tdfxfb_get_fix(struct fb_fix_screeninfo *fix, ...@@ -1689,11 +1562,11 @@ static int tdfxfb_get_fix(struct fb_fix_screeninfo *fix,
} }
static int tdfxfb_get_var(struct fb_var_screeninfo *var, static int tdfxfb_get_var(struct fb_var_screeninfo *var,
int con, int con, struct fb_info *fb)
struct fb_info *fb) { {
const struct fb_info_tdfx *info = (struct fb_info_tdfx*)fb; const struct fb_info_tdfx *info = (struct fb_info_tdfx *) fb;
if(con == -1) if (con == -1)
tdfxfb_encode_var(var, &info->default_par, info); tdfxfb_encode_var(var, &info->default_par, info);
else else
*var = fb_display[con].var; *var = fb_display[con].var;
...@@ -1702,37 +1575,41 @@ static int tdfxfb_get_var(struct fb_var_screeninfo *var, ...@@ -1702,37 +1575,41 @@ static int tdfxfb_get_var(struct fb_var_screeninfo *var,
static void tdfxfb_set_dispsw(struct display *disp, static void tdfxfb_set_dispsw(struct display *disp,
struct fb_info_tdfx *info, struct fb_info_tdfx *info,
int bpp, int bpp, int accel)
int accel) { {
if (disp->dispsw && disp->conp) if (disp->dispsw && disp->conp)
fb_con.con_cursor(disp->conp, CM_ERASE); fb_con.con_cursor(disp->conp, CM_ERASE);
switch(bpp) { switch (bpp) {
#ifdef FBCON_HAS_CFB8 #ifdef FBCON_HAS_CFB8
case 8: case 8:
disp->dispsw = noaccel ? &fbcon_cfb8 : &fbcon_banshee8; disp->dispsw = noaccel ? &fbcon_cfb8 : &fbcon_banshee8;
if (nohwcursor) fbcon_banshee8.cursor = NULL; if (nohwcursor)
fbcon_banshee8.cursor = NULL;
break; break;
#endif #endif
#ifdef FBCON_HAS_CFB16 #ifdef FBCON_HAS_CFB16
case 16: case 16:
disp->dispsw = noaccel ? &fbcon_cfb16 : &fbcon_banshee16; disp->dispsw = noaccel ? &fbcon_cfb16 : &fbcon_banshee16;
disp->dispsw_data = info->fbcon_cmap.cfb16; disp->dispsw_data = info->fbcon_cmap.cfb16;
if (nohwcursor) fbcon_banshee16.cursor = NULL; if (nohwcursor)
fbcon_banshee16.cursor = NULL;
break; break;
#endif #endif
#ifdef FBCON_HAS_CFB24 #ifdef FBCON_HAS_CFB24
case 24: case 24:
disp->dispsw = noaccel ? &fbcon_cfb24 : &fbcon_banshee24; disp->dispsw = noaccel ? &fbcon_cfb24 : &fbcon_banshee24;
disp->dispsw_data = info->fbcon_cmap.cfb24; disp->dispsw_data = info->fbcon_cmap.cfb24;
if (nohwcursor) fbcon_banshee24.cursor = NULL; if (nohwcursor)
fbcon_banshee24.cursor = NULL;
break; break;
#endif #endif
#ifdef FBCON_HAS_CFB32 #ifdef FBCON_HAS_CFB32
case 32: case 32:
disp->dispsw = noaccel ? &fbcon_cfb32 : &fbcon_banshee32; disp->dispsw = noaccel ? &fbcon_cfb32 : &fbcon_banshee32;
disp->dispsw_data = info->fbcon_cmap.cfb32; disp->dispsw_data = info->fbcon_cmap.cfb32;
if (nohwcursor) fbcon_banshee32.cursor = NULL; if (nohwcursor)
fbcon_banshee32.cursor = NULL;
break; break;
#endif #endif
default: default:
...@@ -1742,26 +1619,27 @@ static void tdfxfb_set_dispsw(struct display *disp, ...@@ -1742,26 +1619,27 @@ static void tdfxfb_set_dispsw(struct display *disp,
} }
static int tdfxfb_set_var(struct fb_var_screeninfo *var, static int tdfxfb_set_var(struct fb_var_screeninfo *var,
int con, int con, struct fb_info *fb)
struct fb_info *fb) { {
struct fb_info_tdfx *info = (struct fb_info_tdfx*)fb; struct fb_info_tdfx *info = (struct fb_info_tdfx *) fb;
struct tdfxfb_par par; struct tdfxfb_par par;
struct display *display; struct display *display;
int oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel, accel, err; int oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel, accel,
err;
int activate = var->activate; int activate = var->activate;
int j,k; int j, k;
if(con >= 0) if (con >= 0)
display = &fb_display[con]; display = &fb_display[con];
else else
display = fb->disp; /* used during initialization */ display = fb->disp; /* used during initialization */
if((err = tdfxfb_decode_var(var, &par, info))) if ((err = tdfxfb_decode_var(var, &par, info)))
return err; return err;
tdfxfb_encode_var(var, &par, info); tdfxfb_encode_var(var, &par, info);
if((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) { if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
oldxres = display->var.xres; oldxres = display->var.xres;
oldyres = display->var.yres; oldyres = display->var.yres;
oldvxres = display->var.xres_virtual; oldvxres = display->var.xres_virtual;
...@@ -1769,7 +1647,7 @@ static int tdfxfb_set_var(struct fb_var_screeninfo *var, ...@@ -1769,7 +1647,7 @@ static int tdfxfb_set_var(struct fb_var_screeninfo *var,
oldbpp = display->var.bits_per_pixel; oldbpp = display->var.bits_per_pixel;
oldaccel = display->var.accel_flags; oldaccel = display->var.accel_flags;
display->var = *var; display->var = *var;
if(con < 0 || if (con < 0 ||
oldxres != var->xres || oldxres != var->xres ||
oldyres != var->yres || oldyres != var->yres ||
oldvxres != var->xres_virtual || oldvxres != var->xres_virtual ||
...@@ -1791,13 +1669,14 @@ static int tdfxfb_set_var(struct fb_var_screeninfo *var, ...@@ -1791,13 +1669,14 @@ static int tdfxfb_set_var(struct fb_var_screeninfo *var,
accel = var->accel_flags & FB_ACCELF_TEXT; accel = var->accel_flags & FB_ACCELF_TEXT;
tdfxfb_set_dispsw(display, info, par.bpp, accel); tdfxfb_set_dispsw(display, info, par.bpp, accel);
if(nopan) display->scrollmode = SCROLL_YREDRAW; if (nopan)
display->scrollmode = SCROLL_YREDRAW;
if (info->fb_info.changevar) if (info->fb_info.changevar)
(*info->fb_info.changevar)(con); (*info->fb_info.changevar) (con);
} }
if (var->bits_per_pixel==8) if (var->bits_per_pixel == 8)
for(j = 0; j < 16; j++) { for (j = 0; j < 16; j++) {
k = color_table[j]; k = color_table[j];
fb_info.palette[j].red = default_red[k]; fb_info.palette[j].red = default_red[k];
fb_info.palette[j].green = default_grn[k]; fb_info.palette[j].green = default_grn[k];
...@@ -1805,17 +1684,16 @@ static int tdfxfb_set_var(struct fb_var_screeninfo *var, ...@@ -1805,17 +1684,16 @@ static int tdfxfb_set_var(struct fb_var_screeninfo *var,
} }
del_timer(&(info->cursor.timer)); del_timer(&(info->cursor.timer));
fb_info.cursor.state=CM_ERASE; fb_info.cursor.state = CM_ERASE;
if(!info->fb_info.display_fg || if (!info->fb_info.display_fg ||
info->fb_info.display_fg->vc_num == con || info->fb_info.display_fg->vc_num == con || con < 0)
con < 0)
tdfxfb_set_par(&par, info); tdfxfb_set_par(&par, info);
if (!nohwcursor) if (!nohwcursor)
if (display && display->conp) if (display && display->conp)
tdfxfb_createcursor( display ); tdfxfb_createcursor(display);
info->cursor.redraw=1; info->cursor.redraw = 1;
if(oldbpp != var->bits_per_pixel || con < 0) { if (oldbpp != var->bits_per_pixel || con < 0) {
if((err = fb_alloc_cmap(&display->cmap, 0, 0))) if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
return err; return err;
do_install_cmap(con, &(info->fb_info)); do_install_cmap(con, &(info->fb_info));
} }
...@@ -1824,59 +1702,61 @@ static int tdfxfb_set_var(struct fb_var_screeninfo *var, ...@@ -1824,59 +1702,61 @@ static int tdfxfb_set_var(struct fb_var_screeninfo *var,
return 0; return 0;
} }
static int tdfxfb_pan_display(struct fb_var_screeninfo* var, static int tdfxfb_pan_display(struct fb_var_screeninfo *var,
int con, int con, struct fb_info *fb)
struct fb_info* fb) { {
struct fb_info_tdfx* i = (struct fb_info_tdfx*)fb; struct fb_info_tdfx *i = (struct fb_info_tdfx *) fb;
if(nopan) return -EINVAL; if (nopan)
if(var->xoffset) return -EINVAL; return -EINVAL;
if(var->yoffset > var->yres_virtual) return -EINVAL; if (var->xoffset)
if(nowrap && return -EINVAL;
(var->yoffset + var->yres > var->yres_virtual)) return -EINVAL; if (var->yoffset > var->yres_virtual)
return -EINVAL;
if (nowrap && (var->yoffset + var->yres > var->yres_virtual))
return -EINVAL;
if (con == fb->currcon) if (con == fb->currcon)
do_pan_var(var,i); do_pan_var(var, i);
fb_display[con].var.xoffset=var->xoffset; fb_display[con].var.xoffset = var->xoffset;
fb_display[con].var.yoffset=var->yoffset; fb_display[con].var.yoffset = var->yoffset;
return 0; return 0;
} }
static int tdfxfb_get_cmap(struct fb_cmap *cmap, static int tdfxfb_get_cmap(struct fb_cmap *cmap,
int kspc, int kspc, int con, struct fb_info *fb)
int con, {
struct fb_info *fb) {
struct fb_info_tdfx* i = (struct fb_info_tdfx*)fb; struct fb_info_tdfx *i = (struct fb_info_tdfx *) fb;
struct display *d=(con<0) ? fb->disp : fb_display + con; struct display *d = (con < 0) ? fb->disp : fb_display + con;
if(con == fb->currcon) { if (con == fb->currcon) {
/* current console? */ /* current console? */
return fb_get_cmap(cmap, kspc, tdfxfb_getcolreg, fb); return fb_get_cmap(cmap, kspc, tdfxfb_getcolreg, fb);
} else if(d->cmap.len) { } else if (d->cmap.len) {
/* non default colormap? */ /* non default colormap? */
fb_copy_cmap(&d->cmap, cmap, kspc ? 0 : 2); fb_copy_cmap(&d->cmap, cmap, kspc ? 0 : 2);
} else { } else {
fb_copy_cmap(fb_default_cmap(i->current_par.cmap_len), cmap, kspc ? 0 : 2); fb_copy_cmap(fb_default_cmap(i->current_par.cmap_len),
cmap, kspc ? 0 : 2);
} }
return 0; return 0;
} }
static int tdfxfb_set_cmap(struct fb_cmap *cmap, static int tdfxfb_set_cmap(struct fb_cmap *cmap,
int kspc, int kspc, int con, struct fb_info *fb)
int con, {
struct fb_info *fb) { struct display *d = (con < 0) ? fb->disp : fb_display + con;
struct display *d=(con<0) ? fb->disp : fb_display + con; struct fb_info_tdfx *i = (struct fb_info_tdfx *) fb;
struct fb_info_tdfx *i = (struct fb_info_tdfx*)fb;
int cmap_len = (i->current_par.bpp == 8) ? 256 : 16;
int cmap_len= (i->current_par.bpp == 8) ? 256 : 16; if (d->cmap.len != cmap_len) {
if (d->cmap.len!=cmap_len) {
int err; int err;
if((err = fb_alloc_cmap(&d->cmap, cmap_len, 0))) if ((err = fb_alloc_cmap(&d->cmap, cmap_len, 0)))
return err; return err;
} }
if(con == fb->currcon) { if (con == fb->currcon) {
/* current console? */ /* current console? */
return fb_set_cmap(cmap, kspc, fb); return fb_set_cmap(cmap, kspc, fb);
} else { } else {
...@@ -1919,14 +1799,16 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev, ...@@ -1919,14 +1799,16 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
fb_info.regbase_phys = pci_resource_start(pdev, 0); fb_info.regbase_phys = pci_resource_start(pdev, 0);
fb_info.regbase_size = 1 << 24; fb_info.regbase_size = 1 << 24;
fb_info.regbase_virt = ioremap_nocache(fb_info.regbase_phys, 1 << 24); fb_info.regbase_virt =
ioremap_nocache(fb_info.regbase_phys, 1 << 24);
if (!fb_info.regbase_virt) { if (!fb_info.regbase_virt) {
printk(KERN_WARNING "fb: Can't remap %s register area.\n", name); printk(KERN_WARNING "fb: Can't remap %s register area.\n",
name);
return -ENXIO; return -ENXIO;
} }
fb_info.bufbase_phys = pci_resource_start (pdev, 1); fb_info.bufbase_phys = pci_resource_start(pdev, 1);
if (!(fb_info.bufbase_size = do_lfb_size())) { if (!(fb_info.bufbase_size = do_lfb_size())) {
iounmap(fb_info.regbase_virt); iounmap(fb_info.regbase_virt);
...@@ -1938,12 +1820,13 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev, ...@@ -1938,12 +1820,13 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
fb_info.bufbase_size); fb_info.bufbase_size);
if (!fb_info.regbase_virt) { if (!fb_info.regbase_virt) {
printk(KERN_WARNING "fb: Can't remap %s framebuffer.\n", name); printk(KERN_WARNING "fb: Can't remap %s framebuffer.\n",
name);
iounmap(fb_info.regbase_virt); iounmap(fb_info.regbase_virt);
return -ENXIO; return -ENXIO;
} }
fb_info.iobase = pci_resource_start (pdev, 2); fb_info.iobase = pci_resource_start(pdev, 2);
printk("fb: %s memory = %ldK\n", name, fb_info.bufbase_size >> 10); printk("fb: %s memory = %ldK\n", name, fb_info.bufbase_size >> 10);
...@@ -1965,7 +1848,7 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev, ...@@ -1965,7 +1848,7 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
init_timer(&fb_info.cursor.timer); init_timer(&fb_info.cursor.timer);
fb_info.cursor.timer.function = do_flashcursor; fb_info.cursor.timer.function = do_flashcursor;
fb_info.cursor.timer.data = (unsigned long)(&fb_info); fb_info.cursor.timer.data = (unsigned long) (&fb_info);
fb_info.cursor.state = CM_ERASE; fb_info.cursor.state = CM_ERASE;
spin_lock_init(&fb_info.DAClock); spin_lock_init(&fb_info.DAClock);
...@@ -1988,7 +1871,7 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev, ...@@ -1988,7 +1871,7 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
var = default_mode[0].var; var = default_mode[0].var;
noaccel ? (var.accel_flags &= ~FB_ACCELF_TEXT) : noaccel ? (var.accel_flags &= ~FB_ACCELF_TEXT) :
(var.accel_flags |= FB_ACCELF_TEXT) ; (var.accel_flags |= FB_ACCELF_TEXT);
if (tdfxfb_decode_var(&var, &fb_info.default_par, &fb_info)) { if (tdfxfb_decode_var(&var, &fb_info.default_par, &fb_info)) {
/* /*
...@@ -1996,16 +1879,19 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev, ...@@ -1996,16 +1879,19 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
* line), so try the default * line), so try the default
*/ */
printk(KERN_NOTICE "tdfxfb: can't decode the supplied video mode, using default\n"); printk(KERN_NOTICE
"tdfxfb: can't decode the supplied video mode, using default\n");
var = default_mode[0].var; var = default_mode[0].var;
noaccel ? (var.accel_flags &= ~FB_ACCELF_TEXT) : noaccel ? (var.accel_flags &= ~FB_ACCELF_TEXT) :
(var.accel_flags |= FB_ACCELF_TEXT) ; (var.accel_flags |= FB_ACCELF_TEXT);
if (tdfxfb_decode_var(&var, &fb_info.default_par, &fb_info)) { if (tdfxfb_decode_var
(&var, &fb_info.default_par, &fb_info)) {
/* this is getting really bad!... */ /* this is getting really bad!... */
printk(KERN_WARNING "tdfxfb: can't decode default video mode\n"); printk(KERN_WARNING
"tdfxfb: can't decode default video mode\n");
return -ENXIO; return -ENXIO;
} }
} }
...@@ -2014,12 +1900,14 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev, ...@@ -2014,12 +1900,14 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
fb_info.disp.var = var; fb_info.disp.var = var;
if (tdfxfb_set_var(&var, -1, &fb_info.fb_info)) { if (tdfxfb_set_var(&var, -1, &fb_info.fb_info)) {
printk(KERN_WARNING "tdfxfb: can't set default video mode\n"); printk(KERN_WARNING
"tdfxfb: can't set default video mode\n");
return -ENXIO; return -ENXIO;
} }
if (register_framebuffer(&fb_info.fb_info) < 0) { if (register_framebuffer(&fb_info.fb_info) < 0) {
printk(KERN_WARNING "tdfxfb: can't register framebuffer\n"); printk(KERN_WARNING
"tdfxfb: can't register framebuffer\n");
return -ENXIO; return -ENXIO;
} }
...@@ -2045,7 +1933,8 @@ static void __devexit tdfxfb_remove(struct pci_dev *pdev) ...@@ -2045,7 +1933,8 @@ static void __devexit tdfxfb_remove(struct pci_dev *pdev)
#ifdef CONFIG_MTRR #ifdef CONFIG_MTRR
if (!nomtrr) { if (!nomtrr) {
mtrr_del(fb_info.mtrr_idx, fb_info.bufbase_phys, fb_info.bufbase_size); mtrr_del(fb_info.mtrr_idx, fb_info.bufbase_phys,
fb_info.bufbase_size);
printk("fb: MTRR's turned off\n"); printk("fb: MTRR's turned off\n");
} }
#endif #endif
...@@ -2076,24 +1965,24 @@ module_exit(tdfxfb_exit); ...@@ -2076,24 +1965,24 @@ module_exit(tdfxfb_exit);
#ifndef MODULE #ifndef MODULE
void tdfxfb_setup(char *options, void tdfxfb_setup(char *options, int *ints)
int *ints) { {
char* this_opt; char *this_opt;
if(!options || !*options) if (!options || !*options)
return; return;
while((this_opt = strsep(&options, ",")) != NULL) { while ((this_opt = strsep(&options, ",")) != NULL) {
if(!*this_opt) if (!*this_opt)
continue; continue;
if(!strcmp(this_opt, "inverse")) { if (!strcmp(this_opt, "inverse")) {
inverse = 1; inverse = 1;
fb_invert_cmaps(); fb_invert_cmaps();
} else if(!strcmp(this_opt, "noaccel")) { } else if (!strcmp(this_opt, "noaccel")) {
noaccel = nopan = nowrap = nohwcursor = 1; noaccel = nopan = nowrap = nohwcursor = 1;
} else if(!strcmp(this_opt, "nopan")) { } else if (!strcmp(this_opt, "nopan")) {
nopan = 1; nopan = 1;
} else if(!strcmp(this_opt, "nowrap")) { } else if (!strcmp(this_opt, "nowrap")) {
nowrap = 1; nowrap = 1;
} else if (!strcmp(this_opt, "nohwcursor")) { } else if (!strcmp(this_opt, "nohwcursor")) {
nohwcursor = 1; nohwcursor = 1;
...@@ -2110,26 +1999,28 @@ void tdfxfb_setup(char *options, ...@@ -2110,26 +1999,28 @@ void tdfxfb_setup(char *options,
} }
#endif #endif
static int tdfxfb_switch_con(int con, static int tdfxfb_switch_con(int con, struct fb_info *fb)
struct fb_info *fb) { {
struct fb_info_tdfx *info = (struct fb_info_tdfx*)fb; struct fb_info_tdfx *info = (struct fb_info_tdfx *) fb;
struct tdfxfb_par par; struct tdfxfb_par par;
int old_con = fb->currcon; int old_con = fb->currcon;
int set_par = 1; int set_par = 1;
/* Do we have to save the colormap? */ /* Do we have to save the colormap? */
if (fb->currcon>=0) if (fb->currcon >= 0)
if(fb_display[fb->currcon].cmap.len) if (fb_display[fb->currcon].cmap.len)
fb_get_cmap(&fb_display[fb->currcon].cmap, 1, tdfxfb_getcolreg, fb); fb_get_cmap(&fb_display[fb->currcon].cmap, 1,
tdfxfb_getcolreg, fb);
fb->currcon = con; fb->currcon = con;
fb_display[fb->currcon].var.activate = FB_ACTIVATE_NOW; fb_display[fb->currcon].var.activate = FB_ACTIVATE_NOW;
tdfxfb_decode_var(&fb_display[con].var, &par, info); tdfxfb_decode_var(&fb_display[con].var, &par, info);
if (old_con>=0 && vt_cons[old_con]->vc_mode!=KD_GRAPHICS) { if (old_con >= 0 && vt_cons[old_con]->vc_mode != KD_GRAPHICS) {
/* check if we have to change video registers */ /* check if we have to change video registers */
struct tdfxfb_par old_par; struct tdfxfb_par old_par;
tdfxfb_decode_var(&fb_display[old_con].var, &old_par, info); tdfxfb_decode_var(&fb_display[old_con].var, &old_par,
if (!memcmp(&par,&old_par,sizeof(par))) info);
if (!memcmp(&par, &old_par, sizeof(par)))
set_par = 0; /* avoid flicker */ set_par = 0; /* avoid flicker */
} }
if (set_par) if (set_par)
...@@ -2139,18 +2030,16 @@ static int tdfxfb_switch_con(int con, ...@@ -2139,18 +2030,16 @@ static int tdfxfb_switch_con(int con,
fb_con.con_cursor(fb_display[con].conp, CM_ERASE); fb_con.con_cursor(fb_display[con].conp, CM_ERASE);
del_timer(&(info->cursor.timer)); del_timer(&(info->cursor.timer));
fb_info.cursor.state=CM_ERASE; fb_info.cursor.state = CM_ERASE;
if (!nohwcursor) if (!nohwcursor)
if (fb_display[con].conp) if (fb_display[con].conp)
tdfxfb_createcursor( &fb_display[con] ); tdfxfb_createcursor(&fb_display[con]);
info->cursor.redraw=1; info->cursor.redraw = 1;
tdfxfb_set_dispsw(&fb_display[con], tdfxfb_set_dispsw(&fb_display[con],
info, info, par.bpp, par.accel_flags & FB_ACCELF_TEXT);
par.bpp,
par.accel_flags & FB_ACCELF_TEXT);
do_install_cmap(con, fb); do_install_cmap(con, fb);
tdfxfb_updatevar(con, fb); tdfxfb_updatevar(con, fb);
...@@ -2159,14 +2048,13 @@ static int tdfxfb_switch_con(int con, ...@@ -2159,14 +2048,13 @@ static int tdfxfb_switch_con(int con,
} }
/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */ /* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
static int tdfxfb_blank(int blank, static int tdfxfb_blank(int blank, struct fb_info *fb)
struct fb_info *fb)
{ {
u32 dacmode, state = 0, vgablank = 0; u32 dacmode, state = 0, vgablank = 0;
dacmode = tdfx_inl(DACMODE); dacmode = tdfx_inl(DACMODE);
switch(blank) { switch (blank) {
case 0: /* Screen: On; HSync: On, VSync: On */ case 0: /* Screen: On; HSync: On, VSync: On */
state = 0; state = 0;
vgablank = 0; vgablank = 0;
...@@ -2193,31 +2081,32 @@ static int tdfxfb_blank(int blank, ...@@ -2193,31 +2081,32 @@ static int tdfxfb_blank(int blank,
dacmode |= state; dacmode |= state;
banshee_make_room(1); banshee_make_room(1);
tdfx_outl(DACMODE, dacmode); tdfx_outl(DACMODE, dacmode);
if(vgablank) if (vgablank)
vga_disable_video(); vga_disable_video();
else else
vga_enable_video(); vga_enable_video();
return 0; return 0;
} }
static int tdfxfb_updatevar(int con, static int tdfxfb_updatevar(int con, struct fb_info *fb)
struct fb_info* fb) { {
struct fb_info_tdfx* i = (struct fb_info_tdfx*)fb; struct fb_info_tdfx *i = (struct fb_info_tdfx *) fb;
if ((con==fb->currcon) && (!nopan)) if ((con == fb->currcon) && (!nopan))
do_pan_var(&fb_display[con].var,i); do_pan_var(&fb_display[con].var, i);
return 0; return 0;
} }
static int tdfxfb_getcolreg(unsigned regno, static int tdfxfb_getcolreg(unsigned regno,
unsigned* red, unsigned *red,
unsigned* green, unsigned *green,
unsigned* blue, unsigned *blue,
unsigned* transp, unsigned *transp, struct fb_info *fb)
struct fb_info* fb) { {
struct fb_info_tdfx* i = (struct fb_info_tdfx*)fb; struct fb_info_tdfx *i = (struct fb_info_tdfx *) fb;
if (regno > i->current_par.cmap_len) return 1; if (regno > i->current_par.cmap_len)
return 1;
*red = i->palette[regno].red; *red = i->palette[regno].red;
*green = i->palette[regno].green; *green = i->palette[regno].green;
...@@ -2231,49 +2120,50 @@ static int tdfxfb_setcolreg(unsigned regno, ...@@ -2231,49 +2120,50 @@ static int tdfxfb_setcolreg(unsigned regno,
unsigned red, unsigned red,
unsigned green, unsigned green,
unsigned blue, unsigned blue,
unsigned transp, unsigned transp, struct fb_info *info)
struct fb_info* info) { {
struct fb_info_tdfx* i = (struct fb_info_tdfx*)info; struct fb_info_tdfx *i = (struct fb_info_tdfx *) info;
#ifdef FBCON_HAS_CFB8 #ifdef FBCON_HAS_CFB8
u32 rgbcol; u32 rgbcol;
#endif #endif
if (regno >= i->current_par.cmap_len) return 1; if (regno >= i->current_par.cmap_len)
return 1;
i->palette[regno].red = red; i->palette[regno].red = red;
i->palette[regno].green = green; i->palette[regno].green = green;
i->palette[regno].blue = blue; i->palette[regno].blue = blue;
switch(i->current_par.bpp) { switch (i->current_par.bpp) {
#ifdef FBCON_HAS_CFB8 #ifdef FBCON_HAS_CFB8
case 8: case 8:
rgbcol=(((u32)red & 0xff00) << 8) | rgbcol = (((u32) red & 0xff00) << 8) |
(((u32)green & 0xff00) << 0) | (((u32) green & 0xff00) << 0) |
(((u32)blue & 0xff00) >> 8); (((u32) blue & 0xff00) >> 8);
do_setpalentry(regno,rgbcol); do_setpalentry(regno, rgbcol);
break; break;
#endif #endif
#ifdef FBCON_HAS_CFB16 #ifdef FBCON_HAS_CFB16
case 16: case 16:
i->fbcon_cmap.cfb16[regno] = i->fbcon_cmap.cfb16[regno] =
(((u32)red & 0xf800) >> 0) | (((u32) red & 0xf800) >> 0) |
(((u32)green & 0xfc00) >> 5) | (((u32) green & 0xfc00) >> 5) |
(((u32)blue & 0xf800) >> 11); (((u32) blue & 0xf800) >> 11);
break; break;
#endif #endif
#ifdef FBCON_HAS_CFB24 #ifdef FBCON_HAS_CFB24
case 24: case 24:
i->fbcon_cmap.cfb24[regno] = i->fbcon_cmap.cfb24[regno] =
(((u32)red & 0xff00) << 8) | (((u32) red & 0xff00) << 8) |
(((u32)green & 0xff00) << 0) | (((u32) green & 0xff00) << 0) |
(((u32)blue & 0xff00) >> 8); (((u32) blue & 0xff00) >> 8);
break; break;
#endif #endif
#ifdef FBCON_HAS_CFB32 #ifdef FBCON_HAS_CFB32
case 32: case 32:
i->fbcon_cmap.cfb32[regno] = i->fbcon_cmap.cfb32[regno] =
(((u32)red & 0xff00) << 8) | (((u32) red & 0xff00) << 8) |
(((u32)green & 0xff00) << 0) | (((u32) green & 0xff00) << 0) |
(((u32)blue & 0xff00) >> 8); (((u32) blue & 0xff00) >> 8);
break; break;
#endif #endif
default: default:
...@@ -2283,39 +2173,40 @@ static int tdfxfb_setcolreg(unsigned regno, ...@@ -2283,39 +2173,40 @@ static int tdfxfb_setcolreg(unsigned regno,
return 0; return 0;
} }
static void tdfxfb_createcursorshape(struct display* p) static void tdfxfb_createcursorshape(struct display *p)
{ {
unsigned int h,cu,cd; unsigned int h, cu, cd;
h=fontheight(p); h = fontheight(p);
cd=h; cd = h;
if (cd >= 10) cd --; if (cd >= 10)
fb_info.cursor.type=p->conp->vc_cursor_type & CUR_HWMASK; cd--;
fb_info.cursor.type = p->conp->vc_cursor_type & CUR_HWMASK;
switch (fb_info.cursor.type) { switch (fb_info.cursor.type) {
case CUR_NONE: case CUR_NONE:
cu=cd; cu = cd;
break; break;
case CUR_UNDERLINE: case CUR_UNDERLINE:
cu=cd - 2; cu = cd - 2;
break; break;
case CUR_LOWER_THIRD: case CUR_LOWER_THIRD:
cu=(h * 2) / 3; cu = (h * 2) / 3;
break; break;
case CUR_LOWER_HALF: case CUR_LOWER_HALF:
cu=h / 2; cu = h / 2;
break; break;
case CUR_TWO_THIRDS: case CUR_TWO_THIRDS:
cu=h / 3; cu = h / 3;
break; break;
case CUR_BLOCK: case CUR_BLOCK:
default: default:
cu=0; cu = 0;
cd = h; cd = h;
break; break;
} }
fb_info.cursor.w=fontwidth(p); fb_info.cursor.w = fontwidth(p);
fb_info.cursor.u=cu; fb_info.cursor.u = cu;
fb_info.cursor.d=cd; fb_info.cursor.d = cd;
} }
static void tdfxfb_createcursor(struct display *p) static void tdfxfb_createcursor(struct display *p)
...@@ -2323,7 +2214,7 @@ static void tdfxfb_createcursor(struct display *p) ...@@ -2323,7 +2214,7 @@ static void tdfxfb_createcursor(struct display *p)
u8 *cursorbase; u8 *cursorbase;
u32 xline; u32 xline;
unsigned int i; unsigned int i;
unsigned int h,to; unsigned int h, to;
tdfxfb_createcursorshape(p); tdfxfb_createcursorshape(p);
xline = ~((1 << (32 - fb_info.cursor.w)) - 1); xline = ~((1 << (32 - fb_info.cursor.w)) - 1);
...@@ -2332,33 +2223,33 @@ static void tdfxfb_createcursor(struct display *p) ...@@ -2332,33 +2223,33 @@ static void tdfxfb_createcursor(struct display *p)
xline = swab32(xline); xline = swab32(xline);
#endif #endif
cursorbase=(u8*)fb_info.bufbase_virt; cursorbase = (u8 *) fb_info.bufbase_virt;
h=fb_info.cursor.cursorimage; h = fb_info.cursor.cursorimage;
to=fb_info.cursor.u; to = fb_info.cursor.u;
for (i = 0; i < to; i++) { for (i = 0; i < to; i++) {
writel(0, cursorbase+h); writel(0, cursorbase + h);
writel(0, cursorbase+h+4); writel(0, cursorbase + h + 4);
writel(~0, cursorbase+h+8); writel(~0, cursorbase + h + 8);
writel(~0, cursorbase+h+12); writel(~0, cursorbase + h + 12);
h += 16; h += 16;
} }
to = fb_info.cursor.d; to = fb_info.cursor.d;
for (; i < to; i++) { for (; i < to; i++) {
writel(xline, cursorbase+h); writel(xline, cursorbase + h);
writel(0, cursorbase+h+4); writel(0, cursorbase + h + 4);
writel(~0, cursorbase+h+8); writel(~0, cursorbase + h + 8);
writel(~0, cursorbase+h+12); writel(~0, cursorbase + h + 12);
h += 16; h += 16;
} }
for (; i < 64; i++) { for (; i < 64; i++) {
writel(0, cursorbase+h); writel(0, cursorbase + h);
writel(0, cursorbase+h+4); writel(0, cursorbase + h + 4);
writel(~0, cursorbase+h+8); writel(~0, cursorbase + h + 8);
writel(~0, cursorbase+h+12); writel(~0, cursorbase + h + 12);
h += 16; h += 16;
} }
} }
...@@ -2366,11 +2257,9 @@ static void tdfxfb_createcursor(struct display *p) ...@@ -2366,11 +2257,9 @@ static void tdfxfb_createcursor(struct display *p)
static void tdfxfb_hwcursor_init(void) static void tdfxfb_hwcursor_init(void)
{ {
unsigned int start; unsigned int start;
start = (fb_info.bufbase_size-1024) & PAGE_MASK; start = (fb_info.bufbase_size - 1024) & PAGE_MASK;
fb_info.bufbase_size=start; fb_info.bufbase_size = start;
fb_info.cursor.cursorimage=fb_info.bufbase_size; fb_info.cursor.cursorimage = fb_info.bufbase_size;
printk("tdfxfb: reserving 1024 bytes for the hwcursor at %p\n", printk("tdfxfb: reserving 1024 bytes for the hwcursor at %p\n",
fb_info.regbase_virt+fb_info.cursor.cursorimage); fb_info.regbase_virt + fb_info.cursor.cursorimage);
} }
...@@ -93,7 +93,8 @@ ...@@ -93,7 +93,8 @@
#define FB_ACCEL_IGS_CYBER2010 34 /* CyberPro 2010 */ #define FB_ACCEL_IGS_CYBER2010 34 /* CyberPro 2010 */
#define FB_ACCEL_IGS_CYBER5000 35 /* CyberPro 5000 */ #define FB_ACCEL_IGS_CYBER5000 35 /* CyberPro 5000 */
#define FB_ACCEL_SIS_GLAMOUR 36 /* SiS 300/630/540 */ #define FB_ACCEL_SIS_GLAMOUR 36 /* SiS 300/630/540 */
#define FB_ACCEL_3DLABS_PERMEDIA3 37 /* 3Dlabs Permedia 3 */
#define FB_ACCEL_ATI_RADEON 38 /* ATI Radeon family */
#define FB_ACCEL_NEOMAGIC_NM2070 90 /* NeoMagic NM2070 */ #define FB_ACCEL_NEOMAGIC_NM2070 90 /* NeoMagic NM2070 */
#define FB_ACCEL_NEOMAGIC_NM2090 91 /* NeoMagic NM2090 */ #define FB_ACCEL_NEOMAGIC_NM2090 91 /* NeoMagic NM2090 */
...@@ -169,6 +170,9 @@ struct fb_bitfield { ...@@ -169,6 +170,9 @@ struct fb_bitfield {
#define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */ #define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */
#define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */ #define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */
#define PICOS2KHZ(a) (1000000000UL/(a))
#define KHZ2PICOS(a) (1000000000UL/(a))
struct fb_var_screeninfo { struct fb_var_screeninfo {
__u32 xres; /* visible resolution */ __u32 xres; /* visible resolution */
__u32 yres; __u32 yres;
......
#ifndef _TDFX_H
#define _TDFX_H
/* membase0 register offsets */
#define STATUS 0x00
#define PCIINIT0 0x04
#define SIPMONITOR 0x08
#define LFBMEMORYCONFIG 0x0c
#define MISCINIT0 0x10
#define MISCINIT1 0x14
#define DRAMINIT0 0x18
#define DRAMINIT1 0x1c
#define AGPINIT 0x20
#define TMUGBEINIT 0x24
#define VGAINIT0 0x28
#define VGAINIT1 0x2c
#define DRAMCOMMAND 0x30
#define DRAMDATA 0x34
/* reserved 0x38 */
/* reserved 0x3c */
#define PLLCTRL0 0x40
#define PLLCTRL1 0x44
#define PLLCTRL2 0x48
#define DACMODE 0x4c
#define DACADDR 0x50
#define DACDATA 0x54
#define RGBMAXDELTA 0x58
#define VIDPROCCFG 0x5c
#define HWCURPATADDR 0x60
#define HWCURLOC 0x64
#define HWCURC0 0x68
#define HWCURC1 0x6c
#define VIDINFORMAT 0x70
#define VIDINSTATUS 0x74
#define VIDSERPARPORT 0x78
#define VIDINXDELTA 0x7c
#define VIDININITERR 0x80
#define VIDINYDELTA 0x84
#define VIDPIXBUFTHOLD 0x88
#define VIDCHRMIN 0x8c
#define VIDCHRMAX 0x90
#define VIDCURLIN 0x94
#define VIDSCREENSIZE 0x98
#define VIDOVRSTARTCRD 0x9c
#define VIDOVRENDCRD 0xa0
#define VIDOVRDUDX 0xa4
#define VIDOVRDUDXOFF 0xa8
#define VIDOVRDVDY 0xac
/* ... */
#define VIDOVRDVDYOFF 0xe0
#define VIDDESKSTART 0xe4
#define VIDDESKSTRIDE 0xe8
#define VIDINADDR0 0xec
#define VIDINADDR1 0xf0
#define VIDINADDR2 0xf4
#define VIDINSTRIDE 0xf8
#define VIDCUROVRSTART 0xfc
#define INTCTRL (0x00100000 + 0x04)
#define CLIP0MIN (0x00100000 + 0x08)
#define CLIP0MAX (0x00100000 + 0x0c)
#define DSTBASE (0x00100000 + 0x10)
#define DSTFORMAT (0x00100000 + 0x14)
#define SRCBASE (0x00100000 + 0x34)
#define COMMANDEXTRA_2D (0x00100000 + 0x38)
#define CLIP1MIN (0x00100000 + 0x4c)
#define CLIP1MAX (0x00100000 + 0x50)
#define SRCFORMAT (0x00100000 + 0x54)
#define SRCSIZE (0x00100000 + 0x58)
#define SRCXY (0x00100000 + 0x5c)
#define COLORBACK (0x00100000 + 0x60)
#define COLORFORE (0x00100000 + 0x64)
#define DSTSIZE (0x00100000 + 0x68)
#define DSTXY (0x00100000 + 0x6c)
#define COMMAND_2D (0x00100000 + 0x70)
#define LAUNCH_2D (0x00100000 + 0x80)
#define COMMAND_3D (0x00200000 + 0x120)
/* register bitfields (not all, only as needed) */
#define BIT(x) (1UL << (x))
/* COMMAND_2D reg. values */
#define TDFX_ROP_COPY 0xcc // src
#define TDFX_ROP_INVERT 0x55 // NOT dst
#define TDFX_ROP_XOR 0x66 // src XOR dst
#define AUTOINC_DSTX BIT(10)
#define AUTOINC_DSTY BIT(11)
#define COMMAND_2D_FILLRECT 0x05
#define COMMAND_2D_S2S_BITBLT 0x01 // screen to screen
#define COMMAND_2D_H2S_BITBLT 0x03 // host to screen
#define COMMAND_3D_NOP 0x00
#define STATUS_RETRACE BIT(6)
#define STATUS_BUSY BIT(9)
#define MISCINIT1_CLUT_INV BIT(0)
#define MISCINIT1_2DBLOCK_DIS BIT(15)
#define DRAMINIT0_SGRAM_NUM BIT(26)
#define DRAMINIT0_SGRAM_TYPE BIT(27)
#define DRAMINIT1_MEM_SDRAM BIT(30)
#define VGAINIT0_VGA_DISABLE BIT(0)
#define VGAINIT0_EXT_TIMING BIT(1)
#define VGAINIT0_8BIT_DAC BIT(2)
#define VGAINIT0_EXT_ENABLE BIT(6)
#define VGAINIT0_WAKEUP_3C3 BIT(8)
#define VGAINIT0_LEGACY_DISABLE BIT(9)
#define VGAINIT0_ALT_READBACK BIT(10)
#define VGAINIT0_FAST_BLINK BIT(11)
#define VGAINIT0_EXTSHIFTOUT BIT(12)
#define VGAINIT0_DECODE_3C6 BIT(13)
#define VGAINIT0_SGRAM_HBLANK_DISABLE BIT(22)
#define VGAINIT1_MASK 0x1fffff
#define VIDCFG_VIDPROC_ENABLE BIT(0)
#define VIDCFG_CURS_X11 BIT(1)
#define VIDCFG_HALF_MODE BIT(4)
#define VIDCFG_DESK_ENABLE BIT(7)
#define VIDCFG_CLUT_BYPASS BIT(10)
#define VIDCFG_2X BIT(26)
#define VIDCFG_HWCURSOR_ENABLE BIT(27)
#define VIDCFG_PIXFMT_SHIFT 18
#define DACMODE_2X BIT(0)
/* VGA rubbish, need to change this for multihead support */
#define MISC_W 0x3c2
#define MISC_R 0x3cc
#define SEQ_I 0x3c4
#define SEQ_D 0x3c5
#define CRT_I 0x3d4
#define CRT_D 0x3d5
#define ATT_IW 0x3c0
#define IS1_R 0x3da
#define GRA_I 0x3ce
#define GRA_D 0x3cf
#ifdef __KERNEL__
struct banshee_reg {
/* VGA rubbish */
unsigned char att[21];
unsigned char crt[25];
unsigned char gra[ 9];
unsigned char misc[1];
unsigned char seq[ 5];
/* Banshee extensions */
unsigned char ext[2];
unsigned long vidcfg;
unsigned long vidpll;
unsigned long mempll;
unsigned long gfxpll;
unsigned long dacmode;
unsigned long vgainit0;
unsigned long vgainit1;
unsigned long screensize;
unsigned long stride;
unsigned long cursloc;
unsigned long curspataddr;
unsigned long cursc0;
unsigned long cursc1;
unsigned long startaddr;
unsigned long clip0min;
unsigned long clip0max;
unsigned long clip1min;
unsigned long clip1max;
unsigned long srcbase;
unsigned long dstbase;
unsigned long miscinit0;
};
/*
struct tdfx_par {
u32 max_pixclock;
void *regbase_virt;
unsigned long iobase;
u32 baseline;
struct {
int w,u,d;
unsigned long enable,disable;
struct timer_list timer;
} hwcursor;
spinlock_t DAClock;
};
*/
#endif /* __KERNEL__ */
#endif /* _TDFX_H */
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