summaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Config.in26
-rw-r--r--drivers/video/Makefile29
-rw-r--r--drivers/video/S3triofb.c19
-rw-r--r--drivers/video/acornfb.c238
-rw-r--r--drivers/video/amifb.c408
-rw-r--r--drivers/video/atafb.c25
-rw-r--r--drivers/video/aty.h2
-rw-r--r--drivers/video/atyfb.c1386
-rw-r--r--drivers/video/bwtwofb.c4
-rw-r--r--drivers/video/cgfourteenfb.c8
-rw-r--r--drivers/video/cgsixfb.c39
-rw-r--r--drivers/video/cgthreefb.c4
-rw-r--r--drivers/video/chipsfb.c15
-rw-r--r--drivers/video/clgenfb.c4897
-rw-r--r--drivers/video/clgenfb.h265
-rw-r--r--drivers/video/controlfb.c29
-rw-r--r--drivers/video/creatorfb.c20
-rw-r--r--drivers/video/cyber2000fb.c47
-rw-r--r--drivers/video/cyberfb.c1264
-rw-r--r--drivers/video/cyberfb.h45
-rw-r--r--drivers/video/dnfb.c11
-rw-r--r--drivers/video/dummycon.c2
-rw-r--r--drivers/video/fbcon-vga-planes.c43
-rw-r--r--drivers/video/fbcon.c6
-rw-r--r--drivers/video/fbmem.c181
-rw-r--r--drivers/video/fm2fb.c20
-rw-r--r--drivers/video/font_6x11.c20
-rw-r--r--drivers/video/g364fb.c11
-rw-r--r--drivers/video/hpfb.c11
-rw-r--r--drivers/video/igafb.c29
-rw-r--r--drivers/video/imsttfb.c57
-rw-r--r--drivers/video/leofb.c6
-rw-r--r--drivers/video/macfb.c14
-rw-r--r--drivers/video/macmodes.c395
-rw-r--r--drivers/video/matroxfb.c721
-rw-r--r--drivers/video/mdacon.c10
-rw-r--r--drivers/video/modedb.c410
-rw-r--r--drivers/video/newport_con.c2
-rw-r--r--drivers/video/offb.c38
-rw-r--r--drivers/video/p9100.h87
-rw-r--r--drivers/video/p9100fb.c178
-rw-r--r--drivers/video/platinumfb.c26
-rw-r--r--drivers/video/pm2fb.c101
-rw-r--r--drivers/video/promcon.c10
-rw-r--r--drivers/video/q40fb.c52
-rw-r--r--drivers/video/retz3fb.c144
-rw-r--r--drivers/video/sbusfb.c27
-rw-r--r--drivers/video/sgivwfb.c48
-rw-r--r--drivers/video/skeletonfb.c14
-rw-r--r--drivers/video/tcxfb.c4
-rw-r--r--drivers/video/tgafb.c34
-rw-r--r--drivers/video/valkyriefb.c34
-rw-r--r--drivers/video/vesafb.c98
-rw-r--r--drivers/video/vfb.c25
-rw-r--r--drivers/video/vga.h444
-rw-r--r--drivers/video/vga16fb.c337
-rw-r--r--drivers/video/vga_font.c352
-rw-r--r--drivers/video/vgacon.c30
-rw-r--r--drivers/video/virgefb.c125
59 files changed, 8600 insertions, 4327 deletions
diff --git a/drivers/video/Config.in b/drivers/video/Config.in
index 06dacf03f..9fb8d3905 100644
--- a/drivers/video/Config.in
+++ b/drivers/video/Config.in
@@ -6,7 +6,8 @@ if [ "$CONFIG_FB" = "y" ]; then
define_bool CONFIG_DUMMY_CONSOLE y
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
if [ "$CONFIG_AMIGA" = "y" -o "$CONFIG_PCI" = "y" ]; then
- bool 'Permedia2 support (experimental)' CONFIG_FB_PM2
+ tristate 'Cirrus Logic suport (experimental)' CONFIG_FB_CLGEN
+ tristate 'Permedia2 support (experimental)' CONFIG_FB_PM2
if [ "$CONFIG_FB_PM2" = "y" ]; then
if [ "$CONFIG_PCI" = "y" ]; then
bool ' enable FIFO disconnect feature' CONFIG_FB_PM2_FIFO_DISCONNECT
@@ -43,13 +44,12 @@ if [ "$CONFIG_FB" = "y" ]; then
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
bool 'Amiga CyberVision3D support (experimental)' CONFIG_FB_VIRGE
tristate 'Amiga RetinaZ3 support' CONFIG_FB_RETINAZ3
- tristate 'Amiga CLgen driver' CONFIG_FB_CLGEN
bool 'Amiga FrameMaster II/Rainbow II support (experimental)' CONFIG_FB_FM2
fi
fi
if [ "$CONFIG_ATARI" = "y" ]; then
bool 'Atari native chipset support' CONFIG_FB_ATARI
- bool 'ATI Mach64 display support' CONFIG_FB_ATY
+ tristate 'ATI Mach64 display support' CONFIG_FB_ATY
fi
if [ "$CONFIG_PPC" = "y" ]; then
bool 'Open Firmware frame buffer device support' CONFIG_FB_OF
@@ -57,11 +57,12 @@ if [ "$CONFIG_FB" = "y" ]; then
bool 'Apple "control" display support' CONFIG_FB_CONTROL
bool 'Apple "platinum" display support' CONFIG_FB_PLATINUM
bool 'Apple "valkyrie" display support' CONFIG_FB_VALKYRIE
- bool 'ATI Mach64 display support' CONFIG_FB_ATY
+ tristate 'ATI Mach64 display support' CONFIG_FB_ATY
bool 'IMS Twin Turbo display support' CONFIG_FB_IMSTT
bool 'Chips 65550 display support' CONFIG_FB_CT65550
bool 'S3 Trio display support' CONFIG_FB_S3TRIO
fi
+ tristate 'VGA 16-color graphics console' CONFIG_FB_VGA16
fi
if [ "$CONFIG_MAC" = "y" ]; then
define_bool CONFIG_FB_MAC y
@@ -74,7 +75,7 @@ if [ "$CONFIG_FB" = "y" ]; then
fi
if [ "$ARCH" = "i386" ]; then
bool 'VESA VGA graphics console' CONFIG_FB_VESA
- bool 'VGA 16-color graphics console' CONFIG_FB_VGA16
+ tristate 'VGA 16-color graphics console' CONFIG_FB_VGA16
define_bool CONFIG_VIDEO_SELECT y
fi
if [ "$CONFIG_VISWS" = "y" ]; then
@@ -86,10 +87,10 @@ if [ "$CONFIG_FB" = "y" ]; then
if [ "$CONFIG_FB_MATROX" != "n" ]; then
bool ' Millennium I/II support' CONFIG_FB_MATROX_MILLENIUM
bool ' Mystique support' CONFIG_FB_MATROX_MYSTIQUE
- bool ' G100/G200 support' CONFIG_FB_MATROX_G100
+ bool ' G100/G200/G400 support' CONFIG_FB_MATROX_G100
bool ' Multihead support' CONFIG_FB_MATROX_MULTIHEAD
fi
- bool 'ATI Mach64 display support' CONFIG_FB_ATY
+ tristate 'ATI Mach64 display support' CONFIG_FB_ATY
fi
fi
if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then
@@ -104,6 +105,7 @@ if [ "$CONFIG_FB" = "y" ]; then
if [ "$ARCH" = "sparc" ]; then
bool ' TCX (SS4/SS5 only) support' CONFIG_FB_TCX
bool ' CGfourteen (SX) support' CONFIG_FB_CGFOURTEEN
+ bool ' P9100 (Sparcbook 3 only) support' CONFIG_FB_P9100
fi
bool ' Leo (ZX) support' CONFIG_FB_LEO
fi
@@ -120,7 +122,7 @@ if [ "$CONFIG_FB" = "y" ]; then
if [ "$CONFIG_PCI" != "n" ]; then
bool 'PCI framebuffers' CONFIG_FB_PCI
if [ "$CONFIG_FB_PCI" != "n" ]; then
- bool ' ATI Mach64 display support' CONFIG_FB_ATY
+ tristate ' ATI Mach64 display support' CONFIG_FB_ATY
fi
fi
fi
@@ -142,7 +144,7 @@ if [ "$CONFIG_FB" = "y" ]; then
tristate 'Atari interleaved bitplanes (8 planes) support' CONFIG_FBCON_IPLAN2P8
# tristate 'Atari interleaved bitplanes (16 planes) support' CONFIG_FBCON_IPLAN2P16
tristate 'Mac variable bpp packed pixels support' CONFIG_FBCON_MAC
- bool 'VGA 16-color planar support' CONFIG_FBCON_VGA_PLANES
+ tristate 'VGA 16-color planar support' CONFIG_FBCON_VGA_PLANES
tristate 'VGA characters/attributes support' CONFIG_FBCON_VGA
else
# Guess what we need
@@ -183,6 +185,7 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VALKYRIE" = "y" -o "$CONFIG_FB_PLATINUM" = "y" -o \
"$CONFIG_FB_IGA" = "y" -o "$CONFIG_FB_MATROX" = "y" -o \
"$CONFIG_FB_CT65550" = "y" -o "$CONFIG_FB_PM2" = "y" -o \
+ "$CONFIG_FB_P9100" = "y" -o \
"$CONFIG_FB_SGIVW" = "y" -o "$CONFIG_FB_CYBER2000" = "y" ]; then
define_bool CONFIG_FBCON_CFB8 y
else
@@ -197,6 +200,7 @@ if [ "$CONFIG_FB" = "y" ]; then
"$CONFIG_FB_VALKYRIE" = "m" -o "$CONFIG_FB_PLATINUM" = "m" -o \
"$CONFIG_FB_IGA" = "m" -o "$CONFIG_FB_MATROX" = "m" -o \
"$CONFIG_FB_CT65550" = "m" -o "$CONFIG_FB_PM2" = "m" -o \
+ "$CONFIG_FB_P9100" = "m" -o \
"$CONFIG_FB_SGIVW" = "m" -o "$CONFIG_FB_CYBER2000" = "m" ]; then
define_bool CONFIG_FBCON_CFB8 m
fi
@@ -287,6 +291,10 @@ if [ "$CONFIG_FB" = "y" ]; then
fi
if [ "$CONFIG_FB_VGA16" = "y" ]; then
define_bool CONFIG_FBCON_VGA_PLANES y
+ else
+ if [ "$CONFIG_FB_VGA16" = "m" ]; then
+ define_bool CONFIG_FBCON_VGA_PLANES m
+ fi
fi
if [ "$CONFIG_FB_MDA" = "y" -o "$CONFIG_FB_VGA" = "y" ]; then
define_bool CONFIG_FBCON_VGA y
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 24f5218c6..8e328ed1e 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -37,7 +37,7 @@ endif
ifeq ($(CONFIG_FB),y)
L_OBJS += fonts.o
- OX_OBJS += fbcon.o fbcmap.o fbmem.o
+ OX_OBJS += fbcon.o fbcmap.o fbmem.o modedb.o
ifeq ($(CONFIG_FONT_8x8),y)
L_OBJS += font_8x8.o
endif
@@ -82,6 +82,11 @@ endif
ifeq ($(CONFIG_FB_PM2),y)
L_OBJS += pm2fb.o
CONFIG_FBGEN_BUILTIN = y
+else
+ ifeq ($(CONFIG_FB_PM2),m)
+ M_OBJS += pm2fb.o
+ CONFIG_FBGEN_MODULE = y
+ endif
endif
ifeq ($(CONFIG_FB_APOLLO),y)
@@ -102,6 +107,10 @@ endif
ifeq ($(CONFIG_FB_ATY),y)
L_OBJS += atyfb.o
+else
+ ifeq ($(CONFIG_FB_ATY),m)
+ M_OBJS += atyfb.o
+ endif
endif
ifeq ($(CONFIG_FB_IGA),y)
@@ -206,6 +215,10 @@ endif
ifeq ($(CONFIG_FB_VGA16),y)
L_OBJS += vga16fb.o
+else
+ ifeq ($(CONFIG_FB_VGA16),m)
+ M_OBJS += vga16fb.o
+ endif
endif
ifeq ($(CONFIG_FB_VIRGE),y)
@@ -272,6 +285,13 @@ L_OBJS += sbusfb.o
M_OBJS += cgfourteenfb.o
endif
endif
+ ifeq ($(CONFIG_FB_P9100),y)
+ L_OBJS += p9100fb.o
+ else
+ ifeq ($(CONFIG_FB_P9100),m)
+ M_OBJS += p9100fb.o
+ endif
+ endif
ifeq ($(CONFIG_FB_LEO),y)
L_OBJS += leofb.o
else
@@ -324,6 +344,13 @@ else
M_OBJS += cgfourteenfb.o
endif
endif
+ ifeq ($(CONFIG_FB_P9100),y)
+ M_OBJS += p9100fb.o
+ else
+ ifeq ($(CONFIG_FB_P9100),m)
+ M_OBJS += p9100fb.o
+ endif
+ endif
ifeq ($(CONFIG_FB_LEO),y)
M_OBJS += leofb.o
else
diff --git a/drivers/video/S3triofb.c b/drivers/video/S3triofb.c
index c83c83c96..22fb32ab1 100644
--- a/drivers/video/S3triofb.c
+++ b/drivers/video/S3triofb.c
@@ -99,7 +99,7 @@ static int s3trio_ioctl(struct inode *inode, struct file *file, u_int cmd,
* Interface to the low level console driver
*/
-void s3triofb_init(void);
+int s3triofb_init(void);
static int s3triofbcon_switch(int con, struct fb_info *info);
static int s3triofbcon_updatevar(int con, struct fb_info *info);
static void s3triofbcon_blank(int blank, struct fb_info *info);
@@ -288,7 +288,7 @@ static int s3trio_ioctl(struct inode *inode, struct file *file, u_int cmd,
return -EINVAL;
}
-__initfunc(void s3triofb_init(void))
+int __init s3triofb_init(void)
{
#ifdef __powerpc__
/* We don't want to be called like this. */
@@ -296,9 +296,10 @@ __initfunc(void s3triofb_init(void))
#else /* !__powerpc__ */
/* To be merged with cybervision */
#endif /* !__powerpc__ */
+ return 0;
}
-__initfunc(void s3trio_resetaccel(void)) {
+void __init s3trio_resetaccel(void){
#define EC01_ENH_ENB 0x0005
@@ -341,7 +342,7 @@ __initfunc(void s3trio_resetaccel(void)) {
outw( MF_PIX_CONTROL | MFA_SRC_FOREGR_MIX, 0xbee8);
}
-__initfunc(int s3trio_init(struct device_node *dp)) {
+int __init s3trio_init(struct device_node *dp){
u_char bus, dev;
unsigned int t32;
@@ -402,7 +403,7 @@ __initfunc(int s3trio_init(struct device_node *dp)) {
* We heavily rely on OF for the moment. This needs fixing.
*/
-__initfunc(void s3triofb_init_of(struct device_node *dp))
+void __init s3triofb_init_of(struct device_node *dp)
{
int i, *pp, len;
unsigned long address;
@@ -445,11 +446,11 @@ __initfunc(void s3triofb_init_of(struct device_node *dp))
s3trio_init(dp);
address = 0xc6000000;
s3trio_base = ioremap(address,64*1024*1024);
- fb_fix.smem_start = (char *)address;
+ fb_fix.smem_start = address;
fb_fix.type = FB_TYPE_PACKED_PIXELS;
fb_fix.type_aux = 0;
fb_fix.accel = FB_ACCEL_S3_TRIO64;
- fb_fix.mmio_start = (char *)address+0x1000000;
+ fb_fix.mmio_start = address+0x1000000;
fb_fix.mmio_len = 0x1000000;
fb_fix.xpanstep = 1;
@@ -721,9 +722,9 @@ static void do_install_cmap(int con, struct fb_info *info)
s3trio_setcolreg, &fb_info);
}
-void s3triofb_setup(char *options, int *ints) {
+int s3triofb_setup(char *options) {
- return;
+ return 0;
}
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
index 42485a999..8efdcbe59 100644
--- a/drivers/video/acornfb.c
+++ b/drivers/video/acornfb.c
@@ -34,6 +34,7 @@
#include <video/fbcon-cfb4.h>
#include <video/fbcon-cfb8.h>
#include <video/fbcon-cfb16.h>
+#include <video/fbcon-cfb32.h>
/*
* Default resolution.
@@ -58,7 +59,7 @@
#endif
#define EXTEND8(x) ((x)|(x)<<8)
-#define EXTEND4(x) ((x)|(x)<<4|(x)<<8|(x)<<16)
+#define EXTEND4(x) ((x)|(x)<<4|(x)<<8|(x)<<12)
struct vidc20_palette {
u_int red:8;
@@ -554,14 +555,14 @@ acornfb_vidc20_find_rates(struct vidc_timing *vidc,
bandwidth = var->pixclock * 8 / var->bits_per_pixel;
/* Encode bandwidth as VIDC20 setting */
- if (bandwidth > 16667*2)
- vidc->control |= VIDC20_CTRL_FIFO_16;
- else if (bandwidth > 13333*2)
- vidc->control |= VIDC20_CTRL_FIFO_20;
- else if (bandwidth > 11111*2)
- vidc->control |= VIDC20_CTRL_FIFO_24;
+ if (bandwidth > 33334)
+ vidc->control |= VIDC20_CTRL_FIFO_16; /* < 30.0MB/s */
+ else if (bandwidth > 26666)
+ vidc->control |= VIDC20_CTRL_FIFO_20; /* < 37.5MB/s */
+ else if (bandwidth > 22222)
+ vidc->control |= VIDC20_CTRL_FIFO_24; /* < 45.0MB/s */
else
- vidc->control |= VIDC20_CTRL_FIFO_28;
+ vidc->control |= VIDC20_CTRL_FIFO_28; /* > 45.0MB/s */
/* Find the PLL values */
vidc->pll_ctl = acornfb_vidc20_find_pll(var->pixclock / div);
@@ -742,7 +743,7 @@ acornfb_palette_decode(u_int regno, u_int *red, u_int *green, u_int *blue,
* Before selecting the timing parameters, adjust
* the resolution to fit the rules.
*/
-static void
+static int
acornfb_pre_adjust_timing(struct fb_var_screeninfo *var, int con)
{
u_int font_line_len;
@@ -785,6 +786,13 @@ acornfb_pre_adjust_timing(struct fb_var_screeninfo *var, int con)
font_line_len = var->xres * var->bits_per_pixel * fontht / 8;
min_size = var->xres * var->yres * var->bits_per_pixel / 8;
+ /*
+ * If minimum screen size is greater than that we have
+ * available, reject it.
+ */
+ if (min_size > current_par.screen_size)
+ return -EINVAL;
+
/* Find int 'y', such that y * fll == s * sam < maxsize
* y = s * sam / fll; s = maxsize / sam
*/
@@ -820,6 +828,7 @@ acornfb_pre_adjust_timing(struct fb_var_screeninfo *var, int con)
if (var->yoffset + var->yres > var->yres_virtual)
var->yoffset = var->yres_virtual - var->yres;
}
+ return 0;
}
/*
@@ -897,32 +906,75 @@ acornfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
return 0;
}
+/*
+ * We have to take note of the VIDC20's 16-bit palette here.
+ * The VIDC20 looks up a 16 bit pixel as follows:
+ *
+ * bits 111111
+ * 5432109876543210
+ * red ++++++++ (8 bits, 7 to 0)
+ * green ++++++++ (8 bits, 11 to 4)
+ * blue ++++++++ (8 bits, 15 to 8)
+ *
+ * We use a pixel which looks like:
+ *
+ * bits 111111
+ * 5432109876543210
+ * red +++++ (5 bits, 4 to 0)
+ * green +++++ (5 bits, 9 to 5)
+ * blue +++++ (5 bits, 14 to 10)
+ */
static int
acornfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int trans, struct fb_info *info)
{
union palette pal;
+ int bpp = fb_display[current_par.currcon].var.bits_per_pixel;
if (regno >= current_par.palette_size)
return 1;
pal = acornfb_palette_encode(regno, red, green, blue, trans);
- acornfb_palette_write(regno, pal);
current_par.palette[regno] = pal;
+#ifdef HAS_VIDC20
if (regno < 16) {
- switch (info->disp->var.bits_per_pixel) {
+ switch (bpp) {
#ifdef FBCON_HAS_CFB16
- case 16: /* RGB555 */
- current_par.cmap.cfb16[regno] = (regno << 10) | (regno << 5) | regno;
+ case 16:
+ current_par.cmap.cfb16[regno] =
+ regno | regno << 5 | regno << 10;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB32
+ case 32:
+ current_par.cmap.cfb32[regno] =
+ regno | regno << 8 | regno << 16;
break;
#endif
-
default:
break;
}
}
+#ifdef FBCON_HAS_CFB16
+ if (bpp == 16) {
+ int i;
+
+ pal.p = 0;
+ outl(0x10000000, IO_VIDC_BASE);
+ for (i = 0; i < 256; i += 1) {
+ pal.vidc20.red = current_par.palette[ i & 31].vidc20.red;
+ pal.vidc20.green = current_par.palette[(i >> 1) & 31].vidc20.green;
+ pal.vidc20.blue = current_par.palette[(i >> 2) & 31].vidc20.blue;
+ outl(pal.p, IO_VIDC_BASE);
+ /* Palette register pointer auto-increments */
+ }
+ } else
+#endif
+#endif
+ acornfb_palette_write(regno, pal);
+
return 0;
}
@@ -965,6 +1017,8 @@ acornfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
static int
acornfb_decode_var(struct fb_var_screeninfo *var, int con, int *visual)
{
+ int err;
+
switch (var->bits_per_pixel) {
#ifdef FBCON_HAS_MFB
case 1:
@@ -990,10 +1044,18 @@ acornfb_decode_var(struct fb_var_screeninfo *var, int con, int *visual)
*visual = FB_VISUAL_PSEUDOCOLOR;
break;
#endif
+#ifdef HAS_VIDC20
+#ifdef FBCON_HAS_CFB16
case 16:
- case 24:
+ *visual = FB_VISUAL_DIRECTCOLOR;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB32
case 32:
*visual = FB_VISUAL_TRUECOLOR;
+ break;
+#endif
+#endif
default:
return -EINVAL;
}
@@ -1002,20 +1064,52 @@ acornfb_decode_var(struct fb_var_screeninfo *var, int con, int *visual)
return -EINVAL;
/*
- * Adjust the resolution before using it.
+ * Validate and adjust the resolution
+ * before using it.
*/
- acornfb_pre_adjust_timing(var, con);
+ err = acornfb_pre_adjust_timing(var, con);
+ if (err)
+ return err;
#if defined(HAS_VIDC20)
- var->red.length = 8;
- var->transp.length = 4;
+ switch (var->bits_per_pixel) {
+ case 1: case 2: case 4: case 8:
+ var->red.offset = 0;
+ var->red.length = 8;
+ var->green = var->red;
+ var->blue = var->red;
+ var->transp.offset = 0;
+ var->transp.length = 4;
+ break;
+
+ case 16:
+ var->red.offset = 0;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 5;
+ var->blue.offset = 10;
+ var->blue.length = 5;
+ var->transp.offset = 15;
+ var->transp.length = 1;
+ break;
+
+ case 32:
+ var->red.offset = 0;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 16;
+ var->blue.length = 8;
+ var->transp.offset = 24;
+ var->transp.length = 4;
+ break;
+ }
#elif defined(HAS_VIDC)
var->red.length = 4;
+ var->green = var->red;
+ var->blue = var->red;
var->transp.length = 1;
#endif
- var->green = var->red;
- var->blue = var->red;
-
/*
* Now adjust the timing parameters
*/
@@ -1037,7 +1131,7 @@ acornfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
else
display = &global_disp;
- fix->smem_start = (char *)current_par.screen_base_p;
+ fix->smem_start = current_par.screen_base_p;
fix->smem_len = current_par.screen_size;
fix->type = display->type;
fix->type_aux = display->type_aux;
@@ -1153,11 +1247,18 @@ acornfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
#endif
#ifdef FBCON_HAS_CFB16
case 16:
- current_par.palette_size = VIDC_PALETTE_SIZE;
+ current_par.palette_size = 32;
display->dispsw = &fbcon_cfb16;
display->dispsw_data = current_par.cmap.cfb16;
break;
#endif
+#ifdef FBCON_HAS_CFB32
+ case 32:
+ current_par.palette_size = VIDC_PALETTE_SIZE;
+ display->dispsw = &fbcon_cfb32;
+ display->dispsw_data = current_par.cmap.cfb32;
+ break;
+#endif
default:
display->dispsw = &fbcon_dummy;
break;
@@ -1290,19 +1391,32 @@ acornfb_switch(int con, struct fb_info *info)
static void
acornfb_blank(int blank, struct fb_info *info)
{
- int i;
+ union palette p;
+ int i, bpp = fb_display[current_par.currcon].var.bits_per_pixel;
- if (blank)
+ if (bpp != 16) {
for (i = 0; i < current_par.palette_size; i++) {
- union palette p;
-
- p = acornfb_palette_encode(i, 0, 0, 0, 0);
+ if (blank)
+ p = acornfb_palette_encode(i, 0, 0, 0, 0);
+ else
+ p = current_par.palette[i];
acornfb_palette_write(i, p);
}
- else
- for (i = 0; i < current_par.palette_size; i++)
+ } else {
+ p.p = 0;
+
+ for (i = 0; i < 256; i++) {
+ if (blank)
+ p = acornfb_palette_encode(i, 0, 0, 0, 0);
+ else {
+ p.vidc20.red = current_par.palette[ i & 31].vidc20.red;
+ p.vidc20.green = current_par.palette[(i >> 1) & 31].vidc20.green;
+ p.vidc20.blue = current_par.palette[(i >> 2) & 31].vidc20.blue;
+ }
acornfb_palette_write(i, current_par.palette[i]);
+ }
+ }
}
/*
@@ -1429,8 +1543,8 @@ static const struct modex_params modex_params[] __initdata = {
}
};
-__initfunc(static int
-acornfb_lookup_timing(struct fb_var_screeninfo *var))
+static int __init
+acornfb_lookup_timing(struct fb_var_screeninfo *var)
{
const struct modex_params *x;
const struct modey_params *y;
@@ -1518,8 +1632,8 @@ found:
return 0;
}
-__initfunc(static void
-acornfb_init_fbinfo(void))
+static void __init
+acornfb_init_fbinfo(void)
{
static int first = 1;
@@ -1612,14 +1726,14 @@ acornfb_init_fbinfo(void))
* size can optionally be followed by 'M' or 'K' for
* MB or KB respectively.
*/
-__initfunc(static void
-acornfb_parse_font(char *opt))
+static void __init
+acornfb_parse_font(char *opt)
{
strcpy(fb_info.fontname, opt);
}
-__initfunc(static void
-acornfb_parse_mon(char *opt))
+static void __init
+acornfb_parse_mon(char *opt)
{
fb_info.monspecs.hfmin = simple_strtoul(opt, &opt, 0);
if (*opt == '-')
@@ -1652,8 +1766,8 @@ acornfb_parse_mon(char *opt))
init_var.height = simple_strtoul(opt + 1, NULL, 0);
}
-__initfunc(static void
-acornfb_parse_montype(char *opt))
+static void __init
+acornfb_parse_montype(char *opt)
{
current_par.montype = -2;
@@ -1694,8 +1808,8 @@ acornfb_parse_montype(char *opt))
}
}
-__initfunc(static void
-acornfb_parse_dram(char *opt))
+static void __init
+acornfb_parse_dram(char *opt)
{
unsigned int size;
@@ -1728,14 +1842,14 @@ static struct options {
{ NULL, NULL }
};
-__initfunc(void
-acornfb_setup(char *options, int *ints))
+int __init
+acornfb_setup(char *options)
{
struct options *optp;
char *opt;
if (!options || !*options)
- return;
+ return 0;
acornfb_init_fbinfo();
@@ -1759,14 +1873,15 @@ acornfb_setup(char *options, int *ints))
printk(KERN_ERR "acornfb: unknown parameter: %s\n",
opt);
}
+ return 0;
}
/*
* Detect type of monitor connected
* For now, we just assume SVGA
*/
-__initfunc(static int
-acornfb_detect_monitortype(void))
+static int __init
+acornfb_detect_monitortype(void)
{
return 4;
}
@@ -1802,8 +1917,8 @@ free_unused_pages(unsigned int virtual_start, unsigned int virtual_end)
printk("acornfb: freed %dK memory\n", mb_freed);
}
-__initfunc(void
-acornfb_init(void))
+int __init
+acornfb_init(void)
{
unsigned long size;
u_int h_sync, v_sync;
@@ -1841,7 +1956,7 @@ acornfb_init(void))
size = PAGE_ALIGN(size);
-#ifdef CONFIG_ARCH_RPC
+#if defined(HAS_VIDC20)
if (!current_par.using_vram) {
/*
* RiscPC needs to allocate the DRAM memory
@@ -1849,17 +1964,30 @@ acornfb_init(void))
* VRAM. Archimedes/A5000 machines use a
* fixed address for their framebuffers.
*/
- current_par.screen_base = (unsigned long)kmalloc(size, GFP_KERNEL);
+ int order = 0;
+ unsigned long page, top;
+ while (size > (PAGE_SIZE * (1 << order)))
+ order++;
+ current_par.screen_base = __get_free_pages(GFP_KERNEL, order);
if (current_par.screen_base == 0) {
printk(KERN_ERR "acornfb: unable to allocate screen "
"memory\n");
return;
}
+ top = current_par.screen_base + (PAGE_SIZE * (1 << order));
+ /* Mark the framebuffer pages as reserved so mmap will work. */
+ for (page = current_par.screen_base;
+ page < PAGE_ALIGN(current_par.screen_base + size);
+ page += PAGE_SIZE)
+ mem_map[MAP_NR(page)].flags |= (1 << PG_reserved);
+ /* Hand back any excess pages that we allocated. */
+ for (page = current_par.screen_base + size; page < top; page += PAGE_SIZE)
+ free_page(page);
current_par.screen_base_p =
virt_to_phys(current_par.screen_base);
}
#endif
-#if defined(CONFIG_ARCH_A5K) || defined(CONFIG_ARCH_ARC)
+#if defined(HAS_VIDC)
#define MAX_SIZE 480*1024
/*
* Limit maximum screen size.
@@ -1904,5 +2032,7 @@ acornfb_init(void))
VIDC_NAME, init_var.xres, init_var.yres,
h_sync / 1000, h_sync % 1000, v_sync);
- register_framebuffer(&fb_info);
+ if (register_framebuffer(&fb_info) < 0)
+ return -EINVAL;
+ return 0;
}
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 2aa4a29e3..47531e1bb 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -805,138 +805,86 @@ static char amifb_name[16] = "Amiga ";
*
*/
-static struct fb_videomode amifb_predefined[] __initdata = {
+static struct fb_videomode ami_modedb[] __initdata = {
/*
* AmigaOS Video Modes
+ *
+ * If you change these, make sure to update DEFMODE_* as well!
*/
{
- "ntsc", { /* 640x200, 15 kHz, 60 Hz (NTSC) */
- 640, 200, 640, 200, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_HIRES, 106, 86, 44, 16, 76, 2,
- FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }
+ /* 640x200, 15 kHz, 60 Hz (NTSC) */
+ "ntsc", 60, 640, 200, TAG_HIRES, 106, 86, 44, 16, 76, 2,
+ FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
}, {
- "ntsc-lace", { /* 640x400, 15 kHz, 60 Hz interlaced (NTSC) */
- 640, 400, 640, 400, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_HIRES, 106, 86, 88, 33, 76, 4,
- FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }
+ /* 640x400, 15 kHz, 60 Hz interlaced (NTSC) */
+ "ntsc-lace", 60, 640, TAG_HIRES, 106, 86, 88, 33, 76, 4,
+ FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
}, {
- "pal", { /* 640x256, 15 kHz, 50 Hz (PAL) */
- 640, 256, 640, 256, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_HIRES, 106, 86, 40, 14, 76, 2,
- FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }
+ /* 640x256, 15 kHz, 50 Hz (PAL) */
+ "pal", 50, 640, 256, TAG_HIRES, 106, 86, 40, 14, 76, 2,
+ FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
}, {
- "pal-lace", { /* 640x512, 15 kHz, 50 Hz interlaced (PAL) */
- 640, 512, 640, 512, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_HIRES, 106, 86, 80, 29, 76, 4,
- FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }
+ /* 640x512, 15 kHz, 50 Hz interlaced (PAL) */
+ "pal-lace", 50, 640, 512, TAG_HIRES, 106, 86, 80, 29, 76, 4,
+ FB_SYNC_BROADCAST, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
}, {
- "multiscan", { /* 640x480, 29 kHz, 57 Hz */
- 640, 480, 640, 480, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_SHRES, 96, 112, 29, 8, 72, 8,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }
+ /* 640x480, 29 kHz, 57 Hz */
+ "multiscan", 57, 640, 480, TAG_SHRES, 96, 112, 29, 8, 72, 8,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
}, {
- "multiscan-lace", { /* 640x960, 29 kHz, 57 Hz interlaced */
- 640, 960, 640, 960, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_SHRES, 96, 112, 58, 16, 72, 16,
- 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }
+ /* 640x960, 29 kHz, 57 Hz interlaced */
+ "multiscan-lace", 57, 640, 960, TAG_SHRES, 96, 112, 58, 16, 72, 16,
+ 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
}, {
- "euro36", { /* 640x200, 15 kHz, 72 Hz */
- 640, 200, 640, 200, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_HIRES, 92, 124, 6, 6, 52, 5,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }
+ /* 640x200, 15 kHz, 72 Hz */
+ "euro36", 72, 640, 200, TAG_HIRES, 92, 124, 6, 6, 52, 5,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
}, {
- "euro36-lace", { /* 640x400, 15 kHz, 72 Hz interlaced */
- 640, 400, 640, 400, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_HIRES, 92, 124, 12, 12, 52, 10,
- 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }
+ /* 640x400, 15 kHz, 72 Hz interlaced */
+ "euro36-lace", 72, 640, 400, TAG_HIRES, 92, 124, 12, 12, 52, 10,
+ 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
}, {
- "euro72", { /* 640x400, 29 kHz, 68 Hz */
- 640, 400, 640, 400, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_SHRES, 164, 92, 9, 9, 80, 8,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }
+ /* 640x400, 29 kHz, 68 Hz */
+ "euro72", 68, 640, 400, TAG_SHRES, 164, 92, 9, 9, 80, 8,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
}, {
- "euro72-lace", { /* 640x800, 29 kHz, 68 Hz interlaced */
- 640, 800, 640, 800, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_SHRES, 164, 92, 18, 18, 80, 16,
- 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }
+ /* 640x800, 29 kHz, 68 Hz interlaced */
+ "euro72-lace", 68, 640, 800, TAG_SHRES, 164, 92, 18, 18, 80, 16,
+ 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
}, {
- "super72", { /* 800x300, 23 kHz, 70 Hz */
- 800, 300, 800, 300, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_SHRES, 212, 140, 10, 11, 80, 7,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }
+ /* 800x300, 23 kHz, 70 Hz */
+ "super72", 70, 800, 300, TAG_SHRES, 212, 140, 10, 11, 80, 7,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
}, {
- "super72-lace", { /* 800x600, 23 kHz, 70 Hz interlaced */
- 800, 600, 800, 600, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_SHRES, 212, 140, 20, 22, 80, 14,
- 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }
+ /* 800x600, 23 kHz, 70 Hz interlaced */
+ "super72-lace", 70, 800, 600, TAG_SHRES, 212, 140, 20, 22, 80, 14,
+ 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
}, {
- "dblntsc", { /* 640x200, 27 kHz, 57 Hz doublescan */
- 640, 200, 640, 200, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_SHRES, 196, 124, 18, 17, 80, 4,
- 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP
- }
+ /* 640x200, 27 kHz, 57 Hz doublescan */
+ "dblntsc", 57, 640, 200, TAG_SHRES, 196, 124, 18, 17, 80, 4,
+ 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP
}, {
- "dblntsc-ff", { /* 640x400, 27 kHz, 57 Hz */
- 640, 400, 640, 400, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_SHRES, 196, 124, 36, 35, 80, 7,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }
+ /* 640x400, 27 kHz, 57 Hz */
+ "dblntsc-ff", 57, 640, 400, TAG_SHRES, 196, 124, 36, 35, 80, 7,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
}, {
- "dblntsc-lace", { /* 640x800, 27 kHz, 57 Hz interlaced */
- 640, 800, 640, 800, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_SHRES, 196, 124, 72, 70, 80, 14,
- 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }
+ /* 640x800, 27 kHz, 57 Hz interlaced */
+ "dblntsc-lace", 57, 640, 800, TAG_SHRES, 196, 124, 72, 70, 80, 14,
+ 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
}, {
- "dblpal", { /* 640x256, 27 kHz, 47 Hz doublescan */
- 640, 256, 640, 256, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_SHRES, 196, 124, 14, 13, 80, 4,
- 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP
- }
+ /* 640x256, 27 kHz, 47 Hz doublescan */
+ "dblpal", 47, 640, 256, TAG_SHRES, 196, 124, 14, 13, 80, 4,
+ 0, FB_VMODE_DOUBLE | FB_VMODE_YWRAP
}, {
- "dblpal-ff", { /* 640x512, 27 kHz, 47 Hz */
- 640, 512, 640, 512, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_SHRES, 196, 124, 28, 27, 80, 7,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }
+ /* 640x512, 27 kHz, 47 Hz */
+ "dblpal-ff", 47, 640, 512, TAG_SHRES, 196, 124, 28, 27, 80, 7,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
}, {
- "dblpal-lace", { /* 640x1024, 27 kHz, 47 Hz interlaced */
- 640, 1024, 640, 1024, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_SHRES, 196, 124, 56, 54, 80, 14,
- 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
- }
+ /* 640x1024, 27 kHz, 47 Hz interlaced */
+ "dblpal-lace", 47, 640, 1024, TAG_SHRES, 196, 124, 56, 54, 80, 14,
+ 0, FB_VMODE_INTERLACED | FB_VMODE_YWRAP
},
/*
@@ -944,19 +892,13 @@ static struct fb_videomode amifb_predefined[] __initdata = {
*/
{
- "vga", { /* 640x480, 31 kHz, 60 Hz (VGA) */
- 640, 480, 640, 480, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_SHRES, 64, 96, 30, 9, 112, 2,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }
+ /* 640x480, 31 kHz, 60 Hz (VGA) */
+ "vga", 60, 640, 480, TAG_SHRES, 64, 96, 30, 9, 112, 2,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
}, {
- "vga70", { /* 640x400, 31 kHz, 70 Hz (VGA) */
- 640, 400, 640, 400, 0, 0, 4, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_SHRES, 64, 96, 35, 12, 112, 2,
- FB_SYNC_VERT_HIGH_ACT | FB_SYNC_COMP_HIGH_ACT, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }
+ /* 640x400, 31 kHz, 70 Hz (VGA) */
+ "vga70", 70, 640, 400, TAG_SHRES, 64, 96, 35, 12, 112, 2,
+ FB_SYNC_VERT_HIGH_ACT | FB_SYNC_COMP_HIGH_ACT, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
},
#if 0
@@ -967,41 +909,36 @@ static struct fb_videomode amifb_predefined[] __initdata = {
*/
{
- "a2024-10", { /* 1024x800, 10 Hz */
- 1024, 800, 1024, 800, 0, 0, 2, 0,
- {0, 2, 0}, {0, 2, 0}, {0, 2, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_HIRES, 0, 0, 0, 0, 0, 0,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }
+ /* 1024x800, 10 Hz */
+ "a2024-10", 10, 1024, 800, TAG_HIRES, 0, 0, 0, 0, 0, 0,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
}, {
- "a2024-15", { /* 1024x800, 15 Hz */
- 1024, 800, 1024, 800, 0, 0, 2, 0,
- {0, 2, 0}, {0, 2, 0}, {0, 2, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, TAG_HIRES, 0, 0, 0, 0, 0, 0,
- 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
- }
+ /* 1024x800, 15 Hz */
+ "a2024-15", 10, 1024, 800, TAG_HIRES, 0, 0, 0, 0, 0, 0,
+ 0, FB_VMODE_NONINTERLACED | FB_VMODE_YWRAP
}
#endif
};
-#define NUM_TOTAL_MODES arraysize(amifb_predefined)
+#define NUM_TOTAL_MODES arraysize(ami_modedb)
-static int amifb_ilbm = 0; /* interleaved or normal bitplanes */
-static int amifb_inverse = 0;
-static int amifb_usermode __initdata = 0;
-static int amifb_userdepth __initdata = -1;
+static const char *mode_option __initdata = NULL;
+static int round_down_bpp = 1; /* for mode probing */
/*
* Some default modes
*/
-#define DEFMODE_PAL "pal" /* for PAL OCS/ECS */
-#define DEFMODE_NTSC "ntsc" /* for NTSC OCS/ECS */
-#define DEFMODE_AMBER_PAL "pal-lace" /* for flicker fixed PAL (A3000) */
-#define DEFMODE_AMBER_NTSC "ntsc-lace" /* for flicker fixed NTSC (A3000) */
-#define DEFMODE_AGA "vga70" /* for AGA */
-static struct fb_var_screeninfo amifb_default;
+#define DEFMODE_PAL 2 /* "pal" for PAL OCS/ECS */
+#define DEFMODE_NTSC 0 /* "ntsc" for NTSC OCS/ECS */
+#define DEFMODE_AMBER_PAL 3 /* "pal-lace" for flicker fixed PAL (A3000) */
+#define DEFMODE_AMBER_NTSC 1 /* "ntsc-lace" for flicker fixed NTSC (A3000) */
+#define DEFMODE_AGA 19 /* "vga70" for AGA */
+
+
+static int amifb_ilbm = 0; /* interleaved or normal bitplanes */
+static int amifb_inverse = 0;
/*
@@ -1162,7 +1099,7 @@ static u_short sprfetchmode[3] = {
* Interface used by the world
*/
-void amifb_setup(char *options, int *ints);
+int amifb_setup(char*);
static int amifb_open(struct fb_info *info, int user);
static int amifb_release(struct fb_info *info, int user);
@@ -1193,7 +1130,7 @@ static int amifb_set_cursorstate(struct fb_cursorstate *state, int con);
* Interface to the low level console driver
*/
-void amifb_init(void);
+int amifb_init(void);
static int amifbcon_switch(int con, struct fb_info *info);
static int amifbcon_updatevar(int con, struct fb_info *info);
static void amifbcon_blank(int blank, struct fb_info *info);
@@ -1205,8 +1142,6 @@ static void amifbcon_blank(int blank, struct fb_info *info);
static void do_install_cmap(int con, struct fb_info *info);
static int flash_cursor(void);
static void amifb_interrupt(int irq, void *dev_id, struct pt_regs *fp);
-static void get_video_mode(const char *name);
-static void check_default_mode(void);
static u_long chipalloc(u_long size);
static char *strtoke(char *s,const char *ct);
@@ -1259,8 +1194,7 @@ static struct fb_ops amifb_ops = {
amifb_pan_display, amifb_ioctl
};
-
-__initfunc(void amifb_setup(char *options, int *ints))
+int __init amifb_setup(char *options)
{
char *this_opt;
char mcap_spec[80];
@@ -1269,11 +1203,9 @@ __initfunc(void amifb_setup(char *options, int *ints))
fb_info.fontname[0] = '\0';
if (!options || !*options)
- return;
+ return 0;
for (this_opt = strtok(options, ","); this_opt; this_opt = strtok(NULL, ",")) {
- char *p;
-
if (!strcmp(this_opt, "inverse")) {
amifb_inverse = 1;
fb_invert_cmaps();
@@ -1285,54 +1217,8 @@ __initfunc(void amifb_setup(char *options, int *ints))
strcpy(fb_info.fontname, this_opt+5);
else if (!strncmp(this_opt, "fstart:", 7))
min_fstrt = simple_strtoul(this_opt+7, NULL, 0);
- else if (!strncmp(this_opt, "depth:", 6))
- amifb_userdepth = simple_strtoul(this_opt+6, NULL, 0);
- else if (!strncmp(this_opt, "size:", 5)) {
- p = this_opt + 5;
- if (*p != ';')
- amifb_default.xres = simple_strtoul(p, NULL, 0);
- if (!(p = strchr(p, ';')))
- continue;
- if (*++p != ';')
- amifb_default.yres = simple_strtoul(p, NULL, 0);
- if (!(p = strchr(p, ';')))
- continue;
- if (*++p != ';')
- amifb_default.xres_virtual = simple_strtoul(p, NULL, 0);
- if (!(p = strchr(p, ';')))
- continue;
- if (*++p != ';')
- amifb_default.yres_virtual = simple_strtoul(p, NULL, 0);
- if (!(p = strchr(p, ';')))
- continue;
- if (*++p)
- amifb_default.bits_per_pixel = simple_strtoul(p, NULL, 0);
- } else if (!strncmp(this_opt, "timing:", 7)) {
- p = this_opt + 7;
- if (*p != ';')
- amifb_default.left_margin = simple_strtoul(p, NULL, 0);
- if (!(p = strchr(p, ';')))
- continue;
- if (*++p != ';')
- amifb_default.right_margin = simple_strtoul(p, NULL, 0);
- if (!(p = strchr(p, ';')))
- continue;
- if (*++p != ';')
- amifb_default.upper_margin = simple_strtoul(p, NULL, 0);
- if (!(p = strchr(p, ';')))
- continue;
- if (*++p)
- amifb_default.lower_margin = simple_strtoul(p, NULL, 0);
- } else if (!strncmp(this_opt, "sync:", 5)) {
- p = this_opt + 5;
- if (*p != ';')
- amifb_default.hsync_len = simple_strtoul(p, NULL, 0);
- if (!(p = strchr(p, ';')))
- continue;
- if (*++p)
- amifb_default.vsync_len = simple_strtoul(p, NULL, 0);
- } else
- get_video_mode(this_opt);
+ else
+ mode_option = this_opt;
}
if (min_fstrt < 48)
@@ -1375,6 +1261,7 @@ __initfunc(void amifb_setup(char *options, int *ints))
cap_invalid:
;
}
+ return 0;
}
/*
@@ -1715,13 +1602,15 @@ static int amifb_set_cursorstate(struct fb_cursorstate *state, int con)
* Initialisation
*/
-__initfunc(void amifb_init(void))
+int __init amifb_init(void)
{
int tag, i;
u_long chipptr;
+ u_int defmode;
+ struct fb_var_screeninfo var;
if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_VIDEO))
- return;
+ return -ENXIO;
/*
* TODO: where should we put this? The DMI Resolver doesn't have a
@@ -1732,7 +1621,7 @@ __initfunc(void amifb_init(void))
if (amifb_resolver){
custom.dmacon = DMAF_MASTER | DMAF_RASTER | DMAF_COPPER |
DMAF_BLITTER | DMAF_SPRITE;
- return;
+ return 0;
}
#endif
@@ -1748,9 +1637,8 @@ default_chipset:
maxdepth[TAG_HIRES] = 4;
maxdepth[TAG_LORES] = 6;
maxfmode = TAG_FMODE_1;
- if (!amifb_usermode) /* Set the Default Video Mode */
- get_video_mode(amiga_vblank == 50 ?
- DEFMODE_PAL : DEFMODE_NTSC);
+ defmode = amiga_vblank == 50 ? DEFMODE_PAL
+ : DEFMODE_NTSC;
videomemorysize = VIDEOMEMSIZE_OCS;
break;
#endif /* CONFIG_FB_AMIGA_OCS */
@@ -1763,14 +1651,12 @@ default_chipset:
maxdepth[TAG_HIRES] = 4;
maxdepth[TAG_LORES] = 6;
maxfmode = TAG_FMODE_1;
- if (!amifb_usermode) { /* Set the Default Video Mode */
- if (AMIGAHW_PRESENT(AMBER_FF))
- get_video_mode(amiga_vblank == 50 ?
- DEFMODE_AMBER_PAL : DEFMODE_AMBER_NTSC);
- else
- get_video_mode(amiga_vblank == 50 ?
- DEFMODE_PAL : DEFMODE_NTSC);
- }
+ if (AMIGAHW_PRESENT(AMBER_FF))
+ defmode = amiga_vblank == 50 ? DEFMODE_AMBER_PAL
+ : DEFMODE_AMBER_NTSC;
+ else
+ defmode = amiga_vblank == 50 ? DEFMODE_PAL
+ : DEFMODE_NTSC;
if (amiga_chip_avail()-CHIPRAM_SAFETY_LIMIT >
VIDEOMEMSIZE_ECS_1M)
videomemorysize = VIDEOMEMSIZE_ECS_2M;
@@ -1787,8 +1673,7 @@ default_chipset:
maxdepth[TAG_HIRES] = 8;
maxdepth[TAG_LORES] = 8;
maxfmode = TAG_FMODE_4;
- if (!amifb_usermode) /* Set the Default Video Mode */
- get_video_mode(DEFMODE_AGA);
+ defmode = DEFMODE_AGA;
if (amiga_chip_avail()-CHIPRAM_SAFETY_LIMIT >
VIDEOMEMSIZE_AGA_1M)
videomemorysize = VIDEOMEMSIZE_AGA_2M;
@@ -1803,7 +1688,7 @@ default_chipset:
strcat(amifb_name, "Unknown");
goto default_chipset;
#else /* CONFIG_FB_AMIGA_OCS */
- return;
+ return -ENXIO;
#endif /* CONFIG_FB_AMIGA_OCS */
break;
}
@@ -1824,23 +1709,13 @@ default_chipset:
* Replace the Tag Values with the Real Pixel Clock Values
*/
- if (amifb_userdepth != -1)
- amifb_default.bits_per_pixel = amifb_userdepth;
for (i = 0; i < NUM_TOTAL_MODES; i++) {
- struct fb_var_screeninfo *var = &amifb_predefined[i].var;
- tag = var->pixclock;
+ struct fb_videomode *mode = &ami_modedb[i];
+ tag = mode->pixclock;
if (tag == TAG_SHRES || tag == TAG_HIRES || tag == TAG_LORES) {
- var->pixclock = pixclock[tag];
- if (var->bits_per_pixel > maxdepth[tag])
- var->bits_per_pixel = maxdepth[tag];
+ mode->pixclock = pixclock[tag];
}
}
- tag = amifb_default.pixclock;
- if (tag == TAG_SHRES || tag == TAG_HIRES || tag == TAG_LORES) {
- amifb_default.pixclock = pixclock[tag];
- if (amifb_default.bits_per_pixel > maxdepth[tag])
- amifb_default.bits_per_pixel = maxdepth[tag];
- }
/*
* These monitor specs are for a typical Amiga monitor (e.g. A1960)
@@ -1862,6 +1737,11 @@ default_chipset:
fb_info.blank = &amifbcon_blank;
fb_info.flags = FBINFO_FLAG_DEFAULT;
+ if (!fb_find_mode(&var, &fb_info, mode_option, ami_modedb,
+ NUM_TOTAL_MODES, &ami_modedb[defmode], 4))
+ panic("Can't find any usable video mode");
+
+ round_down_bpp = 0;
chipptr = chipalloc(videomemorysize+
SPRITEMEMSIZE+
DUMMYSPRITEMEMSIZE+
@@ -1904,9 +1784,7 @@ default_chipset:
ami_init_copper();
- check_default_mode();
-
- if (request_irq(IRQ_AMIGA_AUTO_3, amifb_interrupt, IRQ_FLG_LOCK,
+ if (request_irq(IRQ_AMIGA_AUTO_3, amifb_interrupt, 0,
"fb vertb handler", NULL))
panic("Couldn't add vblank interrupt\n");
ami_intena_vals[IRQ_AMIGA_VERTB] = IF_COPER;
@@ -1914,10 +1792,10 @@ default_chipset:
custom.intena = IF_VERTB;
custom.intena = IF_SETCLR | IF_COPER;
- amifb_set_var(&amifb_default, -1, &fb_info);
+ amifb_set_var(&var, -1, &fb_info);
if (register_framebuffer(&fb_info) < 0)
- return;
+ return -EINVAL;
printk("fb%d: %s frame buffer device, using %ldK of video memory\n",
GET_FB_IDX(fb_info.node), fb_info.modename,
@@ -1925,6 +1803,8 @@ default_chipset:
/* TODO: This driver cannot be unloaded yet */
MOD_INC_USE_COUNT;
+
+ return 0;
}
static int amifbcon_switch(int con, struct fb_info *info)
@@ -2050,47 +1930,10 @@ static void amifb_interrupt(int irq, void *dev_id, struct pt_regs *fp)
}
/*
- * Get a Video Mode
- */
-
-__initfunc(static void get_video_mode(const char *name))
-{
- int i;
-
- for (i = 0; i < NUM_TOTAL_MODES; i++) {
- if (!strcmp(name, amifb_predefined[i].name)) {
- amifb_default = amifb_predefined[i].var;
- amifb_usermode = i;
- return;
- }
- }
-}
-
- /*
- * Probe the Video Modes
- */
-
-__initfunc(static void check_default_mode(void))
-{
- struct amifb_par par;
- int mode;
-
- if (!ami_decode_var(&amifb_default, &par))
- return;
- printk("Can't use default video mode. Probing video modes...\n");
- for (mode = 0; mode < NUM_TOTAL_MODES; mode++)
- if (!ami_decode_var(&amifb_predefined[mode].var, &par)) {
- amifb_default = amifb_predefined[mode].var;
- return;
- }
- panic("Can't find any usable video mode");
-}
-
- /*
* Allocate, Clear and Align a Block of Chip Memory
*/
-__initfunc(static u_long chipalloc(u_long size))
+static u_long __init chipalloc(u_long size)
{
u_long ptr;
@@ -2107,7 +1950,7 @@ __initfunc(static u_long chipalloc(u_long size))
* A strtok which returns empty strings, too
*/
-__initfunc(static char *strtoke(char *s,const char *ct))
+static char __init *strtoke(char *s,const char *ct)
{
char *sbegin, *send;
static char *ssave = NULL;
@@ -2138,7 +1981,7 @@ static int ami_encode_fix(struct fb_fix_screeninfo *fix,
{
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id, amifb_name);
- fix->smem_start = (char *)videomemory_phys;
+ fix->smem_start = videomemory_phys;
fix->smem_len = videomemorysize;
#ifdef FBCON_HAS_MFB
@@ -2215,8 +2058,12 @@ static int ami_decode_var(struct fb_var_screeninfo *var,
if (par->bpp < 1)
par->bpp = 1;
if (par->bpp > maxdepth[clk_shift]) {
- DPRINTK("invalid bpp\n");
- return -EINVAL;
+ if (round_down_bpp && maxdepth[clk_shift])
+ par->bpp = maxdepth[clk_shift];
+ else {
+ DPRINTK("invalid bpp\n");
+ return -EINVAL;
+ }
}
} else if (var->nonstd == FB_NONSTD_HAM) {
if (par->bpp < 6)
@@ -3314,7 +3161,7 @@ static void ami_set_sprite(void)
* Initialise the Copper Initialisation List
*/
-__initfunc(static void ami_init_copper(void))
+static void __init ami_init_copper(void)
{
copins *cop = copdisplay.init;
u_long p;
@@ -3520,8 +3367,7 @@ static void ami_rebuild_copper(void)
#ifdef MODULE
int init_module(void)
{
- amifb_init();
- return 0;
+ return amifb_init();
}
void cleanup_module(void)
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index e35a79e0b..8f163cd8c 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -2745,14 +2745,14 @@ atafb_blank(int blank, struct fb_info *info)
do_install_cmap(currcon, info);
}
-__initfunc(void atafb_init(void))
+int __init atafb_init(void)
{
int pad;
int detected_mode;
unsigned long mem_req;
if (!MACH_IS_ATARI)
- return;
+ return -ENXIO;
do {
#ifdef ATAFB_EXT
@@ -2828,9 +2828,12 @@ __initfunc(void atafb_init(void))
/* Map the video memory (physical address given) to somewhere
* in the kernel address space.
*/
- external_addr = ioremap_writethrough(external_addr, external_len);
+ external_addr =
+ ioremap_writethrough((unsigned long)external_addr,
+ external_len);
if (external_vgaiobase)
- external_vgaiobase = ioremap(external_vgaiobase, 0x10000 );
+ external_vgaiobase =
+ (unsigned long)ioremap(external_vgaiobase, 0x10000);
screen_base =
real_screen_base = external_addr;
screen_len = external_len & PAGE_MASK;
@@ -2855,7 +2858,7 @@ __initfunc(void atafb_init(void))
do_install_cmap(0, &fb_info);
if (register_framebuffer(&fb_info) < 0)
- return;
+ return -EINVAL;
printk("Determined %dx%d, depth %d\n",
disp.var.xres, disp.var.yres, disp.var.bits_per_pixel);
@@ -2868,6 +2871,8 @@ __initfunc(void atafb_init(void))
/* TODO: This driver cannot be unloaded yet */
MOD_INC_USE_COUNT;
+
+ return 0;
}
/* a strtok which returns empty strings, too */
@@ -2892,7 +2897,7 @@ static char * strtoke(char * s,const char * ct)
return sbegin;
}
-__initfunc(void atafb_setup( char *options, int *ints ))
+int __init atafb_setup( char *options )
{
char *this_opt;
int temp;
@@ -2907,7 +2912,7 @@ __initfunc(void atafb_setup( char *options, int *ints ))
fb_info.fontname[0] = '\0';
if (!options || !*options)
- return;
+ return 0;
for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) {
if (!*this_opt) continue;
@@ -3069,7 +3074,7 @@ __initfunc(void atafb_setup( char *options, int *ints ))
external_yres = yres;
external_depth = depth;
external_pmode = planes;
- external_addr = addr;
+ external_addr = (void *)addr;
external_len = len;
if (external_card_type == IS_MV300)
@@ -3143,13 +3148,13 @@ __initfunc(void atafb_setup( char *options, int *ints ))
user_invalid:
;
}
+ return 0;
}
#ifdef MODULE
int init_module(void)
{
- atafb_init();
- return 0;
+ return atafb_init();
}
void cleanup_module(void)
diff --git a/drivers/video/aty.h b/drivers/video/aty.h
index 667e7c3ec..e7b6620ad 100644
--- a/drivers/video/aty.h
+++ b/drivers/video/aty.h
@@ -88,6 +88,8 @@
#define MEM_VGA_WP_SEL 0x00B4 /* Dword offset 0_2D */
#define MEM_VGA_RP_SEL 0x00B8 /* Dword offset 0_2E */
+#define I2C_CNTL_1 0x00BC /* Dword offset 0_2F */
+
#define DAC_REGS 0x00C0 /* Dword offset 0_30 */
#define DAC_W_INDEX 0x00C0 /* Dword offset 0_30 */
#define DAC_DATA 0x00C1 /* Dword offset 0_30 */
diff --git a/drivers/video/atyfb.c b/drivers/video/atyfb.c
index 522b790ed..f12fec6e1 100644
--- a/drivers/video/atyfb.c
+++ b/drivers/video/atyfb.c
@@ -1,4 +1,4 @@
-/* $Id: atyfb.c,v 1.107 1999/06/08 19:59:03 geert Exp $
+/* $Id: atyfb.c,v 1.122 1999/09/06 20:44:08 geert Exp $
* linux/drivers/video/atyfb.c -- Frame buffer device for ATI Mach64
*
* Copyright (C) 1997-1998 Geert Uytterhoeven
@@ -72,8 +72,8 @@
#ifdef __sparc__
#include <asm/pbm.h>
#include <asm/fbio.h>
-#include <asm/uaccess.h>
#endif
+#include <asm/uaccess.h>
#include <video/fbcon.h>
#include <video/fbcon-cfb8.h>
@@ -89,8 +89,34 @@
*/
#undef DEBUG
+/* Definitions for the ICS 2595 == ATI 18818_1 Clockchip */
+
+#define REF_FREQ_2595 1432 /* 14.33 MHz (exact 14.31818) */
+#define REF_DIV_2595 46 /* really 43 on ICS 2595 !!! */
+ /* ohne Prescaler */
+#define MAX_FREQ_2595 15938 /* 159.38 MHz (really 170.486) */
+#define MIN_FREQ_2595 8000 /* 80.00 MHz ( 85.565) */
+ /* mit Prescaler 2, 4, 8 */
+#define ABS_MIN_FREQ_2595 1000 /* 10.00 MHz (really 10.697) */
+#define N_ADJ_2595 257
+
+#define STOP_BITS_2595 0x1800
+
+
+#define MIN_N_408 2
+
+#define MIN_N_1703 6
-#define GUI_RESERVE 0x00001000
+#define MIN_M 2
+#define MAX_M 30
+#define MIN_N 35
+#define MAX_N 255-8
+
+
+/* Make sure n * PAGE_SIZE is protected at end of Aperture for GUI-regs */
+/* - must be large enough to catch all GUI-Regs */
+/* - must be aligned to a PAGE boundary */
+#define GUI_RESERVE (1 * PAGE_SIZE)
#ifndef __powerpc__
@@ -126,6 +152,14 @@ struct pll_gx {
u8 n;
};
+struct pll_18818
+{
+ u32 program_bits;
+ u32 locationAddr;
+ u32 period_in_ps;
+ u32 post_divider;
+};
+
struct pll_ct {
u8 pll_ref_div;
u8 pll_gen_cntl;
@@ -136,6 +170,8 @@ struct pll_ct {
u8 pll_ext_cntl;
u32 dsp_config; /* Mach64 GTB DSP */
u32 dsp_on_off; /* Mach64 GTB DSP */
+ u8 mclk_post_div_real;
+ u8 vclk_post_div_real;
};
@@ -148,6 +184,7 @@ struct atyfb_par {
union {
struct pll_gx gx;
struct pll_ct ct;
+ struct pll_18818 ics2595;
} pll;
u32 accel_flags;
};
@@ -189,10 +226,12 @@ struct aty_cursor {
struct fb_info_aty {
struct fb_info fb_info;
+ struct fb_info_aty *next;
unsigned long ati_regbase_phys;
unsigned long ati_regbase;
unsigned long frame_buffer_phys;
unsigned long frame_buffer;
+ unsigned long clk_wr_offset;
struct pci_mmap_map *mmap_map;
struct aty_cursor *cursor;
struct aty_cmap_regs *aty_cmap_regs;
@@ -210,6 +249,7 @@ struct fb_info_aty {
u8 bus_type;
u8 ram_type;
u8 dac_type;
+ u8 dac_subtype;
u8 clk_type;
u8 mem_refresh_rate;
struct display disp;
@@ -259,6 +299,7 @@ static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
static int atyfb_mmap(struct fb_info *info, struct file *file,
struct vm_area_struct *vma);
#endif
+static int atyfb_rasterimg(struct fb_info *info, int start);
/*
@@ -325,6 +366,7 @@ static char *strtoke(char *s, const char *ct);
static void reset_engine(const struct fb_info_aty *info);
static void init_engine(const struct atyfb_par *par, struct fb_info_aty *info);
+
static void aty_st_514(int offset, u8 val, const struct fb_info_aty *info);
static void aty_st_pll(int offset, u8 val, const struct fb_info_aty *info);
static u8 aty_ld_pll(int offset, const struct fb_info_aty *info);
@@ -338,18 +380,51 @@ static int aty_crtc_to_var(const struct crtc *crtc,
struct fb_var_screeninfo *var);
static void aty_set_pll_gx(const struct fb_info_aty *info,
const struct pll_gx *pll);
-static int aty_var_to_pll_18818(u32 vclk_per, struct pll_gx *pll);
+
+static int aty_set_dac_ATI68860_B(const struct fb_info_aty *info, u32 bpp,
+ u32 AccelMode);
+static int aty_set_dac_ATT21C498(const struct fb_info_aty *info,
+ const struct pll_18818 *pll, u32 bpp);
+void aty_dac_waste4(const struct fb_info_aty *info);
+
+static int aty_var_to_pll_18818(u32 period_in_ps, struct pll_18818 *pll);
+static u32 aty_pll_18818_to_var(const struct pll_18818 *pll);
+static void aty_set_pll18818(const struct fb_info_aty *info,
+ const struct pll_18818 *pll);
+
+static void aty_StrobeClock(const struct fb_info_aty *info);
+
+static void aty_ICS2595_put1bit(u8 data, const struct fb_info_aty *info);
+
+static int aty_var_to_pll_408(u32 period_in_ps, struct pll_18818 *pll);
+static u32 aty_pll_408_to_var(const struct pll_18818 *pll);
+static void aty_set_pll_408(const struct fb_info_aty *info,
+ const struct pll_18818 *pll);
+
+static int aty_var_to_pll_1703(u32 period_in_ps, struct pll_18818 *pll);
+static u32 aty_pll_1703_to_var(const struct pll_18818 *pll);
+static void aty_set_pll_1703(const struct fb_info_aty *info,
+ const struct pll_18818 *pll);
+
+static int aty_var_to_pll_8398(u32 period_in_ps, struct pll_18818 *pll);
+static u32 aty_pll_8398_to_var(const struct pll_18818 *pll);
+static void aty_set_pll_8398(const struct fb_info_aty *info,
+ const struct pll_18818 *pll);
+
static int aty_var_to_pll_514(u32 vclk_per, struct pll_gx *pll);
-static int aty_pll_gx_to_var(const struct pll_gx *pll, u32 *vclk_per,
+static u32 aty_pll_gx_to_var(const struct pll_gx *pll,
const struct fb_info_aty *info);
static void aty_set_pll_ct(const struct fb_info_aty *info,
const struct pll_ct *pll);
-static int aty_dsp_gt(const struct fb_info_aty *info, u8 mclk_fb_div,
- u8 mclk_post_div, u8 vclk_fb_div, u8 vclk_post_div,
- u8 bpp, struct pll_ct *pll);
+static int aty_valid_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
+ struct pll_ct *pll);
+static int aty_dsp_gt(const struct fb_info_aty *info, u8 bpp,
+ struct pll_ct *pll);
+static void aty_calc_pll_ct(const struct fb_info_aty *info,
+ struct pll_ct *pll);
static int aty_var_to_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
u8 bpp, struct pll_ct *pll);
-static int aty_pll_ct_to_var(const struct pll_ct *pll, u32 *vclk_per,
+static u32 aty_pll_ct_to_var(const struct pll_ct *pll,
const struct fb_info_aty *info);
static void atyfb_set_par(const struct atyfb_par *par,
struct fb_info_aty *info);
@@ -380,11 +455,13 @@ static int read_aty_sense(const struct fb_info_aty *info);
* Interface used by the world
*/
-void atyfb_init(void);
+int atyfb_init(void);
#ifdef CONFIG_FB_OF
void atyfb_of_init(struct device_node *dp);
#endif
-void atyfb_setup(char *options, int *ints);
+#ifndef MODULE
+int atyfb_setup(char*);
+#endif
static int currcon = 0;
@@ -392,10 +469,11 @@ static struct fb_ops atyfb_ops = {
atyfb_open, atyfb_release, atyfb_get_fix, atyfb_get_var, atyfb_set_var,
atyfb_get_cmap, atyfb_set_cmap, atyfb_pan_display, atyfb_ioctl,
#ifdef __sparc__
- atyfb_mmap
+ atyfb_mmap,
#else
- NULL
+ NULL,
#endif
+ atyfb_rasterimg
};
static char atyfb_name[16] = "ATY Mach64";
@@ -406,6 +484,10 @@ static u32 default_vram __initdata = 0;
static int default_pll __initdata = 0;
static int default_mclk __initdata = 0;
+#ifndef MODULE
+static const char *mode_option __initdata = NULL;
+#endif
+
#if defined(CONFIG_PPC)
static int default_vmode __initdata = VMODE_NVRAM;
static int default_cmode __initdata = CMODE_NVRAM;
@@ -465,7 +547,7 @@ static const char *aty_ct_ram[8] __initdata = {
};
-static inline u32 aty_ld_le32(volatile unsigned int regindex,
+static inline u32 aty_ld_le32(unsigned int regindex,
const struct fb_info_aty *info)
{
unsigned long temp;
@@ -473,10 +555,10 @@ static inline u32 aty_ld_le32(volatile unsigned int regindex,
#if defined(__powerpc__)
temp = info->ati_regbase;
- asm("lwbrx %0,%1,%2" : "=r"(val) : "r" (regindex), "r" (temp));
+ asm volatile("lwbrx %0,%1,%2" : "=r"(val) : "b" (regindex), "r" (temp));
#elif defined(__sparc_v9__)
temp = info->ati_regbase + regindex;
- asm("lduwa [%1] %2, %0" : "=r" (val) : "r" (temp), "i" (ASI_PL));
+ val = readl(temp);
#else
temp = info->ati_regbase+regindex;
val = le32_to_cpu(*((volatile u32 *)(temp)));
@@ -484,34 +566,42 @@ static inline u32 aty_ld_le32(volatile unsigned int regindex,
return val;
}
-static inline void aty_st_le32(volatile unsigned int regindex, u32 val,
+static inline void aty_st_le32(unsigned int regindex, u32 val,
const struct fb_info_aty *info)
{
unsigned long temp;
#if defined(__powerpc__)
temp = info->ati_regbase;
- asm("stwbrx %0,%1,%2" : : "r" (val), "r" (regindex), "r" (temp) :
+ asm volatile("stwbrx %0,%1,%2" : : "r" (val), "b" (regindex), "r" (temp) :
"memory");
#elif defined(__sparc_v9__)
temp = info->ati_regbase + regindex;
- asm("stwa %0, [%1] %2" : : "r" (val), "r" (temp), "i" (ASI_PL) : "memory");
+ writel(val, temp);
#else
temp = info->ati_regbase+regindex;
*((volatile u32 *)(temp)) = cpu_to_le32(val);
#endif
}
-static inline u8 aty_ld_8(volatile unsigned int regindex,
+static inline u8 aty_ld_8(unsigned int regindex,
const struct fb_info_aty *info)
{
+#ifdef __sparc_v9__
+ return readb(info->ati_regbase + regindex);
+#else
return *(volatile u8 *)(info->ati_regbase+regindex);
+#endif
}
-static inline void aty_st_8(volatile unsigned int regindex, u8 val,
+static inline void aty_st_8(unsigned int regindex, u8 val,
const struct fb_info_aty *info)
{
+#ifdef __sparc_v9__
+ writeb(val, info->ati_regbase + regindex);
+#else
*(volatile u8 *)(info->ati_regbase+regindex) = val;
+#endif
}
@@ -941,8 +1031,10 @@ atyfb_cursor(struct display *p, int mode, int x, int y)
}
}
-__initfunc(static struct aty_cursor *
-aty_init_cursor(struct fb_info_aty *fb))
+static struct fb_info_aty *fb_list = NULL;
+
+static struct aty_cursor * __init
+aty_init_cursor(struct fb_info_aty *fb)
{
struct aty_cursor *cursor;
unsigned long addr;
@@ -1169,6 +1261,124 @@ static int aty_var_to_crtc(const struct fb_info_aty *info,
return 0;
}
+
+static int aty_set_dac_ATI68860_B(const struct fb_info_aty *info, u32 bpp,
+ u32 AccelMode)
+{
+ u32 gModeReg, devSetupRegA, temp, mask;
+
+ gModeReg = 0;
+ devSetupRegA = 0;
+
+ switch (bpp) {
+ case 8:
+ gModeReg = 0x83;
+ devSetupRegA = 0x60 | 0x00 /*(info->mach64DAC8Bit ? 0x00 : 0x01) */;
+ break;
+ case 15:
+ gModeReg = 0xA0;
+ devSetupRegA = 0x60;
+ break;
+ case 16:
+ gModeReg = 0xA1;
+ devSetupRegA = 0x60;
+ break;
+ case 24:
+ gModeReg = 0xC0;
+ devSetupRegA = 0x60;
+ break;
+ case 32:
+ gModeReg = 0xE3;
+ devSetupRegA = 0x60;
+ break;
+ }
+
+ if (!AccelMode) {
+ gModeReg = 0x80;
+ devSetupRegA = 0x61;
+ }
+
+ temp = aty_ld_8(DAC_CNTL, info);
+ aty_st_8(DAC_CNTL, (temp & ~DAC_EXT_SEL_RS2) | DAC_EXT_SEL_RS3, info);
+
+ aty_st_8(DAC_REGS + 2, 0x1D, info);
+ aty_st_8(DAC_REGS + 3, gModeReg, info);
+ aty_st_8(DAC_REGS, 0x02, info);
+
+ temp = aty_ld_8(DAC_CNTL, info);
+ aty_st_8(DAC_CNTL, temp | DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3, info);
+
+ if (info->total_vram < MEM_SIZE_1M)
+ mask = 0x04;
+ else if (info->total_vram == MEM_SIZE_1M)
+ mask = 0x08;
+ else
+ mask = 0x0C;
+
+ /* The following assumes that the BIOS has correctly set R7 of the
+ * Device Setup Register A at boot time.
+ */
+#define A860_DELAY_L 0x80
+
+ temp = aty_ld_8(DAC_REGS, info);
+ aty_st_8(DAC_REGS, (devSetupRegA | mask) | (temp & A860_DELAY_L), info);
+ temp = aty_ld_8(DAC_CNTL, info);
+ aty_st_8(DAC_CNTL, (temp & ~(DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3)), info);
+
+ return 0;
+}
+
+static int aty_set_dac_ATT21C498(const struct fb_info_aty *info,
+ const struct pll_18818 *pll, u32 bpp)
+{
+ u32 dotClock;
+ int muxmode = 0;
+ int DACMask = 0;
+
+ dotClock = 100000000 / pll->period_in_ps;
+
+ switch (bpp) {
+ case 8:
+ if (dotClock > 8000) {
+ DACMask = 0x24;
+ muxmode = 1;
+ } else
+ DACMask = 0x04;
+ break;
+ case 15:
+ DACMask = 0x16;
+ break;
+ case 16:
+ DACMask = 0x36;
+ break;
+ case 24:
+ DACMask = 0xE6;
+ break;
+ case 32:
+ DACMask = 0xE6;
+ break;
+ }
+
+ if (1 /* info->mach64DAC8Bit */)
+ DACMask |= 0x02;
+
+ aty_dac_waste4(info);
+ aty_st_8(DAC_REGS + 2, DACMask, info);
+
+ return muxmode;
+}
+
+void aty_dac_waste4(const struct fb_info_aty *info)
+{
+ (void)aty_ld_8(DAC_REGS, info);
+
+ (void)aty_ld_8(DAC_REGS + 2, info);
+ (void)aty_ld_8(DAC_REGS + 2, info);
+ (void)aty_ld_8(DAC_REGS + 2, info);
+ (void)aty_ld_8(DAC_REGS + 2, info);
+}
+
+
static void aty_set_dac_514(const struct fb_info_aty *info, u32 bpp)
{
static struct {
@@ -1366,60 +1576,477 @@ static void aty_set_pll_gx(const struct fb_info_aty *info,
}
}
-static int aty_var_to_pll_18818(u32 vclk_per, struct pll_gx *pll)
+
+static int aty_var_to_pll_18818(u32 period_in_ps, struct pll_18818 *pll)
{
- /*
- * FIXME: use real calculations instead of using fixed values from the old
- * driver
- */
- static struct {
- u32 ps_lim; /* pixclock period rounding limit (arbitrary) */
- u8 mode; /* (prescsaler << 4) | Select */
- u8 prog; /* ref_div_count */
- } ATI18818_clocks[] = {
- { 7500, 0x0B, 1 }, /* 7407.4 ps = 135.00 MHz */
- { 9000, 0x0A, 1 }, /* 7936.5 ps = 126.00 MHz */
- { 11000, 0x09, 1 }, /* 10000.0 ps = 100.00 MHz */
- { 12800, 0x0D, 1 }, /* 12500.0 ps = 80.00 MHz */
- { 13500, 0x0E, 1 }, /* 13333.3 ps = 75.00 MHz */
-/* { 14000, 0x03, 2 },*/ /* 13888.8 ps = 72.00 MHz */
- { 15000, 0x1B, 1 }, /* 14814.8 ps = 67.50 MHz */
- { 15500, 0x0F, 1 }, /* 15384.6 ps = 65.00 MHz */
- { 16000, 0x1A, 1 }, /* 15873.0 ps = 63.00 MHz */
-/* { 16000, 0x02, 2 },*/ /* 15873.0 ps = 63.00 MHz */
-/* { 18000, 0x01, 2 },*/ /* 17655.4 ps = 56.64 MHz */
-/* { 19900, 0x00, 2 },*/ /* 19860.9 ps = 50.35 MHz */
- { 20000, 0x07, 1 }, /* 20000.0 ps = 50.00 MHz */
- { 20300, 0x06, 1 }, /* 20202.0 ps = 49.50 MHz */
- { 22500, 0x05, 1 }, /* 22271.2 ps = 44.90 MHz */
- { 25000, 0x04, 1 }, /* 25000.0 ps = 40.00 MHz */
-/* { 28000, 0x03, 1 },*/ /* 27777.8 ps = 36.00 MHz */
- { 30000, 0x2B, 1 }, /* 29629,6 ps = 33.75 MHz */
- { 31000, 0x1F, 1 }, /* 30769.2 ps = 32.50 MHz */
- { 32000, 0x2A, 1 }, /* 31746.0 ps = 31.50 MHz */
-/* { 32000, 0x02, 1 },*/ /* 31746.0 ps = 31.50 MHz */
-/* { 36000, 0x01, 1 },*/ /* 35310.7 ps = 28.32 MHz */
-/* { 39900, 0x00, 1 },*/ /* 39714.1 ps = 25.18 MHz */
- { 40000, 0x17, 1 }, /* 40000.0 ps = 25.00 MHz */
- { 40600, 0x16, 1 }, /* 40404.0 ps = 24.75 MHz */
- { 45000, 0x15, 1 }, /* 44543.4 ps = 22.45 MHz */
- { 50000, 0x14, 1 }, /* 50000.0 ps = 20.00 MHz */
-/* { 56000, 0x13, 1 },*/ /* 55555.5 ps = 18.00 MHz */
- { 62000, 0x2F, 1 }, /* 61538.8 ps = 16.25 MHz */
-/* { 64000, 0x12, 1 },*/ /* 63492.0 ps = 15.75 MHz */
- };
- int set;
+ u32 MHz100; /* in 0.01 MHz */
+ u32 program_bits;
+ u32 post_divider;
- for (set = 0; set < sizeof(ATI18818_clocks)/sizeof(*ATI18818_clocks);
- set++)
- if (vclk_per <= ATI18818_clocks[set].ps_lim) {
- pll->m = ATI18818_clocks[set].mode;
- pll->n = ATI18818_clocks[set].prog;
- return 0;
+ /* Calculate the programming word */
+ MHz100 = 100000000 / period_in_ps;
+
+ program_bits = -1;
+ post_divider = 1;
+
+ if (MHz100 > MAX_FREQ_2595) {
+ MHz100 = MAX_FREQ_2595;
+ return -EINVAL;
+ } else if (MHz100 < ABS_MIN_FREQ_2595) {
+ program_bits = 0; /* MHz100 = 257 */
+ return -EINVAL;
+ } else {
+ while (MHz100 < MIN_FREQ_2595) {
+ MHz100 *= 2;
+ post_divider *= 2;
}
- return -EINVAL;
+ }
+ MHz100 *= 1000;
+ MHz100 = (REF_DIV_2595 * MHz100) / REF_FREQ_2595;
+
+ MHz100 += 500; /* + 0.5 round */
+ MHz100 /= 1000;
+
+ if (program_bits == -1) {
+ program_bits = MHz100 - N_ADJ_2595;
+ switch (post_divider) {
+ case 1:
+ program_bits |= 0x0600;
+ break;
+ case 2:
+ program_bits |= 0x0400;
+ break;
+ case 4:
+ program_bits |= 0x0200;
+ break;
+ case 8:
+ default:
+ break;
+ }
+ }
+
+ program_bits |= STOP_BITS_2595;
+
+ pll->program_bits = program_bits;
+ pll->locationAddr = 0;
+ pll->post_divider = post_divider;
+ pll->period_in_ps = period_in_ps;
+
+ return 0;
+}
+
+static u32 aty_pll_18818_to_var(const struct pll_18818 *pll)
+{
+ return(pll->period_in_ps); /* default for now */
+}
+
+static void aty_set_pll18818(const struct fb_info_aty *info,
+ const struct pll_18818 *pll)
+{
+ u32 program_bits;
+ u32 locationAddr;
+
+ u32 i;
+
+ u8 old_clock_cntl;
+ u8 old_crtc_ext_disp;
+
+ old_clock_cntl = aty_ld_8(CLOCK_CNTL, info);
+ aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 0, info);
+
+ old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
+ aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24),
+ info);
+
+ udelay(15000); /* delay for 50 (15) ms */
+
+ program_bits = pll->program_bits;
+ locationAddr = pll->locationAddr;
+
+ /* Program the clock chip */
+ aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 0, info); /* Strobe = 0 */
+ aty_StrobeClock(info);
+ aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 1, info); /* Strobe = 0 */
+ aty_StrobeClock(info);
+
+ aty_ICS2595_put1bit(1, info); /* Send start bits */
+ aty_ICS2595_put1bit(0, info); /* Start bit */
+ aty_ICS2595_put1bit(0, info); /* Read / ~Write */
+
+ for (i = 0; i < 5; i++) { /* Location 0..4 */
+ aty_ICS2595_put1bit(locationAddr & 1, info);
+ locationAddr >>= 1;
+ }
+
+ for (i = 0; i < 8 + 1 + 2 + 2; i++) {
+ aty_ICS2595_put1bit(program_bits & 1, info);
+ program_bits >>= 1;
+ }
+
+ udelay(1000); /* delay for 1 ms */
+
+ (void)aty_ld_8(DAC_REGS, info); /* Clear DAC Counter */
+ aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, info);
+ aty_st_8(CLOCK_CNTL + info->clk_wr_offset, old_clock_cntl | CLOCK_STROBE,
+ info);
+
+ udelay(50000); /* delay for 50 (15) ms */
+ aty_st_8(CLOCK_CNTL + info->clk_wr_offset,
+ ((pll->locationAddr & 0x0F) | CLOCK_STROBE), info);
+
+ return;
+}
+
+
+static int aty_var_to_pll_408(u32 period_in_ps, struct pll_18818 *pll)
+{
+ u32 mhz100; /* in 0.01 MHz */
+ u32 program_bits;
+ /* u32 post_divider; */
+ u32 mach64MinFreq, mach64MaxFreq, mach64RefFreq;
+ u32 temp, tempB;
+ u16 remainder, preRemainder;
+ short divider = 0, tempA;
+
+ /* Calculate the programming word */
+ mhz100 = 100000000 / period_in_ps;
+ mach64MinFreq = MIN_FREQ_2595;
+ mach64MaxFreq = MAX_FREQ_2595;
+ mach64RefFreq = REF_FREQ_2595; /* 14.32 MHz */
+
+ /* Calculate program word */
+ if (mhz100 == 0)
+ program_bits = 0xFF;
+ else {
+ if (mhz100 < mach64MinFreq)
+ mhz100 = mach64MinFreq;
+ if (mhz100 > mach64MaxFreq)
+ mhz100 = mach64MaxFreq;
+
+ while (mhz100 < (mach64MinFreq << 3)) {
+ mhz100 <<= 1;
+ divider += 0x40;
+ }
+
+ temp = (unsigned int)mhz100;
+ temp = (unsigned int)(temp * (MIN_N_408 + 2));
+ temp -= ((short)(mach64RefFreq << 1));
+
+ tempA = MIN_N_408;
+ preRemainder = 0xFFFF;
+
+ do {
+ tempB = temp;
+ remainder = tempB % mach64RefFreq;
+ tempB = tempB / mach64RefFreq;
+ if (((tempB & 0xFFFF) <= 255) && (remainder <= preRemainder)) {
+ preRemainder = remainder;
+ divider &= ~0x3f;
+ divider |= tempA;
+ divider = (divider & 0x00FF) + ((tempB & 0xFF) << 8);
+ }
+ temp += mhz100;
+ tempA++;
+ } while(tempA <= 32);
+
+ program_bits = divider;
+ }
+
+ pll->program_bits = program_bits;
+ pll->locationAddr = 0;
+ pll->post_divider = divider; /* fuer nix */
+ pll->period_in_ps = period_in_ps;
+
+ return 0;
+}
+
+static u32 aty_pll_408_to_var(const struct pll_18818 *pll)
+{
+ return(pll->period_in_ps); /* default for now */
+}
+
+static void aty_set_pll_408(const struct fb_info_aty *info,
+ const struct pll_18818 *pll)
+{
+ u32 program_bits;
+ u32 locationAddr;
+
+ u8 tmpA, tmpB, tmpC;
+ char old_crtc_ext_disp;
+
+ old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
+ aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24),
+ info);
+
+ program_bits = pll->program_bits;
+ locationAddr = pll->locationAddr;
+
+ /* Program clock */
+ aty_dac_waste4(info);
+ tmpB = aty_ld_8(DAC_REGS + 2, info) | 1;
+ aty_dac_waste4(info);
+ aty_st_8(DAC_REGS + 2, tmpB, info);
+
+ tmpA = tmpB;
+ tmpC = tmpA;
+ tmpA |= 8;
+ tmpB = 1;
+
+ aty_st_8(DAC_REGS, tmpB, info);
+ aty_st_8(DAC_REGS + 2, tmpA, info);
+
+ udelay(400); /* delay for 400 us */
+
+ locationAddr = (locationAddr << 2) + 0x40;
+ tmpB = locationAddr;
+ tmpA = program_bits >> 8;
+
+ aty_st_8(DAC_REGS, tmpB, info);
+ aty_st_8(DAC_REGS + 2, tmpA, info);
+
+ tmpB = locationAddr + 1;
+ tmpA = (u8)program_bits;
+
+ aty_st_8(DAC_REGS, tmpB, info);
+ aty_st_8(DAC_REGS + 2, tmpA, info);
+
+ tmpB = locationAddr + 2;
+ tmpA = 0x77;
+
+ aty_st_8(DAC_REGS, tmpB, info);
+ aty_st_8(DAC_REGS + 2, tmpA, info);
+
+ udelay(400); /* delay for 400 us */
+ tmpA = tmpC & (~(1 | 8));
+ tmpB = 1;
+
+ aty_st_8(DAC_REGS, tmpB, info);
+ aty_st_8(DAC_REGS + 2, tmpA, info);
+
+ (void)aty_ld_8(DAC_REGS, info); /* Clear DAC Counter */
+ aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, info);
+
+ return;
+}
+
+
+static int aty_var_to_pll_1703(u32 period_in_ps, struct pll_18818 *pll)
+{
+ u32 mhz100; /* in 0.01 MHz */
+ u32 program_bits;
+ /* u32 post_divider; */
+ u32 mach64MinFreq, mach64MaxFreq, mach64RefFreq;
+ u32 temp, tempB;
+ u16 remainder, preRemainder;
+ short divider = 0, tempA;
+
+ /* Calculate the programming word */
+ mhz100 = 100000000 / period_in_ps;
+ mach64MinFreq = MIN_FREQ_2595;
+ mach64MaxFreq = MAX_FREQ_2595;
+ mach64RefFreq = REF_FREQ_2595; /* 14.32 MHz */
+
+ /* Calculate program word */
+ if (mhz100 == 0)
+ program_bits = 0xE0;
+ else {
+ if (mhz100 < mach64MinFreq)
+ mhz100 = mach64MinFreq;
+ if (mhz100 > mach64MaxFreq)
+ mhz100 = mach64MaxFreq;
+
+ divider = 0;
+ while (mhz100 < (mach64MinFreq << 3)) {
+ mhz100 <<= 1;
+ divider += 0x20;
+ }
+
+ temp = (unsigned int)(mhz100);
+ temp = (unsigned int)(temp * (MIN_N_1703 + 2));
+ temp -= (short)(mach64RefFreq << 1);
+
+ tempA = MIN_N_1703;
+ preRemainder = 0xffff;
+
+ do {
+ tempB = temp;
+ remainder = tempB % mach64RefFreq;
+ tempB = tempB / mach64RefFreq;
+
+ if ((tempB & 0xffff) <= 127 && (remainder <= preRemainder)) {
+ preRemainder = remainder;
+ divider &= ~0x1f;
+ divider |= tempA;
+ divider = (divider & 0x00ff) + ((tempB & 0xff) << 8);
+ }
+
+ temp += mhz100;
+ tempA++;
+ } while (tempA <= (MIN_N_1703 << 1));
+
+ program_bits = divider;
+ }
+
+ pll->program_bits = program_bits;
+ pll->locationAddr = 0;
+ pll->post_divider = divider; /* fuer nix */
+ pll->period_in_ps = period_in_ps;
+
+ return 0;
+}
+
+static u32 aty_pll_1703_to_var(const struct pll_18818 *pll)
+{
+ return(pll->period_in_ps); /* default for now */
+}
+
+static void aty_set_pll_1703(const struct fb_info_aty *info,
+ const struct pll_18818 *pll)
+{
+ u32 program_bits;
+ u32 locationAddr;
+
+ char old_crtc_ext_disp;
+
+ old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
+ aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24),
+ info);
+
+ program_bits = pll->program_bits;
+ locationAddr = pll->locationAddr;
+
+ /* Program clock */
+ aty_dac_waste4(info);
+
+ (void)aty_ld_8(DAC_REGS + 2, info);
+ aty_st_8(DAC_REGS+2, (locationAddr << 1) + 0x20, info);
+ aty_st_8(DAC_REGS+2, 0, info);
+ aty_st_8(DAC_REGS+2, (program_bits & 0xFF00) >> 8, info);
+ aty_st_8(DAC_REGS+2, (program_bits & 0xFF), info);
+
+ (void)aty_ld_8(DAC_REGS, info); /* Clear DAC Counter */
+ aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, info);
+
+ return;
+}
+
+
+static int aty_var_to_pll_8398(u32 period_in_ps, struct pll_18818 *pll)
+{
+
+ u32 tempA, tempB, fOut, longMHz100, diff, preDiff;
+
+ u32 mhz100; /* in 0.01 MHz */
+ u32 program_bits;
+ /* u32 post_divider; */
+ u32 mach64MinFreq, mach64MaxFreq, mach64RefFreq;
+ u16 m, n, k=0, save_m, save_n, twoToKth;
+
+ /* Calculate the programming word */
+ mhz100 = 100000000 / period_in_ps;
+ mach64MinFreq = MIN_FREQ_2595;
+ mach64MaxFreq = MAX_FREQ_2595;
+ mach64RefFreq = REF_FREQ_2595; /* 14.32 MHz */
+
+ save_m = 0;
+ save_n = 0;
+
+ /* Calculate program word */
+ if (mhz100 == 0)
+ program_bits = 0xE0;
+ else
+ {
+ if (mhz100 < mach64MinFreq)
+ mhz100 = mach64MinFreq;
+ if (mhz100 > mach64MaxFreq)
+ mhz100 = mach64MaxFreq;
+
+ longMHz100 = mhz100 * 256 / 100; /* 8 bit scale this */
+
+ while (mhz100 < (mach64MinFreq << 3))
+ {
+ mhz100 <<= 1;
+ k++;
+ }
+
+ twoToKth = 1 << k;
+ diff = 0;
+ preDiff = 0xFFFFFFFF;
+
+ for (m = MIN_M; m <= MAX_M; m++)
+ {
+ for (n = MIN_N; n <= MAX_N; n++)
+ {
+ tempA = (14.31818 * 65536);
+ tempA *= (n + 8); /* 43..256 */
+ tempB = twoToKth * 256;
+ tempB *= (m + 2); /* 4..32 */
+ fOut = tempA / tempB; /* 8 bit scale */
+
+ if (longMHz100 > fOut)
+ diff = longMHz100 - fOut;
+ else
+ diff = fOut - longMHz100;
+
+ if (diff < preDiff)
+ {
+ save_m = m;
+ save_n = n;
+ preDiff = diff;
+ }
+ }
+ }
+
+ program_bits = (k << 6) + (save_m) + (save_n << 8);
+ }
+
+ pll->program_bits = program_bits;
+ pll->locationAddr = 0;
+ pll->post_divider = 0;
+ pll->period_in_ps = period_in_ps;
+
+ return 0;
+}
+
+static u32 aty_pll_8398_to_var(const struct pll_18818 *pll)
+{
+ return(pll->period_in_ps); /* default for now */
+}
+
+static void aty_set_pll_8398(const struct fb_info_aty *info,
+ const struct pll_18818 *pll)
+{
+ u32 program_bits;
+ u32 locationAddr;
+
+ char old_crtc_ext_disp;
+ char tmp;
+
+ old_crtc_ext_disp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
+ aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp | (CRTC_EXT_DISP_EN >> 24),
+ info);
+
+ program_bits = pll->program_bits;
+ locationAddr = pll->locationAddr;
+
+ /* Program clock */
+ tmp = aty_ld_8(DAC_CNTL, info);
+ aty_st_8(DAC_CNTL, tmp | DAC_EXT_SEL_RS2 | DAC_EXT_SEL_RS3, info);
+
+ aty_st_8(DAC_REGS, locationAddr, info);
+ aty_st_8(DAC_REGS+1, (program_bits & 0xff00) >> 8, info);
+ aty_st_8(DAC_REGS+1, (program_bits & 0xff), info);
+
+ tmp = aty_ld_8(DAC_CNTL, info);
+ aty_st_8(DAC_CNTL, (tmp & ~DAC_EXT_SEL_RS2) | DAC_EXT_SEL_RS3, info);
+
+ (void)aty_ld_8(DAC_REGS, info); /* Clear DAC Counter */
+ aty_st_8(CRTC_GEN_CNTL + 3, old_crtc_ext_disp, info);
+
+ return;
}
+
static int aty_var_to_pll_514(u32 vclk_per, struct pll_gx *pll)
{
/*
@@ -1450,9 +2077,44 @@ static int aty_var_to_pll_514(u32 vclk_per, struct pll_gx *pll)
return -EINVAL;
}
- /* FIXME: ATI18818?? */
-static int aty_pll_gx_to_var(const struct pll_gx *pll, u32 *vclk_per,
+static void aty_StrobeClock(const struct fb_info_aty *info)
+{
+ u8 tmp;
+
+ udelay(26);
+
+ tmp = aty_ld_8(CLOCK_CNTL, info);
+ aty_st_8(CLOCK_CNTL + info->clk_wr_offset, tmp | CLOCK_STROBE, info);
+
+ return;
+}
+
+
+static void aty_ICS2595_put1bit(u8 data, const struct fb_info_aty *info)
+{
+ u8 tmp;
+
+ data &= 0x01;
+ tmp = aty_ld_8(CLOCK_CNTL, info);
+ aty_st_8(CLOCK_CNTL + info->clk_wr_offset, (tmp & ~0x04) | (data << 2),
+ info);
+
+ tmp = aty_ld_8(CLOCK_CNTL, info);
+ aty_st_8(CLOCK_CNTL + info->clk_wr_offset, (tmp & ~0x08) | (0 << 3), info);
+
+ aty_StrobeClock(info);
+
+ tmp = aty_ld_8(CLOCK_CNTL, info);
+ aty_st_8(CLOCK_CNTL + info->clk_wr_offset, (tmp & ~0x08) | (1 << 3), info);
+
+ aty_StrobeClock(info);
+
+ return;
+}
+
+
+static u32 aty_pll_gx_to_var(const struct pll_gx *pll,
const struct fb_info_aty *info)
{
u8 df, vco_div_count, ref_div_count;
@@ -1461,9 +2123,7 @@ static int aty_pll_gx_to_var(const struct pll_gx *pll, u32 *vclk_per,
vco_div_count = pll->m & 0x3f;
ref_div_count = pll->n;
- *vclk_per = ((info->ref_clk_per*ref_div_count)<<(3-df))/(vco_div_count+65);
-
- return 0;
+ return ((info->ref_clk_per*ref_div_count)<<(3-df))/(vco_div_count+65);
}
@@ -1495,16 +2155,15 @@ static void aty_set_pll_ct(const struct fb_info_aty *info,
}
}
-static int aty_dsp_gt(const struct fb_info_aty *info, u8 mclk_fb_div,
- u8 mclk_post_div, u8 vclk_fb_div, u8 vclk_post_div,
- u8 bpp, struct pll_ct *pll)
+static int aty_dsp_gt(const struct fb_info_aty *info, u8 bpp,
+ struct pll_ct *pll)
{
u32 dsp_xclks_per_row, dsp_loop_latency, dsp_precision, dsp_off, dsp_on;
u32 xclks_per_row, fifo_off, fifo_on, y, fifo_size, page_size;
/* xclocks_per_row<<11 */
- xclks_per_row = (mclk_fb_div*vclk_post_div*64<<11)/
- (vclk_fb_div*mclk_post_div*bpp);
+ xclks_per_row = (pll->mclk_fb_div*pll->vclk_post_div_real*64<<11)/
+ (pll->vclk_fb_div*pll->mclk_post_div_real*bpp);
if (xclks_per_row < (1<<11))
FAIL("Dotclock to high");
if (Gx == GT_CHIP_ID || Gx == GU_CHIP_ID || Gx == VT_CHIP_ID ||
@@ -1564,63 +2223,59 @@ static int aty_dsp_gt(const struct fb_info_aty *info, u8 mclk_fb_div,
return 0;
}
-static int aty_var_to_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
- u8 bpp, struct pll_ct *pll)
+static int aty_valid_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
+ struct pll_ct *pll)
{
u32 q, x; /* x is a workaround for sparc64-linux-gcc */
- u8 pll_ref_div, pll_gen_cntl, pll_ext_cntl;
- u8 mclk_fb_div, mclk_post_div, mpostdiv = 0;
- u8 vclk_fb_div, vclk_post_div, vpostdiv = 0;
- int err;
-
x = x; /* x is a workaround for sparc64-linux-gcc */
- pll->pll_vclk_cntl = 0x03; /* VCLK = PLL_VCLK/VCLKx_POST */
-
- pll_ref_div = info->pll_per*2*255/info->ref_clk_per;
+ pll->pll_ref_div = info->pll_per*2*255/info->ref_clk_per;
/* FIXME: use the VTB/GTB /3 post divider if it's better suited */
- q = info->ref_clk_per*pll_ref_div*4/info->mclk_per; /* actually 8*q */
+ q = info->ref_clk_per*pll->pll_ref_div*4/info->mclk_per; /* actually 8*q */
if (q < 16*8 || q > 255*8)
FAIL("mclk out of range");
else if (q < 32*8)
- mclk_post_div = 8;
+ pll->mclk_post_div_real = 8;
else if (q < 64*8)
- mclk_post_div = 4;
+ pll->mclk_post_div_real = 4;
else if (q < 128*8)
- mclk_post_div = 2;
+ pll->mclk_post_div_real = 2;
else
- mclk_post_div = 1;
- mclk_fb_div = q*mclk_post_div/8;
+ pll->mclk_post_div_real = 1;
+ pll->mclk_fb_div = q*pll->mclk_post_div_real/8;
/* FIXME: use the VTB/GTB /{3,6,12} post dividers if they're better suited */
- q = info->ref_clk_per*pll_ref_div*4/vclk_per; /* actually 8*q */
+ q = info->ref_clk_per*pll->pll_ref_div*4/vclk_per; /* actually 8*q */
if (q < 16*8 || q > 255*8)
FAIL("vclk out of range");
else if (q < 32*8)
- vclk_post_div = 8;
+ pll->vclk_post_div_real = 8;
else if (q < 64*8)
- vclk_post_div = 4;
+ pll->vclk_post_div_real = 4;
else if (q < 128*8)
- vclk_post_div = 2;
+ pll->vclk_post_div_real = 2;
else
- vclk_post_div = 1;
- vclk_fb_div = q*vclk_post_div/8;
+ pll->vclk_post_div_real = 1;
+ pll->vclk_fb_div = q*pll->vclk_post_div_real/8;
+ return 0;
+}
- if ((err = aty_dsp_gt(info, mclk_fb_div, mclk_post_div, vclk_fb_div,
- vclk_post_div, bpp, pll)))
- return err;
+static void aty_calc_pll_ct(const struct fb_info_aty *info, struct pll_ct *pll)
+{
+ u8 mpostdiv = 0;
+ u8 vpostdiv = 0;
if ((((Gx == GT_CHIP_ID) && (Rev & 0x03)) || (Gx == GU_CHIP_ID) ||
(Gx == GV_CHIP_ID) || (Gx == GW_CHIP_ID) || (Gx == GZ_CHIP_ID) ||
(Gx == LG_CHIP_ID) || (Gx == GB_CHIP_ID) || (Gx == GD_CHIP_ID) ||
(Gx == GI_CHIP_ID) || (Gx == GP_CHIP_ID) || (Gx == GQ_CHIP_ID) ||
(Gx == VU_CHIP_ID)) && (info->ram_type >= SDRAM))
- pll_gen_cntl = 0x04;
+ pll->pll_gen_cntl = 0x04;
else
- pll_gen_cntl = 0x84;
+ pll->pll_gen_cntl = 0x84;
- switch (mclk_post_div) {
+ switch (pll->mclk_post_div_real) {
case 1:
mpostdiv = 0;
break;
@@ -1637,61 +2292,64 @@ static int aty_var_to_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
mpostdiv = 3;
break;
}
- pll_gen_cntl |= mpostdiv<<4; /* mclk */
+ pll->pll_gen_cntl |= mpostdiv<<4; /* mclk */
if (Gx == VT_CHIP_ID && (Rev == 0x40 || Rev == 0x48))
- pll_ext_cntl = 0;
+ pll->pll_ext_cntl = 0;
else
- pll_ext_cntl = mpostdiv; /* xclk == mclk */
+ pll->pll_ext_cntl = mpostdiv; /* xclk == mclk */
- switch (vclk_post_div) {
+ switch (pll->vclk_post_div_real) {
case 2:
vpostdiv = 1;
break;
case 3:
- pll_ext_cntl |= 0x10;
+ pll->pll_ext_cntl |= 0x10;
case 1:
vpostdiv = 0;
break;
case 6:
- pll_ext_cntl |= 0x10;
+ pll->pll_ext_cntl |= 0x10;
case 4:
vpostdiv = 2;
break;
case 12:
- pll_ext_cntl |= 0x10;
+ pll->pll_ext_cntl |= 0x10;
case 8:
vpostdiv = 3;
break;
}
- vclk_post_div = vpostdiv;
-
- pll->pll_ref_div = pll_ref_div;
- pll->pll_gen_cntl = pll_gen_cntl;
- pll->mclk_fb_div = mclk_fb_div;
- pll->vclk_post_div = vclk_post_div;
- pll->vclk_fb_div = vclk_fb_div;
- pll->pll_ext_cntl = pll_ext_cntl;
+
+ pll->pll_vclk_cntl = 0x03; /* VCLK = PLL_VCLK/VCLKx_POST */
+ pll->vclk_post_div = vpostdiv;
+}
+
+static int aty_var_to_pll_ct(const struct fb_info_aty *info, u32 vclk_per,
+ u8 bpp, struct pll_ct *pll)
+{
+ int err;
+
+ if ((err = aty_valid_pll_ct(info, vclk_per, pll)))
+ return err;
+ if (!(Gx == GX_CHIP_ID || Gx == CX_CHIP_ID || Gx == CT_CHIP_ID ||
+ Gx == ET_CHIP_ID ||
+ ((Gx == VT_CHIP_ID || Gx == GT_CHIP_ID) && !(Rev & 0x07)))) {
+ if ((err = aty_dsp_gt(info, bpp, pll)))
+ return err;
+ }
+ aty_calc_pll_ct(info, pll);
return 0;
}
-static int aty_pll_ct_to_var(const struct pll_ct *pll, u32 *vclk_per,
+static u32 aty_pll_ct_to_var(const struct pll_ct *pll,
const struct fb_info_aty *info)
{
+ u32 ref_clk_per = info->ref_clk_per;
u8 pll_ref_div = pll->pll_ref_div;
u8 vclk_fb_div = pll->vclk_fb_div;
- u8 vclk_post_div = pll->vclk_post_div;
- u8 pll_ext_cntl = pll->pll_ext_cntl;
- static u8 vclk_post_div_tab[] = {
- 1, 2, 4, 8,
- 3, 0, 6, 12
- };
- u8 vpostdiv = vclk_post_div_tab[((pll_ext_cntl & 0x10) >> 2) |
- (vclk_post_div & 3)];
- if (vpostdiv == 0)
- return -EINVAL;
- *vclk_per = pll_ref_div*vpostdiv*info->ref_clk_per/vclk_fb_div/2;
- return 0;
+ u8 vclk_post_div = pll->vclk_post_div_real;
+
+ return ref_clk_per*pll_ref_div*vclk_post_div/vclk_fb_div/2;
}
/* ------------------------------------------------------------------------- */
@@ -1700,27 +2358,76 @@ static void atyfb_set_par(const struct atyfb_par *par,
struct fb_info_aty *info)
{
u32 i;
+ int accelmode;
+ int muxmode;
+ u8 tmp;
+
+ accelmode = par->accel_flags; /* hack */
info->current_par = *par;
if (info->blitter_may_be_busy)
wait_for_idle(info);
+ tmp = aty_ld_8(CRTC_GEN_CNTL + 3, info);
aty_set_crtc(info, &par->crtc);
- aty_st_8(CLOCK_CNTL, 0, info);
- aty_st_8(CLOCK_CNTL, CLOCK_STROBE, info);
+ aty_st_8(CLOCK_CNTL + info->clk_wr_offset, 0, info);
+ /* better call aty_StrobeClock ?? */
+ aty_st_8(CLOCK_CNTL + info->clk_wr_offset, CLOCK_STROBE, info);
if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID)) {
- switch (info->dac_type) {
+ switch (info->dac_subtype) {
case DAC_IBMRGB514:
aty_set_dac_514(info, par->crtc.bpp);
break;
case DAC_ATI68860_B:
- /* FIXME */
+ case DAC_ATI68860_C:
+ muxmode = aty_set_dac_ATI68860_B(info, par->crtc.bpp,
+ accelmode);
+ aty_st_le32(BUS_CNTL, 0x890e20f1, info);
+ aty_st_le32(DAC_CNTL, 0x47052100, info);
break;
- }
- aty_set_pll_gx(info, &par->pll.gx);
+ case DAC_ATT20C408:
+ muxmode = aty_set_dac_ATT21C498(info, &par->pll.ics2595,
+ par->crtc.bpp);
+ aty_st_le32(BUS_CNTL, 0x890e20f1, info);
+ aty_st_le32(DAC_CNTL, 0x00072000, info);
+ break;
+ case DAC_ATT21C498:
+ muxmode = aty_set_dac_ATT21C498(info, &par->pll.ics2595,
+ par->crtc.bpp);
+ aty_st_le32(BUS_CNTL, 0x890e20f1, info);
+ aty_st_le32(DAC_CNTL, 0x00072000, info);
+ break;
+ default:
+ printk(" atyfb_set_par: DAC type not implemented yet!\n");
+ aty_st_le32(BUS_CNTL, 0x890e20f1, info);
+ aty_st_le32(DAC_CNTL, 0x47052100, info);
+ /* new in 2.2.3p1 from Geert. ???????? */
aty_st_le32(BUS_CNTL, 0x590e10ff, info);
aty_st_le32(DAC_CNTL, 0x47012100, info);
+ break;
+ }
+
+ switch (info->clk_type) {
+ case CLK_ATI18818_1:
+ aty_set_pll18818(info, &par->pll.ics2595);
+ break;
+ case CLK_STG1703:
+ aty_set_pll_1703(info, &par->pll.ics2595);
+ break;
+ case CLK_CH8398:
+ aty_set_pll_8398(info, &par->pll.ics2595);
+ break;
+ case CLK_ATT20C408:
+ aty_set_pll_408(info, &par->pll.ics2595);
+ break;
+ case CLK_IBMRGB514:
+ aty_set_pll_gx(info, &par->pll.gx);
+ break;
+ default:
+ printk(" atyfb_set_par: CLK type not implemented yet!");
+ break;
+ }
/* Don't forget MEM_CNTL */
i = aty_ld_le32(MEM_CNTL, info) & 0xf0ffffff;
@@ -1739,7 +2446,7 @@ static void atyfb_set_par(const struct atyfb_par *par,
} else {
aty_set_pll_ct(info, &par->pll.ct);
- i = aty_ld_le32(MEM_CNTL, info) & 0xf30fffff;
+ i = aty_ld_le32(MEM_CNTL, info) & 0xf00fffff;
if (!(Gx == VT_CHIP_ID && (Rev == 0x40 || Rev == 0x48)))
i |= info->mem_refresh_rate << 20;
switch (par->crtc.bpp) {
@@ -1808,7 +2515,16 @@ static int atyfb_decode_var(const struct fb_var_screeninfo *var,
if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID))
switch (info->clk_type) {
case CLK_ATI18818_1:
- err = aty_var_to_pll_18818(var->pixclock, &par->pll.gx);
+ err = aty_var_to_pll_18818(var->pixclock, &par->pll.ics2595);
+ break;
+ case CLK_STG1703:
+ err = aty_var_to_pll_1703(var->pixclock, &par->pll.ics2595);
+ break;
+ case CLK_CH8398:
+ err = aty_var_to_pll_8398(var->pixclock, &par->pll.ics2595);
+ break;
+ case CLK_ATT20C408:
+ err = aty_var_to_pll_408(var->pixclock, &par->pll.ics2595);
break;
case CLK_IBMRGB514:
err = aty_var_to_pll_514(var->pixclock, &par->pll.gx);
@@ -1844,11 +2560,25 @@ static int atyfb_encode_var(struct fb_var_screeninfo *var,
if ((err = aty_crtc_to_var(&par->crtc, var)))
return err;
if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID))
- err = aty_pll_gx_to_var(&par->pll.gx, &var->pixclock, info);
+ switch (info->clk_type) {
+ case CLK_ATI18818_1:
+ var->pixclock = aty_pll_18818_to_var(&par->pll.ics2595);
+ break;
+ case CLK_STG1703:
+ var->pixclock = aty_pll_1703_to_var(&par->pll.ics2595);
+ break;
+ case CLK_CH8398:
+ var->pixclock = aty_pll_8398_to_var(&par->pll.ics2595);
+ break;
+ case CLK_ATT20C408:
+ var->pixclock = aty_pll_408_to_var(&par->pll.ics2595);
+ break;
+ case CLK_IBMRGB514:
+ var->pixclock = aty_pll_gx_to_var(&par->pll.gx, info);
+ break;
+ }
else
- err = aty_pll_ct_to_var(&par->pll.ct, &var->pixclock, info);
- if (err)
- return err;
+ var->pixclock = aty_pll_ct_to_var(&par->pll.ct, info);
var->height = -1;
var->width = -1;
@@ -1923,7 +2653,7 @@ static int encode_fix(struct fb_fix_screeninfo *fix,
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id, atyfb_name);
- fix->smem_start = (char *)info->frame_buffer_phys;
+ fix->smem_start = info->frame_buffer_phys;
fix->smem_len = (u32)info->total_vram;
#ifdef __LITTLE_ENDIAN
@@ -1940,19 +2670,19 @@ static int encode_fix(struct fb_fix_screeninfo *fix,
* Reg Block 1 (multimedia extensions) is at ati_regbase_phys-0x400
*/
if (Gx == GX_CHIP_ID || Gx == CX_CHIP_ID) {
- fix->mmio_start = (char *)info->ati_regbase_phys;
+ fix->mmio_start = info->ati_regbase_phys;
fix->mmio_len = 0x400;
fix->accel = FB_ACCEL_ATI_MACH64GX;
} else if (Gx == CT_CHIP_ID || Gx == ET_CHIP_ID) {
- fix->mmio_start = (char *)info->ati_regbase_phys;
+ fix->mmio_start = info->ati_regbase_phys;
fix->mmio_len = 0x400;
fix->accel = FB_ACCEL_ATI_MACH64CT;
} else if (Gx == VT_CHIP_ID || Gx == VU_CHIP_ID || Gx == VV_CHIP_ID) {
- fix->mmio_start = (char *)(info->ati_regbase_phys-0x400);
+ fix->mmio_start = info->ati_regbase_phys-0x400;
fix->mmio_len = 0x800;
fix->accel = FB_ACCEL_ATI_MACH64VT;
} else {
- fix->mmio_start = (char *)(info->ati_regbase_phys-0x400);
+ fix->mmio_start = info->ati_regbase_phys-0x400;
fix->mmio_len = 0x800;
fix->accel = FB_ACCEL_ATI_MACH64GT;
}
@@ -2194,36 +2924,112 @@ static int atyfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
}
+#ifdef DEBUG
+#define ATYIO_CLKR 0x41545900 /* ATY\00 */
+#define ATYIO_CLKW 0x41545901 /* ATY\01 */
+
+struct atyclk {
+ u32 ref_clk_per;
+ u8 pll_ref_div;
+ u8 mclk_fb_div;
+ u8 mclk_post_div; /* 1,2,3,4,8 */
+ u8 vclk_fb_div;
+ u8 vclk_post_div; /* 1,2,3,4,6,8,12 */
+ u32 dsp_xclks_per_row; /* 0-16383 */
+ u32 dsp_loop_latency; /* 0-15 */
+ u32 dsp_precision; /* 0-7 */
+ u32 dsp_on; /* 0-2047 */
+ u32 dsp_off; /* 0-2047 */
+};
+#endif
+
static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
- u_long arg, int con, struct fb_info *info)
+ u_long arg, int con, struct fb_info *info2)
{
+#if defined(__sparc__) || defined(DEBUG)
+ struct fb_info_aty *info = (struct fb_info_aty *)info2;
+#endif /* __sparc__ || DEBUG */
#ifdef __sparc__
- struct fb_info_aty *fb = (struct fb_info_aty *)info;
struct fbtype fbtyp;
struct display *disp;
if (con >= 0)
disp = &fb_display[con];
else
- disp = info->disp;
+ disp = info2->disp;
+#endif
switch (cmd) {
+#ifdef __sparc__
case FBIOGTYPE:
fbtyp.fb_type = FBTYPE_PCI_GENERIC;
- fbtyp.fb_width = fb->current_par.crtc.vxres;
- fbtyp.fb_height = fb->current_par.crtc.vyres;
- fbtyp.fb_depth = fb->current_par.crtc.bpp;
+ fbtyp.fb_width = info->current_par.crtc.vxres;
+ fbtyp.fb_height = info->current_par.crtc.vyres;
+ fbtyp.fb_depth = info->current_par.crtc.bpp;
fbtyp.fb_cmsize = disp->cmap.len;
- fbtyp.fb_size = fb->total_vram;
+ fbtyp.fb_size = info->total_vram;
copy_to_user_ret((struct fbtype *)arg, &fbtyp, sizeof(fbtyp), -EFAULT);
break;
+#endif /* __sparc__ */
+#ifdef DEBUG
+ case ATYIO_CLKR:
+ if ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID)) {
+ struct atyclk clk;
+ struct pll_ct *pll = &info->current_par.pll.ct;
+ u32 dsp_config = pll->dsp_config;
+ u32 dsp_on_off = pll->dsp_on_off;
+ clk.ref_clk_per = info->ref_clk_per;
+ clk.pll_ref_div = pll->pll_ref_div;
+ clk.mclk_fb_div = pll->mclk_fb_div;
+ clk.mclk_post_div = pll->mclk_post_div_real;
+ clk.vclk_fb_div = pll->vclk_fb_div;
+ clk.vclk_post_div = pll->vclk_post_div_real;
+ clk.dsp_xclks_per_row = dsp_config & 0x3fff;
+ clk.dsp_loop_latency = (dsp_config>>16) & 0xf;
+ clk.dsp_precision = (dsp_config>>20) & 7;
+ clk.dsp_on = dsp_on_off & 0x7ff;
+ clk.dsp_off = (dsp_on_off>>16) & 0x7ff;
+ copy_to_user_ret((struct atyclk *)arg, &clk, sizeof(clk),
+ -EFAULT);
+ } else
+ return -EINVAL;
+ break;
+ case ATYIO_CLKW:
+ if ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID)) {
+ struct atyclk clk;
+ struct pll_ct *pll = &info->current_par.pll.ct;
+ copy_from_user_ret(&clk, (struct atyclk *)arg, sizeof(clk),
+ -EFAULT);
+ info->ref_clk_per = clk.ref_clk_per;
+ pll->pll_ref_div = clk.pll_ref_div;
+ pll->mclk_fb_div = clk.mclk_fb_div;
+ pll->mclk_post_div_real = clk.mclk_post_div;
+ pll->vclk_fb_div = clk.vclk_fb_div;
+ pll->vclk_post_div_real = clk.vclk_post_div;
+ pll->dsp_config = (clk.dsp_xclks_per_row & 0x3fff) |
+ ((clk.dsp_loop_latency & 0xf)<<16) |
+ ((clk.dsp_precision & 7)<<20);
+ pll->dsp_on_off = (clk.dsp_on & 0x7ff) |
+ ((clk.dsp_off & 0x7ff)<<16);
+ aty_calc_pll_ct(info, pll);
+ aty_set_pll_ct(info, pll);
+ } else
+ return -EINVAL;
+ break;
+#endif /* DEBUG */
default:
return -EINVAL;
}
return 0;
-#else
- return -EINVAL;
-#endif
+}
+
+static int atyfb_rasterimg(struct fb_info *info, int start)
+{
+ struct fb_info_aty *fb = (struct fb_info_aty *)info;
+
+ if (fb->blitter_may_be_busy)
+ wait_for_idle(fb);
+ return 0;
}
#ifdef __sparc__
@@ -2424,7 +3230,7 @@ static void atyfb_palette(int enter)
* Initialisation
*/
-__initfunc(static int aty_init(struct fb_info_aty *info, const char *name))
+static int __init aty_init(struct fb_info_aty *info, const char *name)
{
u32 chip_id;
u32 i;
@@ -2439,12 +3245,16 @@ __initfunc(static int aty_init(struct fb_info_aty *info, const char *name))
u8 pll_ref_div;
info->aty_cmap_regs = (struct aty_cmap_regs *)(info->ati_regbase+0xc0);
+#ifdef __sparc_v9__
+ info->aty_cmap_regs = __va(info->aty_cmap_regs);
+#endif
chip_id = aty_ld_le32(CONFIG_CHIP_ID, info);
Gx = chip_id & CFG_CHIP_TYPE;
Rev = (chip_id & CFG_CHIP_REV)>>24;
for (j = 0; j < (sizeof(aty_features)/sizeof(*aty_features)); j++)
if (aty_features[j].chip_type == Gx) {
chipname = aty_features[j].name;
+ info->dac_type = (aty_ld_le32(DAC_CNTL, info) >> 16) & 0x07;
break;
}
if (!chipname) {
@@ -2458,10 +3268,16 @@ __initfunc(static int aty_init(struct fb_info_aty *info, const char *name))
ramname = aty_gx_ram[info->ram_type];
/* FIXME: clockchip/RAMDAC probing? */
#ifdef CONFIG_ATARI
- info->dac_type = DAC_ATI68860_B;
info->clk_type = CLK_ATI18818_1;
+ info->dac_type = (aty_ld_le32(CONFIG_STAT0, info) >> 9) & 0x07;
+ if (info->dac_type == 0x07)
+ info->dac_subtype = DAC_ATT20C408;
+ else
+ info->dac_subtype = (aty_ld_8(SCRATCH_REG1 + 1, info) & 0xF0) |
+ info->dac_type;
#else
info->dac_type = DAC_IBMRGB514;
+ info->dac_subtype = DAC_IBMRGB514;
info->clk_type = CLK_IBMRGB514;
#endif
/* FIXME */
@@ -2472,6 +3288,7 @@ __initfunc(static int aty_init(struct fb_info_aty *info, const char *name))
info->ram_type = (aty_ld_le32(CONFIG_STAT0, info) & 0x07);
ramname = aty_ct_ram[info->ram_type];
info->dac_type = DAC_INTERNAL;
+ info->dac_subtype = DAC_INTERNAL;
info->clk_type = CLK_INTERNAL;
if ((Gx == CT_CHIP_ID) || (Gx == ET_CHIP_ID)) {
pll = 135;
@@ -2667,32 +3484,64 @@ __initfunc(static int aty_init(struct fb_info_aty *info, const char *name))
info->total_vram -= GUI_RESERVE;
}
+ disp = &info->disp;
+
+ strcpy(info->fb_info.modename, atyfb_name);
+ info->fb_info.node = -1;
+ info->fb_info.fbops = &atyfb_ops;
+ info->fb_info.disp = disp;
+ strcpy(info->fb_info.fontname, fontname);
+ info->fb_info.changevar = NULL;
+ info->fb_info.switch_con = &atyfbcon_switch;
+ info->fb_info.updatevar = &atyfbcon_updatevar;
+ info->fb_info.blank = &atyfbcon_blank;
+ info->fb_info.flags = FBINFO_FLAG_DEFAULT;
+
+#ifdef MODULE
+ var = default_var;
+#else /* !MODULE */
+ memset(&var, 0, sizeof(var));
#if defined(CONFIG_PPC)
- if (default_vmode == VMODE_NVRAM) {
- default_vmode = nvram_read_byte(NV_VMODE);
- if (default_vmode <= 0 || default_vmode > VMODE_MAX)
- default_vmode = VMODE_CHOOSE;
- }
- if (default_vmode == VMODE_CHOOSE) {
- if (Gx == LG_CHIP_ID)
- /* G3 PowerBook with 1024x768 LCD */
- default_vmode = VMODE_1024_768_60;
- else {
- sense = read_aty_sense(info);
- default_vmode = mac_map_monitor_sense(sense);
+ if (mode_option) {
+ if (!mac_find_mode(&var, &info->fb_info, mode_option, 8))
+ var = default_var;
+ } else {
+ if (default_vmode == VMODE_NVRAM) {
+ default_vmode = nvram_read_byte(NV_VMODE);
+ if (default_vmode <= 0 || default_vmode > VMODE_MAX)
+ default_vmode = VMODE_CHOOSE;
+ }
+ if (default_vmode == VMODE_CHOOSE) {
+ if (Gx == LG_CHIP_ID)
+ /* G3 PowerBook with 1024x768 LCD */
+ default_vmode = VMODE_1024_768_60;
+ else {
+ sense = read_aty_sense(info);
+ default_vmode = mac_map_monitor_sense(sense);
+ }
}
+ if (default_vmode <= 0 || default_vmode > VMODE_MAX)
+ default_vmode = VMODE_640_480_60;
+ if (default_cmode == CMODE_NVRAM)
+ default_cmode = nvram_read_byte(NV_CMODE);
+ if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
+ default_cmode = CMODE_8;
+ if (mac_vmode_to_var(default_vmode, default_cmode, &var))
+ var = default_var;
}
- if (default_vmode <= 0 || default_vmode > VMODE_MAX)
- default_vmode = VMODE_640_480_60;
- if (default_cmode == CMODE_NVRAM)
- default_cmode = nvram_read_byte(NV_CMODE);
- if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
- default_cmode = CMODE_8;
- if (mac_vmode_to_var(default_vmode, default_cmode, &var))
- var = default_var;
#else /* !CONFIG_PPC */
- var = default_var;
+#ifdef __sparc__
+ if (mode_option) {
+ if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0, NULL, 8))
+ var = default_var;
+ } else
+ var = default_var;
+#else
+ if (!fb_find_mode(&var, &info->fb_info, mode_option, NULL, 0, NULL, 8))
+ var = default_var;
+#endif /* !__sparc__ */
#endif /* !CONFIG_PPC */
+#endif /* !MODULE */
if (noaccel)
var.accel_flags &= ~FB_ACCELF_TEXT;
else
@@ -2710,19 +3559,6 @@ __initfunc(static int aty_init(struct fb_info_aty *info, const char *name))
return 0;
}
- disp = &info->disp;
-
- strcpy(info->fb_info.modename, atyfb_name);
- info->fb_info.node = -1;
- info->fb_info.fbops = &atyfb_ops;
- info->fb_info.disp = disp;
- strcpy(info->fb_info.fontname, fontname);
- info->fb_info.changevar = NULL;
- info->fb_info.switch_con = &atyfbcon_switch;
- info->fb_info.updatevar = &atyfbcon_updatevar;
- info->fb_info.blank = &atyfbcon_blank;
- info->fb_info.flags = FBINFO_FLAG_DEFAULT;
-
#ifdef __sparc__
atyfb_save_palette(&info->fb_info, 0);
#endif
@@ -2746,12 +3582,15 @@ __initfunc(static int aty_init(struct fb_info_aty *info, const char *name))
if (register_framebuffer(&info->fb_info) < 0)
return 0;
+ info->next = fb_list;
+ fb_list = info;
+
printk("fb%d: %s frame buffer device on %s\n",
GET_FB_IDX(info->fb_info.node), atyfb_name, name);
return 1;
}
-__initfunc(void atyfb_init(void))
+int __init atyfb_init(void)
{
#if defined(CONFIG_FB_OF)
/* We don't want to be called like this. */
@@ -2771,7 +3610,7 @@ __initfunc(void atyfb_init(void))
/* Do not attach when we have a serial console. */
if (!con_is_present())
- return;
+ return -ENXIO;
#else
u16 tmp;
#endif
@@ -2779,39 +3618,40 @@ __initfunc(void atyfb_init(void))
for (pdev = pci_devices; pdev; pdev = pdev->next) {
if (((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) &&
(pdev->vendor == PCI_VENDOR_ID_ATI)) {
+ struct resource *rp;
info = kmalloc(sizeof(struct fb_info_aty), GFP_ATOMIC);
if (!info) {
printk("atyfb_init: can't alloc fb_info_aty\n");
- return;
+ return -ENXIO;
}
memset(info, 0, sizeof(struct fb_info_aty));
- addr = pdev->base_address[0];
- if ((addr & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO)
- addr = pdev->base_address[1];
+ rp = &pdev->resource[0];
+ if (rp->flags & IORESOURCE_IO)
+ rp = &pdev->resource[1];
+ addr = rp->start;
if (!addr)
continue;
- addr &= PCI_BASE_ADDRESS_MEM_MASK;
#ifdef __sparc__
/*
* Map memory-mapped registers.
*/
- info->ati_regbase = addr + 0x7ffc00;
- info->ati_regbase_phys = __pa(addr + 0x7ffc00);
+ info->ati_regbase = addr + 0x7ffc00UL;
+ info->ati_regbase_phys = addr + 0x7ffc00UL;
/*
* Map in big-endian aperture.
*/
- info->frame_buffer = (unsigned long)(addr + 0x800000);
- info->frame_buffer_phys = __pa(addr + 0x800000);
+ info->frame_buffer = (unsigned long) __va(addr + 0x800000UL);
+ info->frame_buffer_phys = addr + 0x800000UL;
/*
* Figure mmap addresses from PCI config space.
* Split Framebuffer in big- and little-endian halfs.
*/
- for (i = 0; i < 6 && pdev->base_address[i]; i++)
+ for (i = 0; i < 6 && pdev->resource[i].start; i++)
/* nothing */;
j = i + 4;
@@ -2819,27 +3659,26 @@ __initfunc(void atyfb_init(void))
if (!info->mmap_map) {
printk("atyfb_init: can't alloc mmap_map\n");
kfree(info);
- return;
+ return -ENXIO;
}
memset(info->mmap_map, 0, j * sizeof(*info->mmap_map));
- for (i = 0, j = 2; i < 6 && pdev->base_address[i]; i++) {
+ for (i = 0, j = 2; i < 6 && pdev->resource[i].start; i++) {
+ struct resource *rp = &pdev->resource[i];
int io, breg = PCI_BASE_ADDRESS_0 + (i << 2);
unsigned long base;
u32 size, pbase;
- base = pdev->base_address[i];
+ base = rp->start;
- io = (base & PCI_BASE_ADDRESS_SPACE)==PCI_BASE_ADDRESS_SPACE_IO;
+ io = (rp->flags & IORESOURCE_IO);
+ size = rp->end - base + 1;
+
pci_read_config_dword(pdev, breg, &pbase);
- pci_write_config_dword(pdev, breg, 0xffffffff);
- pci_read_config_dword(pdev, breg, &size);
- pci_write_config_dword(pdev, breg, pbase);
if (io)
size &= ~1;
- size = ~(size) + 1;
/*
* Map the framebuffer a second time, this time without
@@ -2849,7 +3688,7 @@ __initfunc(void atyfb_init(void))
*/
if (base == addr) {
info->mmap_map[j].voff = (pbase + 0x10000000) & PAGE_MASK;
- info->mmap_map[j].poff = __pa(base & PAGE_MASK);
+ info->mmap_map[j].poff = base & PAGE_MASK;
info->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
info->mmap_map[j].prot_mask = _PAGE_CACHE;
info->mmap_map[j].prot_flag = _PAGE_E;
@@ -2862,7 +3701,7 @@ __initfunc(void atyfb_init(void))
*/
if (base == addr) {
info->mmap_map[j].voff = (pbase + 0x800000) & PAGE_MASK;
- info->mmap_map[j].poff = __pa((base+0x800000) & PAGE_MASK);
+ info->mmap_map[j].poff = (base+0x800000) & PAGE_MASK;
info->mmap_map[j].size = 0x800000;
info->mmap_map[j].prot_mask = _PAGE_CACHE;
info->mmap_map[j].prot_flag = _PAGE_E|_PAGE_IE;
@@ -2871,7 +3710,7 @@ __initfunc(void atyfb_init(void))
}
info->mmap_map[j].voff = pbase & PAGE_MASK;
- info->mmap_map[j].poff = __pa(base & PAGE_MASK);
+ info->mmap_map[j].poff = base & PAGE_MASK;
info->mmap_map[j].size = (size + ~PAGE_MASK) & PAGE_MASK;
info->mmap_map[j].prot_mask = _PAGE_CACHE;
info->mmap_map[j].prot_flag = _PAGE_E;
@@ -2999,7 +3838,7 @@ __initfunc(void atyfb_init(void))
if(!info->ati_regbase) {
kfree(info);
- return;
+ return -ENOMEM;
}
info->ati_regbase_phys += 0xc00;
@@ -3026,7 +3865,7 @@ __initfunc(void atyfb_init(void))
if(!info->frame_buffer) {
kfree(info);
- return;
+ return -ENXIO;
}
#endif /* __sparc__ */
@@ -3035,7 +3874,7 @@ __initfunc(void atyfb_init(void))
if (info->mmap_map)
kfree(info->mmap_map);
kfree(info);
- return;
+ return -ENXIO;
}
#ifdef __sparc__
@@ -3051,14 +3890,16 @@ __initfunc(void atyfb_init(void))
info->mmap_map[0].prot_mask = _PAGE_CACHE;
info->mmap_map[0].prot_flag = _PAGE_E;
info->mmap_map[1].voff = info->mmap_map[0].voff + info->total_vram;
- info->mmap_map[1].poff = __pa(info->ati_regbase & PAGE_MASK);
+ info->mmap_map[1].poff = info->ati_regbase & PAGE_MASK;
info->mmap_map[1].size = PAGE_SIZE;
info->mmap_map[1].prot_mask = _PAGE_CACHE;
info->mmap_map[1].prot_flag = _PAGE_E;
#endif /* __sparc__ */
}
}
+
#elif defined(CONFIG_ATARI)
+ u32 clock_r;
int m64_num;
struct fb_info_aty *info;
@@ -3073,7 +3914,7 @@ __initfunc(void atyfb_init(void))
info = kmalloc(sizeof(struct fb_info_aty), GFP_ATOMIC);
if (!info) {
printk("atyfb_init: can't alloc fb_info_aty\n");
- return;
+ return -ENOMEM;
}
memset(info, 0, sizeof(struct fb_info_aty));
@@ -3082,21 +3923,40 @@ __initfunc(void atyfb_init(void))
* kernel address space.
*/
info->frame_buffer = ioremap(phys_vmembase[m64_num], phys_size[m64_num]);
- info->frame_buffer_phys = info->frame_buffer;
+ info->frame_buffer_phys = info->frame_buffer; /* Fake! */
info->ati_regbase = ioremap(phys_guiregbase[m64_num], 0x10000)+0xFC00ul;
- info->ati_regbase_phys = info->ati_regbase;
+ info->ati_regbase_phys = info->ati_regbase; /* Fake! */
+
+ aty_st_le32(CLOCK_CNTL, 0x12345678, info);
+ clock_r = aty_ld_le32(CLOCK_CNTL, info);
+
+ switch (clock_r & 0x003F) {
+ case 0x12:
+ info->clk_wr_offset = 3; /* */
+ break;
+ case 0x34:
+ info->clk_wr_offset = 2; /* Medusa ST-IO ISA Adapter etc. */
+ break;
+ case 0x16:
+ info->clk_wr_offset = 1; /* */
+ break;
+ case 0x38:
+ info->clk_wr_offset = 0; /* Panther 1 ISA Adapter (Gerald) */
+ break;
+ }
if (!aty_init(info, "ISA bus")) {
kfree(info);
/* This is insufficient! kernel_map has added two large chunks!! */
- return;
+ return -ENXIO;
}
}
-#endif
+#endif /* CONFIG_ATARI */
+ return 0;
}
#ifdef CONFIG_FB_OF
-__initfunc(void atyfb_of_init(struct device_node *dp))
+void __init atyfb_of_init(struct device_node *dp)
{
unsigned long addr;
u8 bus, devfn;
@@ -3135,7 +3995,7 @@ __initfunc(void atyfb_of_init(struct device_node *dp))
0x1000);
if(! info->ati_regbase) {
- printk("atyfb_init: ioremap() returned NULL\n");
+ printk("atyfb_of_init: ioremap() returned NULL\n");
kfree(info);
return;
}
@@ -3162,7 +4022,7 @@ __initfunc(void atyfb_of_init(struct device_node *dp))
info->frame_buffer = (unsigned long)ioremap(addr, 0x800000);
if(! info->frame_buffer) {
- printk("atyfb_init: ioremap() returned NULL\n");
+ printk("atyfb_of_init: ioremap() returned NULL\n");
kfree(info);
return;
}
@@ -3180,12 +4040,13 @@ __initfunc(void atyfb_of_init(struct device_node *dp))
#endif /* CONFIG_FB_OF */
-__initfunc(void atyfb_setup(char *options, int *ints))
+#ifndef MODULE
+int __init atyfb_setup(char *options)
{
char *this_opt;
if (!options || !*options)
- return;
+ return 0;
for (this_opt = strtok(options, ","); this_opt;
this_opt = strtok(NULL, ",")) {
@@ -3247,11 +4108,15 @@ __initfunc(void atyfb_setup(char *options, int *ints))
}
}
#endif
+ else
+ mode_option = this_opt;
}
+ return 0;
}
+#endif /* !MODULE */
#ifdef CONFIG_ATARI
-__initfunc(static int store_video_par(char *video_str, unsigned char m64_num))
+static int __init store_video_par(char *video_str, unsigned char m64_num)
{
char *p;
unsigned long vmembase, size, guiregbase;
@@ -3280,7 +4145,7 @@ mach64_invalid:
return -1;
}
-__initfunc(static char *strtoke(char *s, const char *ct))
+static char __init *strtoke(char *s, const char *ct)
{
static char *ssave = NULL;
char *sbegin, *send;
@@ -3870,3 +4735,44 @@ static struct display_switch fbcon_aty32 = {
FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
};
#endif
+
+#ifdef MODULE
+int __init init_module(void)
+{
+ atyfb_init();
+ return fb_list ? 0 : -ENXIO;
+}
+
+void cleanup_module(void)
+{
+ while (fb_list) {
+ struct fb_info_aty *info = fb_list;
+ fb_list = info->next;
+
+ unregister_framebuffer(&info->fb_info);
+
+#ifndef __sparc__
+ if (info->ati_regbase)
+ iounmap((void *)info->ati_regbase);
+ if (info->frame_buffer)
+ iounmap((void *)info->frame_buffer);
+#ifdef __BIG_ENDIAN
+ if (info->cursor && info->cursor->ram)
+ iounmap(info->cursor->ram);
+#endif
+#endif
+
+ if (info->cursor) {
+ if (info->cursor->timer)
+ kfree(info->cursor->timer);
+ kfree(info->cursor);
+ }
+#ifdef __sparc__
+ if (info->mmap_map)
+ kfree(info->mmap_map);
+#endif
+ kfree(info);
+ }
+}
+
+#endif
diff --git a/drivers/video/bwtwofb.c b/drivers/video/bwtwofb.c
index 0735ca1b3..25a223600 100644
--- a/drivers/video/bwtwofb.c
+++ b/drivers/video/bwtwofb.c
@@ -1,4 +1,4 @@
-/* $Id: bwtwofb.c,v 1.7 1999/01/26 10:55:02 jj Exp $
+/* $Id: bwtwofb.c,v 1.8 1999/08/26 05:13:09 shadow Exp $
* bwtwofb.c: BWtwo frame buffer driver
*
* Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
@@ -216,7 +216,7 @@ char __init *bwtwofb_init(struct fb_info_sbusfb *fb)
#endif
fb->margins = bw2_margins;
- fb->physbase = phys;
+ fb->physbase = __get_phys(fb->sbdp->sbus_vaddrs[0]);
fb->mmap_map = bw2_mmap_map;
#ifdef __sparc_v9__
diff --git a/drivers/video/cgfourteenfb.c b/drivers/video/cgfourteenfb.c
index c5dfaad6e..0e1f095c6 100644
--- a/drivers/video/cgfourteenfb.c
+++ b/drivers/video/cgfourteenfb.c
@@ -1,4 +1,4 @@
-/* $Id: cgfourteenfb.c,v 1.4 1999/01/26 10:55:03 jj Exp $
+/* $Id: cgfourteenfb.c,v 1.5 1999/08/10 15:56:02 davem Exp $
* cgfourteenfb.c: CGfourteen frame buffer driver
*
* Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
@@ -288,19 +288,19 @@ static int cg14_ioctl (struct fb_info_sbusfb *fb, unsigned int cmd, unsigned lon
return 0;
}
-__initfunc(static unsigned long get_phys(unsigned long addr))
+static unsigned long __init get_phys(unsigned long addr)
{
return __get_phys(addr);
}
-__initfunc(static int get_iospace(unsigned long addr))
+static int __init get_iospace(unsigned long addr)
{
return __get_iospace(addr);
}
static char idstring[60] __initdata = { 0 };
-__initfunc(char *cgfourteenfb_init(struct fb_info_sbusfb *fb))
+char __init *cgfourteenfb_init(struct fb_info_sbusfb *fb)
{
struct fb_fix_screeninfo *fix = &fb->fix;
struct display *disp = &fb->disp;
diff --git a/drivers/video/cgsixfb.c b/drivers/video/cgsixfb.c
index 1973ba92b..5921e232b 100644
--- a/drivers/video/cgsixfb.c
+++ b/drivers/video/cgsixfb.c
@@ -1,4 +1,4 @@
-/* $Id: cgsixfb.c,v 1.17 1999/05/25 01:00:31 davem Exp $
+/* $Id: cgsixfb.c,v 1.19 1999/08/10 15:56:03 davem Exp $
* cgsixfb.c: CGsix (GX,GXplus) frame buffer driver
*
* Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
@@ -588,9 +588,21 @@ static void cg6_margins (struct fb_info_sbusfb *fb, struct display *p, int x_mar
p->screen_base += (y_margin - fb->y_margin) * p->line_length + (x_margin - fb->x_margin);
}
+static int __init cg6_rasterimg (struct fb_info *info, int start)
+{
+ struct fb_info_sbusfb *fb = sbusfbinfo(info);
+ register struct cg6_fbc *fbc = fb->s.cg6.fbc;
+ int i;
+
+ do {
+ i = fbc->s;
+ } while (i & 0x10000000);
+ return 0;
+}
+
static char idstring[70] __initdata = { 0 };
-__initfunc(char *cgsixfb_init(struct fb_info_sbusfb *fb))
+char __init *cgsixfb_init(struct fb_info_sbusfb *fb)
{
struct fb_fix_screeninfo *fix = &fb->fix;
struct fb_var_screeninfo *var = &fb->var;
@@ -601,10 +613,20 @@ __initfunc(char *cgsixfb_init(struct fb_info_sbusfb *fb))
char *p;
char *cardtype;
struct bt_regs *bt;
+ struct fb_ops *fbops;
+
+ fbops = kmalloc(sizeof(*fbops), GFP_KERNEL);
+ if (!fbops) return NULL;
+
+ *fbops = *fb->info.fbops;
+ fbops->fb_rasterimg = cg6_rasterimg;
+ fb->info.fbops = fbops;
+
+ if (prom_getbool (fb->prom_node, "dblbuf")) {
+ type->fb_size *= 4;
+ fix->smem_len *= 4;
+ }
- strcpy(fb->info.modename, "CGsix");
-
- strcpy(fix->id, "CGsix");
fix->line_length = fb->var.xres_virtual;
fix->accel = FB_ACCEL_SUN_CGSIX;
@@ -660,9 +682,9 @@ __initfunc(char *cgsixfb_init(struct fb_info_sbusfb *fb))
if (((conf >> CG6_FHC_REV_SHIFT) & CG6_FHC_REV_MASK) >= 11) {
if (fix->smem_len <= 0x100000) {
- cardtype = "TurboGX";
+ cardtype = "TGX";
} else {
- cardtype = "TurboGX+";
+ cardtype = "TGX+";
}
} else {
if (fix->smem_len <= 0x100000) {
@@ -680,6 +702,9 @@ __initfunc(char *cgsixfb_init(struct fb_info_sbusfb *fb))
#endif
(fb->s.cg6.thc->thc_misc >> CG6_THC_MISC_REV_SHIFT) & CG6_THC_MISC_REV_MASK,
p, conf >> CG6_FHC_REV_SHIFT & CG6_FHC_REV_MASK, cardtype);
+
+ sprintf(fb->info.modename, "CGsix [%s]", cardtype);
+ sprintf(fix->id, "CGsix [%s]", cardtype);
cg6_reset(fb);
diff --git a/drivers/video/cgthreefb.c b/drivers/video/cgthreefb.c
index 91611c674..e8cb95e59 100644
--- a/drivers/video/cgthreefb.c
+++ b/drivers/video/cgthreefb.c
@@ -1,4 +1,4 @@
-/* $Id: cgthreefb.c,v 1.4 1999/01/26 10:55:01 jj Exp $
+/* $Id: cgthreefb.c,v 1.5 1999/08/10 15:56:04 davem Exp $
* cgthreefb.c: CGthree frame buffer driver
*
* Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
@@ -145,7 +145,7 @@ static u_char cg3_dacvals[] __initdata = {
static char idstring[60] __initdata = { 0 };
-__initfunc(char *cgthreefb_init(struct fb_info_sbusfb *fb))
+char __init *cgthreefb_init(struct fb_info_sbusfb *fb)
{
struct fb_fix_screeninfo *fix = &fb->fix;
struct display *disp = &fb->disp;
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
index eb5d8931c..79df3aa98 100644
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/chipsfb.c
@@ -112,7 +112,7 @@ static struct notifier_block chips_sleep_notifier = {
/*
* Exported functions
*/
-void chips_init(void);
+int chips_init(void);
void chips_of_init(struct device_node *dp);
static int chips_open(struct fb_info *info, int user);
@@ -525,7 +525,7 @@ static struct chips_init_reg chips_init_xr[] = {
{ 0xa8, 0x00 }
};
-__initfunc(static void chips_hw_init(struct fb_info_chips *p))
+static void __init chips_hw_init(struct fb_info_chips *p)
{
int i;
@@ -544,12 +544,12 @@ __initfunc(static void chips_hw_init(struct fb_info_chips *p))
write_fr(chips_init_fr[i].addr, chips_init_fr[i].data);
}
-__initfunc(static void init_chips(struct fb_info_chips *p))
+static void __init init_chips(struct fb_info_chips *p)
{
int i;
strcpy(p->fix.id, "C&T 65550");
- p->fix.smem_start = (char *) p->frame_buffer_phys;
+ p->fix.smem_start = p->frame_buffer_phys;
// FIXME: Assumes 1MB frame buffer, but 65550 supports 1MB or 2MB.
// * "3500" PowerBook G3 (the original PB G3) has 2MB.
@@ -559,7 +559,7 @@ __initfunc(static void init_chips(struct fb_info_chips *p))
// * 3400 has 1MB (I think). Don't know if it's expandable.
// -- Tim Seufert
p->fix.smem_len = 0x100000; // 1MB
- p->fix.mmio_start = (char *) p->io_base_phys;
+ p->fix.mmio_start = p->io_base_phys;
p->fix.type = FB_TYPE_PACKED_PIXELS;
p->fix.visual = FB_VISUAL_PSEUDOCOLOR;
p->fix.line_length = 800;
@@ -645,7 +645,7 @@ __initfunc(static void init_chips(struct fb_info_chips *p))
all_chips = p;
}
-__initfunc(void chips_init(void))
+int __init chips_init(void)
{
#ifndef CONFIG_FB_OF
struct device_node *dp;
@@ -654,9 +654,10 @@ __initfunc(void chips_init(void))
if (dp != 0)
chips_of_init(dp);
#endif /* CONFIG_FB_OF */
+ return 0;
}
-__initfunc(void chips_of_init(struct device_node *dp))
+void __init chips_of_init(struct device_node *dp)
{
struct fb_info_chips *p;
unsigned long addr;
diff --git a/drivers/video/clgenfb.c b/drivers/video/clgenfb.c
index 3f95ae58c..23e0f64dc 100644
--- a/drivers/video/clgenfb.c
+++ b/drivers/video/clgenfb.c
@@ -1,7 +1,39 @@
/*
- * Based on retz3fb.c and clgen.c
+ * drivers/video/clgenfb.c - driver for Cirrus Logic chipsets
+ *
+ * Copyright 1999 Jeff Garzik <jgarzik@pobox.com>
+ *
+ * Contributors (thanks, all!)
+ *
+ * Jeff Rugen:
+ * Major contributions; Motorola PowerStack (PPC and PCI) support,
+ * GD54xx, 1280x1024 mode support, change MCLK based on VCLK.
+ *
+ * Geert Uytterhoeven:
+ * Excellent code review.
+ *
+ * Lars Hecking:
+ * Amiga updates and testing.
+ *
+ * Original clgenfb author: Frank Neumann
+ *
+ * Based on retz3fb.c and clgen.c:
+ * Copyright (C) 1997 Jes Sorensen
+ * Copyright (C) 1996 Frank Neumann
+ *
+ ***************************************************************
+ *
+ * Format this code with GNU indent '-kr -i8 -pcs' options.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ *
*/
-
+
+#define CLGEN_VERSION "1.9.4.4"
+
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -11,12 +43,23 @@
#include <linux/malloc.h>
#include <linux/delay.h>
#include <linux/fb.h>
-#include <linux/zorro.h>
#include <linux/init.h>
-#include <asm/amigahw.h>
+#include <linux/selection.h>
#include <asm/pgtable.h>
#include <asm/delay.h>
#include <asm/io.h>
+#ifdef CONFIG_ZORRO
+#include <linux/zorro.h>
+#endif
+#ifdef CONFIG_PCI
+#include <linux/pci.h>
+#endif
+#ifdef CONFIG_AMIGA
+#include <asm/amigahw.h>
+#endif
+#ifdef CONFIG_FB_OF
+#include <asm/prom.h>
+#endif
#include <video/fbcon.h>
#include <video/fbcon-mfb.h>
@@ -26,125 +69,415 @@
#include <video/fbcon-cfb32.h>
#include "clgenfb.h"
+#include "vga.h"
-#define CLGEN_VERSION "1.4 ?"
-/* #define DEBUG if(1) */
-#define DEBUG if(0)
+
+/*****************************************************************
+ *
+ * compatibility with older kernel versions
+ *
+ */
+
+#ifndef LINUX_VERSION_CODE
+#include <linux/version.h>
+#endif
+
+#ifndef KERNEL_VERSION
+#define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
+#endif
+
+#ifndef PCI_DEVICE_ID_CIRRUS_5462
+#define PCI_DEVICE_ID_CIRRUS_5462 0x00d0
+#endif
+
+
+
+
+/*****************************************************************
+ *
+ * debugging and utility macros
+ *
+ */
+
+/* enable debug output? */
+/* #define CLGEN_DEBUG 1 */
+
+/* disable runtime assertions? */
+/* #define CLGEN_NDEBUG */
+
+
+/* debug output */
+#ifdef CLGEN_DEBUG
+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+/* debugging assertions */
+#ifndef CLGEN_NDEBUG
+#define assert(expr) \
+ if(!(expr)) { \
+ printk( "Assertion failed! %s,%s,%s,line=%d\n",\
+ #expr,__FILE__,__FUNCTION__,__LINE__); \
+ }
+#else
+#define assert(expr)
+#endif
#define arraysize(x) (sizeof(x)/sizeof(*(x)))
-/* board types */
-#define BT_NONE 0
-#define BT_SD64 1
-#define BT_PICCOLO 2
-#define BT_PICASSO 3
-#define BT_SPECTRUM 4
-#define BT_PICASSO4 5
+#ifdef TRUE
+#undef TRUE
+#endif
+#ifdef FALSE
+#undef FALSE
+#endif
+#define TRUE 1
+#define FALSE 0
+
+#define MB_ (1024*1024)
#define MAX_NUM_BOARDS 7
-#define TRUE 1
-#define FALSE 0
-struct clgenfb_par
-{
- struct fb_var_screeninfo var;
-
- __u32 line_length; /* in BYTES! */
- __u32 visual;
- __u32 type;
-
- long freq;
- long nom;
- long den;
- long div;
-
- long HorizRes; /* The x resolution in pixel */
- long HorizTotal;
- long HorizDispEnd;
- long HorizBlankStart;
- long HorizBlankEnd;
- long HorizSyncStart;
- long HorizSyncEnd;
-
- long VertRes; /* the physical y resolution in scanlines */
- long VertTotal;
- long VertDispEnd;
- long VertSyncStart;
- long VertSyncEnd;
- long VertBlankStart;
- long VertBlankEnd;
+
+
+/*****************************************************************
+ *
+ * chipset information
+ *
+ */
+
+/* board types */
+typedef enum {
+ BT_NONE = 0,
+ BT_SD64,
+ BT_PICCOLO,
+ BT_PICASSO,
+ BT_SPECTRUM,
+ BT_PICASSO4, /* GD5446 */
+ BT_ALPINE, /* GD543x/4x */
+ BT_GD5480,
+ BT_LAGUNA, /* GD546x */
+} clgen_board_t;
+
+
+
+/*
+ * per-board-type information, used for enumerating and abstracting
+ * chip-specific information
+ * NOTE: MUST be in the same order as clgen_board_t in order to
+ * use direct indexing on this array
+ * NOTE: '__initdata' cannot be used as some of this info
+ * is required at runtime. Maybe separate into an init-only and
+ * a run-time table?
+ */
+static const struct clgen_board_info_rec {
+ clgen_board_t btype; /* chipset enum, not strictly necessary, as
+ * clgen_board_info[] is directly indexed
+ * by this value */
+ char *name; /* ASCII name of chipset */
+ long maxclock; /* maximum video clock */
+ unsigned init_sr07 : 1; /* init SR07 during init_vgachip() */
+ unsigned init_sr1f : 1; /* write SR1F during init_vgachip() */
+ unsigned scrn_start_bit19 : 1; /* construct bit 19 of screen start address */
+
+ /* initial SR07 value, then for each mode */
+ unsigned char sr07;
+ unsigned char sr07_1bpp;
+ unsigned char sr07_1bpp_mux;
+ unsigned char sr07_8bpp;
+ unsigned char sr07_8bpp_mux;
+
+ unsigned char sr1f; /* SR1F VGA initial register value */
+} clgen_board_info[] = {
+ { BT_NONE, }, /* dummy record */
+ { BT_SD64,
+ "CL SD64",
+ 140000, /* the SD64/P4 have a higher max. videoclock */
+ TRUE,
+ TRUE,
+ TRUE,
+ 0xF0,
+ 0xF0,
+ 0, /* unused, does not multiplex */
+ 0xF1,
+ 0, /* unused, does not multiplex */
+ 0x20 },
+ { BT_PICCOLO,
+ "CL Piccolo",
+ 90000,
+ TRUE,
+ TRUE,
+ FALSE,
+ 0x80,
+ 0x80,
+ 0, /* unused, does not multiplex */
+ 0x81,
+ 0, /* unused, does not multiplex */
+ 0x22 },
+ { BT_PICASSO,
+ "CL Picasso",
+ 90000,
+ TRUE,
+ TRUE,
+ FALSE,
+ 0x20,
+ 0x20,
+ 0, /* unused, does not multiplex */
+ 0x21,
+ 0, /* unused, does not multiplex */
+ 0x22 },
+ { BT_SPECTRUM,
+ "CL Spectrum",
+ 90000,
+ TRUE,
+ TRUE,
+ FALSE,
+ 0x80,
+ 0x80,
+ 0, /* unused, does not multiplex */
+ 0x81,
+ 0, /* unused, does not multiplex */
+ 0x22 },
+ { BT_PICASSO4,
+ "CL Picasso4",
+ 140000, /* the SD64/P4 have a higher max. videoclock */
+ TRUE,
+ FALSE,
+ TRUE,
+ 0x20,
+ 0x20,
+ 0, /* unused, does not multiplex */
+ 0x21,
+ 0, /* unused, does not multiplex */
+ 0 },
+ { BT_ALPINE,
+ "CL Alpine",
+ 110000, /* 135100 for some, 85500 for others */
+ TRUE,
+ TRUE,
+ TRUE,
+ 0xA0,
+ 0xA1,
+ 0xA7,
+ 0xA1,
+ 0xA7,
+ 0x1C },
+ { BT_GD5480,
+ "CL GD5480",
+ 90000,
+ TRUE,
+ TRUE,
+ TRUE,
+ 0x10,
+ 0x11,
+ 0, /* unused, does not multiplex */
+ 0x11,
+ 0, /* unused, does not multiplex */
+ 0x1C },
+ { BT_LAGUNA,
+ "CL Laguna",
+ 135100,
+ FALSE,
+ FALSE,
+ TRUE,
+ 0, /* unused */
+ 0, /* unused */
+ 0, /* unused */
+ 0, /* unused */
+ 0, /* unused */
+ 0 }, /* unused */
+};
+
+
+#ifdef CONFIG_PCI
+/* the list of PCI devices for which we probe, and the
+ * order in which we do it */
+static const struct {
+ clgen_board_t btype;
+ const char *nameOverride; /* XXX unused... for now */
+ unsigned short device;
+} clgen_pci_probe_list[] __initdata = {
+ { BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5436 },
+ { BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5434_8 },
+ { BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5434_4 },
+ { BT_ALPINE, NULL, PCI_DEVICE_ID_CIRRUS_5430 }, /* GD-5440 has identical id */
+ { BT_GD5480, NULL, PCI_DEVICE_ID_CIRRUS_5480 }, /* MacPicasso probably */
+ { BT_PICASSO4, NULL, PCI_DEVICE_ID_CIRRUS_5446 }, /* Picasso 4 is a GD5446 */
+ { BT_LAGUNA, "CL Laguna", PCI_DEVICE_ID_CIRRUS_5462 },
+ { BT_LAGUNA, "CL Laguna 3D", PCI_DEVICE_ID_CIRRUS_5464 },
+ { BT_LAGUNA, "CL Laguna 3DA", PCI_DEVICE_ID_CIRRUS_5465 },
+};
+#endif /* CONFIG_PCI */
+
+
+
+#ifdef CONFIG_ZORRO
+static const struct {
+ clgen_board_t btype;
+ int key, key2;
+} clgen_zorro_probe_list[] __initdata = {
+ { BT_SD64,
+ ZORRO_PROD_HELFRICH_SD64_RAM,
+ ZORRO_PROD_HELFRICH_SD64_REG },
+ { BT_PICCOLO,
+ ZORRO_PROD_HELFRICH_PICCOLO_RAM,
+ ZORRO_PROD_HELFRICH_PICCOLO_REG },
+ { BT_PICASSO,
+ ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
+ ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG },
+ { BT_SPECTRUM,
+ ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
+ ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG },
+ { BT_PICASSO4,
+ ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3,
+ 0 },
+};
+#endif /* CONFIG_ZORRO */
+
+
+
+struct clgenfb_par {
+ struct fb_var_screeninfo var;
+
+ __u32 line_length; /* in BYTES! */
+ __u32 visual;
+ __u32 type;
+
+ long freq;
+ long nom;
+ long den;
+ long div;
+ long multiplexing;
+ long mclk;
+ long divMCLK;
+
+ long HorizRes; /* The x resolution in pixel */
+ long HorizTotal;
+ long HorizDispEnd;
+ long HorizBlankStart;
+ long HorizBlankEnd;
+ long HorizSyncStart;
+ long HorizSyncEnd;
+
+ long VertRes; /* the physical y resolution in scanlines */
+ long VertTotal;
+ long VertDispEnd;
+ long VertSyncStart;
+ long VertSyncEnd;
+ long VertBlankStart;
+ long VertBlankEnd;
};
+
+
+#ifdef CLGEN_DEBUG
+typedef enum {
+ CRT,
+ SEQ
+} clgen_dbg_reg_class_t;
+#endif /* CLGEN_DEBUG */
+
+
+
+
/* info about board */
-struct clgenfb_info
-{
- struct fb_info_gen gen;
-
- int keyRAM; /* RAM, REG zorro board keys */
- int keyREG;
- unsigned long fbmem;
- volatile unsigned char *regs;
- unsigned long mem;
- unsigned long size;
- int btype;
- int smallboard;
- unsigned char SFR; /* Shadow of special function register */
-
- unsigned long fbmem_phys;
- unsigned long fbregs_phys;
-
- struct clgenfb_par currentmode;
- union {
+struct clgenfb_info {
+ struct fb_info_gen gen;
+
+ caddr_t fbmem;
+ caddr_t regs;
+ caddr_t mem;
+ unsigned long size;
+ clgen_board_t btype;
+ int smallboard;
+ unsigned char SFR; /* Shadow of special function register */
+
+ unsigned long fbmem_phys;
+ unsigned long fbregs_phys;
+
+ struct clgenfb_par currentmode;
+
+ struct { u8 red, green, blue, pad; } palette[256];
+
+ union {
#ifdef FBCON_HAS_CFB16
- u16 cfb16[16];
+ u16 cfb16[16];
#endif
#ifdef FBCON_HAS_CFB24
- u32 cfb24[16];
+ u32 cfb24[16];
#endif
#ifdef FBCON_HAS_CFB32
- u32 cfb32[16];
+ u32 cfb32[16];
+#endif
+ } fbcon_cmap;
+
+#ifdef CONFIG_ZORRO
+ int keyRAM; /* RAM, REG zorro board keys */
+ int keyREG;
+ unsigned long board_addr,
+ board_size;
+#endif
+
+#ifdef CONFIG_PCI
+ struct pci_dev *pdev;
#endif
- } fbcon_cmap;
};
+
+
+
static struct display disp;
-static struct clgenfb_info boards[MAX_NUM_BOARDS]; /* the boards */
-static struct clgenfb_info *fb_info=NULL; /* pointer to current board */
+static struct clgenfb_info boards[MAX_NUM_BOARDS]; /* the boards */
+
+static unsigned clgen_def_mode = 1;
+
+static int release_io_ports = 0;
+
+
/*
* Predefined Video Modes
*/
-static struct fb_videomode clgenfb_predefined[] __initdata =
+static const struct {
+ const char *name;
+ struct fb_var_screeninfo var;
+} clgenfb_predefined[] __initdata =
+
{
- { "Autodetect", /* autodetect mode */
- { 0 }
+ {"Autodetect", /* autodetect mode */
+ {0}
},
- { "640x480", /* 640x480, 31.25 kHz, 60 Hz, 25 MHz PixClock */
- {
- 640, 480, 640, 480, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCEL_NONE, 40000, 32, 32, 33, 10, 96, 2,
- FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
- }
+ {"640x480", /* 640x480, 31.25 kHz, 60 Hz, 25 MHz PixClock */
+ {
+ 640, 480, 640, 480, 0, 0, 8, 0,
+ {0, 8, 0},
+ {0, 8, 0},
+ {0, 8, 0},
+ {0, 0, 0},
+ 0, 0, -1, -1, FB_ACCEL_NONE, 40000, 32, 32, 33, 10, 96, 2,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }
},
- /* 1024x768, 55.8 kHz, 70 Hz, 80 MHz PixClock */
/*
- Modeline from XF86Config:
- Mode "1024x768" 80 1024 1136 1340 1432 768 770 774 805
- */
- {
- "1024x768",
- {
- 1024, 768, 1024, 768, 0, 0, 8, 0,
- {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCEL_NONE, 12500, 92, 112, 31, 2, 204, 4,
- FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
- }
+ Modeline from XF86Config:
+ Mode "1024x768" 80 1024 1136 1340 1432 768 770 774 805
+ */
+ {"1024x768", /* 1024x768, 55.8 kHz, 70 Hz, 80 MHz PixClock */
+ {
+ 1024, 768, 1024, 768, 0, 0, 8, 0,
+ {0, 8, 0},
+ {0, 8, 0},
+ {0, 8, 0},
+ {0, 0, 0},
+ 0, 0, -1, -1, FB_ACCEL_NONE, 12500, 92, 112, 31, 2, 204, 4,
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }
}
};
@@ -155,135 +488,189 @@ static struct fb_var_screeninfo clgenfb_default;
* Frame Buffer Name
*/
-static char clgenfb_name[16] = "CLgen";
+static const char *clgenfb_name = "CLgen";
/****************************************************************************/
/**** BEGIN PROTOTYPES ******************************************************/
+
/*--- Interface used by the world ------------------------------------------*/
-void clgenfb_init(void);
-void clgenfb_setup(char *options, int *ints);
-int clgenfb_open(struct fb_info *info, int user);
-int clgenfb_release(struct fb_info *info, int user);
-int clgenfb_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg, int con,
- struct fb_info *info);
+int clgenfb_init (void);
+int clgenfb_setup (char *options);
+
+#ifdef MODULE
+static void clgenfb_cleanup (struct clgenfb_info *info);
+#endif
+
+static int clgenfb_open (struct fb_info *info, int user);
+static int clgenfb_release (struct fb_info *info, int user);
+static int clgenfb_ioctl (struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg, int con,
+ struct fb_info *info);
+#if defined(CONFIG_FB_OF)
+int clgen_of_init (struct device_node *dp);
+#endif
/* function table of the above functions */
static struct fb_ops clgenfb_ops =
{
- clgenfb_open,
- clgenfb_release,
- fbgen_get_fix, /* using the generic functions */
- fbgen_get_var, /* makes things much easier... */
- fbgen_set_var,
- fbgen_get_cmap,
- fbgen_set_cmap,
- fbgen_pan_display,
- clgenfb_ioctl,
- NULL
+ clgenfb_open,
+ clgenfb_release,
+ fbgen_get_fix, /* using the generic functions */
+ fbgen_get_var, /* makes things much easier... */
+ fbgen_set_var,
+ fbgen_get_cmap,
+ fbgen_set_cmap,
+ fbgen_pan_display,
+ clgenfb_ioctl,
+ NULL
};
/*--- Hardware Specific Routines -------------------------------------------*/
-static void clgen_detect(void);
-static int clgen_encode_fix(struct fb_fix_screeninfo *fix, const void *par,
+static void clgen_detect (void);
+static int clgen_encode_fix (struct fb_fix_screeninfo *fix, const void *par,
struct fb_info_gen *info);
-static int clgen_decode_var(const struct fb_var_screeninfo *var, void *par,
+static int clgen_decode_var (const struct fb_var_screeninfo *var, void *par,
struct fb_info_gen *info);
-static int clgen_encode_var(struct fb_var_screeninfo *var, const void *par,
+static int clgen_encode_var (struct fb_var_screeninfo *var, const void *par,
struct fb_info_gen *info);
-static void clgen_get_par(void *par, struct fb_info_gen *info);
-static void clgen_set_par(const void *par, struct fb_info_gen *info);
-static int clgen_getcolreg(unsigned regno, unsigned *red, unsigned *green,
- unsigned *blue, unsigned *transp,
- struct fb_info *info);
-static int clgen_setcolreg(unsigned regno, unsigned red, unsigned green,
+static void clgen_get_par (void *par, struct fb_info_gen *info);
+static void clgen_set_par (const void *par, struct fb_info_gen *info);
+static int clgen_getcolreg (unsigned regno, unsigned *red, unsigned *green,
+ unsigned *blue, unsigned *transp,
+ struct fb_info *info);
+static int clgen_setcolreg (unsigned regno, unsigned red, unsigned green,
unsigned blue, unsigned transp,
struct fb_info *info);
-static int clgen_pan_display(const struct fb_var_screeninfo *var,
+static int clgen_pan_display (const struct fb_var_screeninfo *var,
struct fb_info_gen *info);
-static int clgen_blank(int blank_mode, struct fb_info_gen *info);
+static int clgen_blank (int blank_mode, struct fb_info_gen *info);
-static void clgen_set_disp(const void *par, struct display *disp,
- struct fb_info_gen *info);
+static void clgen_set_disp (const void *par, struct display *disp,
+ struct fb_info_gen *info);
/* function table of the above functions */
-static struct fbgen_hwswitch clgen_hwswitch =
+static struct fbgen_hwswitch clgen_hwswitch =
{
- clgen_detect,
- clgen_encode_fix,
- clgen_decode_var,
- clgen_encode_var,
- clgen_get_par,
- clgen_set_par,
- clgen_getcolreg,
- clgen_setcolreg,
- clgen_pan_display,
- clgen_blank,
- clgen_set_disp
+ clgen_detect,
+ clgen_encode_fix,
+ clgen_decode_var,
+ clgen_encode_var,
+ clgen_get_par,
+ clgen_set_par,
+ clgen_getcolreg,
+ clgen_setcolreg,
+ clgen_pan_display,
+ clgen_blank,
+ clgen_set_disp
};
/* Text console acceleration */
#ifdef FBCON_HAS_CFB8
-static void fbcon_clgen8_bmove(struct display *p, int sy, int sx,
+static void fbcon_clgen8_bmove (struct display *p, int sy, int sx,
int dy, int dx, int height, int width);
-static void fbcon_clgen8_clear(struct vc_data *conp, struct display *p,
+static void fbcon_clgen8_clear (struct vc_data *conp, struct display *p,
int sy, int sx, int height, int width);
-static struct display_switch fbcon_clgen_8 = {
- fbcon_cfb8_setup,
- fbcon_clgen8_bmove,
- fbcon_clgen8_clear,
- fbcon_cfb8_putc,
- fbcon_cfb8_putcs,
- fbcon_cfb8_revc,
- NULL,
- NULL,
- fbcon_cfb8_clear_margins,
- FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+static struct display_switch fbcon_clgen_8 =
+{
+ fbcon_cfb8_setup,
+ fbcon_clgen8_bmove,
+ fbcon_clgen8_clear,
+ fbcon_cfb8_putc,
+ fbcon_cfb8_putcs,
+ fbcon_cfb8_revc,
+ NULL,
+ NULL,
+ fbcon_cfb8_clear_margins,
+ FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)
+};
+#endif
+#ifdef FBCON_HAS_CFB16
+static void fbcon_clgen16_bmove (struct display *p, int sy, int sx,
+ int dy, int dx, int height, int width);
+static void fbcon_clgen16_clear (struct vc_data *conp, struct display *p,
+ int sy, int sx, int height, int width);
+static struct display_switch fbcon_clgen_16 =
+{
+ fbcon_cfb16_setup,
+ fbcon_clgen16_bmove,
+ fbcon_clgen16_clear,
+ fbcon_cfb16_putc,
+ fbcon_cfb16_putcs,
+ fbcon_cfb16_revc,
+ NULL,
+ NULL,
+ fbcon_cfb16_clear_margins,
+ FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)
+};
+#endif
+#ifdef FBCON_HAS_CFB32
+static void fbcon_clgen32_bmove (struct display *p, int sy, int sx,
+ int dy, int dx, int height, int width);
+static void fbcon_clgen32_clear (struct vc_data *conp, struct display *p,
+ int sy, int sx, int height, int width);
+static struct display_switch fbcon_clgen_32 =
+{
+ fbcon_cfb32_setup,
+ fbcon_clgen32_bmove,
+ fbcon_clgen32_clear,
+ fbcon_cfb32_putc,
+ fbcon_cfb32_putcs,
+ fbcon_cfb32_revc,
+ NULL,
+ NULL,
+ fbcon_cfb32_clear_margins,
+ FONTWIDTH (4) | FONTWIDTH (8) | FONTWIDTH (12) | FONTWIDTH (16)
};
#endif
/*--- Internal routines ----------------------------------------------------*/
-static void init_vgachip(void);
-static void switch_monitor(int on);
-
-static void WGen( int regnum, unsigned char val );
-static unsigned char RGen( int regnum );
-static void WSeq( unsigned char regnum, unsigned char val );
-static unsigned char RSeq( unsigned char regnum );
-static void WCrt( unsigned char regnum, unsigned char val );
-static unsigned char RCrt( unsigned char regnum );
-static void WGfx( unsigned char regnum, unsigned char val );
-static unsigned char RGfx( unsigned char regnum );
-static void WAttr( unsigned char regnum, unsigned char val );
-static void AttrOn( void );
-static unsigned char RAttr( unsigned char regnum );
-static void WHDR( unsigned char val );
-static unsigned char RHDR( void );
-static void WSFR( unsigned char val );
-static void WSFR2( unsigned char val );
-static void WClut( unsigned char regnum, unsigned char red,
- unsigned char green,
- unsigned char blue );
-static void RClut( unsigned char regnum, unsigned char *red,
- unsigned char *green,
- unsigned char *blue );
-static void clgen_WaitBLT( void );
-static void clgen_BitBLT (u_short curx, u_short cury,
- u_short destx, u_short desty,
- u_short width, u_short height,
- u_short line_length);
-static void clgen_RectFill (u_short x, u_short y,
- u_short width, u_short height,
- u_char color, u_short line_length);
-
-static void bestclock(long freq, long *best,
- long *nom, long *den,
- long *div, long maxfreq);
+static void init_vgachip (struct clgenfb_info *fb_info);
+static void switch_monitor (struct clgenfb_info *fb_info, int on);
+static void WGen (const struct clgenfb_info *fb_info,
+ int regnum, unsigned char val);
+static unsigned char RGen (const struct clgenfb_info *fb_info, int regnum);
+static void AttrOn (const struct clgenfb_info *fb_info);
+static void WHDR (const struct clgenfb_info *fb_info, unsigned char val);
+static void WSFR (struct clgenfb_info *fb_info, unsigned char val);
+static void WSFR2 (struct clgenfb_info *fb_info, unsigned char val);
+static void WClut (struct clgenfb_info *fb_info, unsigned char regnum, unsigned char red,
+ unsigned char green,
+ unsigned char blue);
+#if 0
+static void RClut (struct clgenfb_info *fb_info, unsigned char regnum, unsigned char *red,
+ unsigned char *green,
+ unsigned char *blue);
+#endif
+static void clgen_WaitBLT (caddr_t regbase);
+static void clgen_BitBLT (caddr_t regbase, u_short curx, u_short cury,
+ u_short destx, u_short desty,
+ u_short width, u_short height,
+ u_short line_length);
+static void clgen_RectFill (struct clgenfb_info *fb_info, u_short x, u_short y,
+ u_short width, u_short height,
+ u_char color, u_short line_length);
+
+static void bestclock (long freq, long *best,
+ long *nom, long *den,
+ long *div, long maxfreq);
+
+#ifdef CONFIG_PCI
+static struct pci_dev *clgen_pci_dev_get (clgen_board_t *btype);
+static unsigned int clgen_get_memsize (caddr_t regbase);
+static int clgen_pci_setup (struct clgenfb_info *fb_info, clgen_board_t *btype);
+#endif /* CONFIG_PCI */
+
+#ifdef CLGEN_DEBUG
+static void clgen_dump (void);
+static void clgen_dbg_reg_dump (caddr_t regbase);
+static void clgen_dbg_print_regs (caddr_t regbase, clgen_dbg_reg_class_t reg_class,...);
+static void clgen_dbg_print_byte (const char *name, unsigned char val);
+#endif /* CLGEN_DEBUG */
/*** END PROTOTYPES ********************************************************/
/*****************************************************************************/
@@ -292,302 +679,478 @@ static void bestclock(long freq, long *best,
static int opencount = 0;
/*--- Open /dev/fbx ---------------------------------------------------------*/
-int clgenfb_open(struct fb_info *info, int user)
+static int clgenfb_open (struct fb_info *info, int user)
{
- MOD_INC_USE_COUNT;
- if (opencount++ == 0) switch_monitor(1);
- return 0;
+ MOD_INC_USE_COUNT;
+ if (opencount++ == 0)
+ switch_monitor ((struct clgenfb_info *) info, 1);
+ return 0;
}
/*--- Close /dev/fbx --------------------------------------------------------*/
-int clgenfb_release(struct fb_info *info, int user)
+static int clgenfb_release (struct fb_info *info, int user)
{
- if (--opencount == 0) switch_monitor(0);
- MOD_DEC_USE_COUNT;
- return 0;
+ if (--opencount == 0)
+ switch_monitor ((struct clgenfb_info *) info, 0);
+ MOD_DEC_USE_COUNT;
+ return 0;
}
/*--- handle /dev/fbx ioctl calls ------------------------------------------*/
-int clgenfb_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg, int con,
- struct fb_info *info)
+static int clgenfb_ioctl (struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg, int con,
+ struct fb_info *info)
{
- printk(">clgenfb_ioctl()\n");
- /* Nothing exciting here... */
- printk("<clgenfb_ioctl()\n");
- return -EINVAL;
+ DPRINTK ("ENTER\n");
+ /* Nothing exciting here... */
+ DPRINTK ("EXIT\n");
+ return -EINVAL;
}
-
/**** END Interface used by the World *************************************/
/****************************************************************************/
/**** BEGIN Hardware specific Routines **************************************/
-static void clgen_detect(void)
+static void clgen_detect (void)
{
- printk(">clgen_detect()\n");
- printk("<clgen_detect()\n");
+ DPRINTK ("ENTER\n");
+ DPRINTK ("EXIT\n");
}
-static int clgen_encode_fix(struct fb_fix_screeninfo *fix, const void *par,
- struct fb_info_gen *info)
+static int clgen_encode_fix (struct fb_fix_screeninfo *fix, const void *par,
+ struct fb_info_gen *info)
{
- struct clgenfb_par *_par = (struct clgenfb_par*) par;
- struct clgenfb_info *_info = (struct clgenfb_info*)info;
-
- memset(fix, 0, sizeof(struct fb_fix_screeninfo));
- strcpy(fix->id, clgenfb_name);
-
- fix->smem_start = (char*)_info->fbmem_phys;
-
- /* monochrome: only 1 memory plane */
- /* 8 bit and above: Use whole memory area */
- fix->smem_len = _par->var.bits_per_pixel == 1 ? _info->size / 4
- : _info->size;
- fix->type = _par->type;
- fix->type_aux = 0;
- fix->visual = _par->visual;
- fix->xpanstep = 1;
- fix->ypanstep = 1;
- fix->ywrapstep = 0;
- fix->line_length = _par->line_length;
- fix->mmio_start = (char *)_info->fbregs_phys;
- fix->mmio_len = 0x10000;
- fix->accel = FB_ACCEL_NONE;
+ struct clgenfb_par *_par = (struct clgenfb_par *) par;
+ struct clgenfb_info *_info = (struct clgenfb_info *) info;
+
+ DPRINTK ("ENTER\n");
+
+ memset (fix, 0, sizeof (struct fb_fix_screeninfo));
+ strcpy (fix->id, clgenfb_name);
+
+ if (_info->btype == BT_GD5480) {
+ /* Select proper byte-swapping aperture */
+ switch (_par->var.bits_per_pixel) {
+ case 1:
+ case 8:
+ fix->smem_start = _info->fbmem_phys;
+ break;
+ case 16:
+ fix->smem_start = _info->fbmem_phys + 1 * MB_;
+ break;
+ case 24:
+ case 32:
+ fix->smem_start = _info->fbmem_phys + 2 * MB_;
+ break;
+ }
+ } else {
+ fix->smem_start = _info->fbmem_phys;
+ }
- return 0;
+ /* monochrome: only 1 memory plane */
+ /* 8 bit and above: Use whole memory area */
+ fix->smem_len = _par->var.bits_per_pixel == 1 ? _info->size / 4
+ : _info->size;
+ fix->type = _par->type;
+ fix->type_aux = 0;
+ fix->visual = _par->visual;
+ fix->xpanstep = 1;
+ fix->ypanstep = 1;
+ fix->ywrapstep = 0;
+ fix->line_length = _par->line_length;
+
+ /* FIXME: map region at 0xB8000 if available, fill in here */
+ fix->mmio_start = 0;
+ fix->mmio_len = 0;
+ fix->accel = FB_ACCEL_NONE;
+
+ DPRINTK ("EXIT\n");
+ return 0;
}
-static int clgen_decode_var(const struct fb_var_screeninfo *var, void *par,
- struct fb_info_gen *info)
+
+
+/* Get a good MCLK value */
+static long clgen_get_mclk (long freq, int bpp, long *div)
{
- long freq;
- int xres, hfront, hsync, hback;
- int yres, vfront, vsync, vback;
- int nom,den; /* translyting from pixels->bytes */
- int i;
- static struct
- {
- int xres,yres;
- }
- modes[] = { {1600,1280}, {1280,1024}, {1024,768},
- {800,600}, {640,480}, {-1,-1} };
-
- struct clgenfb_par *_par = (struct clgenfb_par *)par;
-
- fb_info = (struct clgenfb_info*)info;
- printk("clgen_decode_var()\n");
-
- printk("Requested: %dx%dx%d\n", var->xres,var->yres,var->bits_per_pixel);
- printk(" virtual: %dx%d\n", var->xres_virtual,var->yres_virtual);
- printk(" offset: (%d,%d)\n", var->xoffset, var->yoffset);
- printk("grayscale: %d\n", var->grayscale);
-#if 0
- printk(" activate: 0x%x\n", var->activate);
- printk(" pixclock: %d\n", var->pixclock);
- printk(" htiming: %d;%d %d\n", var->left_margin,var->right_margin,var->hsync_len);
- printk(" vtiming: %d;%d %d\n", var->upper_margin,var->lower_margin,var->vsync_len);
- printk(" sync: 0x%x\n", var->sync);
- printk(" vmode: 0x%x\n", var->vmode);
-#endif
+ long mclk;
+
+ assert (div != NULL);
+
+ /* Calculate MCLK, in case VCLK is high enough to require > 50MHz.
+ * Assume a 64-bit data path for now. The formula is:
+ * ((B * PCLK * 2)/W) * 1.2
+ * B = bytes per pixel, PCLK = pixclock, W = data width in bytes */
+ mclk = ((bpp / 8) * freq * 2) / 4;
+ mclk = (mclk * 12) / 10;
+ if (mclk < 50000)
+ mclk = 50000;
+ DPRINTK ("Use MCLK of %ld kHz\n", mclk);
+
+ /* Calculate value for SR1F. Multiply by 2 so we can round up. */
+ mclk = ((mclk * 16) / 14318);
+ mclk = (mclk + 1) / 2;
+ DPRINTK ("Set SR1F[5:0] to 0x%lx\n", mclk);
+
+ /* Determine if we should use MCLK instead of VCLK, and if so, what we
+ * should divide it by to get VCLK */
+ switch (freq) {
+ case 24751 ... 25249:
+ *div = 2;
+ DPRINTK ("Using VCLK = MCLK/2\n");
+ break;
+ case 49501 ... 50499:
+ *div = 1;
+ DPRINTK ("Using VCLK = MCLK\n");
+ break;
+ default:
+ *div = 0;
+ break;
+ }
- _par->var = *var;
-
- switch (var->bits_per_pixel)
- {
- case 1: nom = 4; den = 8; break; /* 8 pixel per byte, only 1/4th of mem usable */
- case 8: nom = 1; den = 1; break; /* 1 pixel == 1 byte */
- case 16: nom = 2; den = 1; break; /* 2 bytes per pixel */
- case 24: nom = 3; den = 1; break; /* 3 bytes per pixel */
- case 32: nom = 4; den = 1; break; /* 4 bytes per pixel */
- default:
- printk("clgen: mode %dx%dx%d rejected...color depth not supported.\n",
- var->xres, var->yres, var->bits_per_pixel);
- return -EINVAL;
- }
+ return mclk;
+}
- if (_par->var.xres*nom/den * _par->var.yres > fb_info->size)
- {
- printk("clgen: mode %dx%dx%d rejected...resolution too high to fit into video memory!\n",
- var->xres, var->yres, var->bits_per_pixel);
- return -EINVAL;
- }
-
- /* use highest possible virtual resolution */
- if (_par->var.xres_virtual == -1 &&
- _par->var.yres_virtual == -1)
- {
- printk("clgen: using maximum available virtual resolution\n");
- for (i=0; modes[i].xres != -1; i++)
+static int clgen_decode_var (const struct fb_var_screeninfo *var, void *par,
+ struct fb_info_gen *info)
+{
+ long freq;
+ long maxclock;
+ int xres, hfront, hsync, hback;
+ int yres, vfront, vsync, vback;
+ int nom, den; /* translyting from pixels->bytes */
+ int i;
+ static struct {
+ int xres, yres;
+ } modes[] = { {
+ 1600, 1280
+ }, {
+ 1280, 1024
+ }, {
+ 1024, 768
+ },
{
- if (modes[i].xres*nom/den * modes[i].yres < fb_info->size/2)
+ 800, 600
+ }, {
+ 640, 480
+ }, {
+ -1, -1
+ }
+ };
+
+ struct clgenfb_par *_par = (struct clgenfb_par *) par;
+ struct clgenfb_info *fb_info = (struct clgenfb_info *) info;
+
+ assert (var != NULL);
+ assert (par != NULL);
+ assert (info != NULL);
+
+ DPRINTK ("ENTER\n");
+
+ DPRINTK ("Requested: %dx%dx%d\n", var->xres, var->yres, var->bits_per_pixel);
+ DPRINTK (" virtual: %dx%d\n", var->xres_virtual, var->yres_virtual);
+ DPRINTK (" offset: (%d,%d)\n", var->xoffset, var->yoffset);
+ DPRINTK ("grayscale: %d\n", var->grayscale);
+
+ memset (par, 0, sizeof (struct clgenfb_par));
+
+ _par->var = *var;
+
+ switch (var->bits_per_pixel) {
+ case 1:
+ nom = 4;
+ den = 8;
+ break; /* 8 pixel per byte, only 1/4th of mem usable */
+ case 2 ... 8:
+ _par->var.bits_per_pixel = 8;
+ nom = 1;
+ den = 1;
+ break; /* 1 pixel == 1 byte */
+ case 9 ... 16:
+ _par->var.bits_per_pixel = 16;
+ nom = 2;
+ den = 1;
+ break; /* 2 bytes per pixel */
+ case 17 ... 24:
+ _par->var.bits_per_pixel = 24;
+ nom = 3;
+ den = 1;
+ break; /* 3 bytes per pixel */
+ case 25 ... 32:
+ _par->var.bits_per_pixel = 32;
+ nom = 4;
+ den = 1;
+ break; /* 4 bytes per pixel */
+ default:
+ printk ("clgen: mode %dx%dx%d rejected...color depth not supported.\n",
+ var->xres, var->yres, var->bits_per_pixel);
+ DPRINTK ("EXIT - EINVAL error\n");
+ return -EINVAL;
+ }
+
+ if (_par->var.xres * nom / den * _par->var.yres > fb_info->size) {
+ printk ("clgen: mode %dx%dx%d rejected...resolution too high to fit into video memory!\n",
+ var->xres, var->yres, var->bits_per_pixel);
+ DPRINTK ("EXIT - EINVAL error\n");
+ return -EINVAL;
+ }
+ /* use highest possible virtual resolution */
+ if (_par->var.xres_virtual == -1 &&
+ _par->var.yres_virtual == -1) {
+ printk ("clgen: using maximum available virtual resolution\n");
+ for (i = 0; modes[i].xres != -1; i++) {
+ if (modes[i].xres * nom / den * modes[i].yres < fb_info->size / 2)
+ break;
+ }
+ if (modes[i].xres == -1) {
+ printk ("clgen: could not find a virtual resolution that fits into video memory!!\n");
+ DPRINTK ("EXIT - EINVAL error\n");
+ return -EINVAL;
+ }
+ _par->var.xres_virtual = modes[i].xres;
+ _par->var.yres_virtual = modes[i].yres;
+
+ printk ("clgen: virtual resolution set to maximum of %dx%d\n",
+ _par->var.xres_virtual, _par->var.yres_virtual);
+ } else if (_par->var.xres_virtual == -1) {
+ /* FIXME: maximize X virtual resolution only */
+ } else if (_par->var.yres_virtual == -1) {
+ /* FIXME: maximize Y virtual resolution only */
+ }
+ if (_par->var.xoffset < 0)
+ _par->var.xoffset = 0;
+ if (_par->var.yoffset < 0)
+ _par->var.yoffset = 0;
+
+ /* truncate xoffset and yoffset to maximum if too high */
+ if (_par->var.xoffset > _par->var.xres_virtual - _par->var.xres)
+ _par->var.xoffset = _par->var.xres_virtual - _par->var.xres - 1;
+
+ if (_par->var.yoffset > _par->var.yres_virtual - _par->var.yres)
+ _par->var.yoffset = _par->var.yres_virtual - _par->var.yres - 1;
+
+ switch (_par->var.bits_per_pixel) {
+ case 1:
+ _par->line_length = _par->var.xres_virtual / 8;
+ _par->visual = FB_VISUAL_MONO10;
+ break;
+
+ case 8:
+ _par->line_length = _par->var.xres_virtual;
+ _par->visual = FB_VISUAL_PSEUDOCOLOR;
+ _par->var.red.offset = 0;
+ _par->var.red.length = 6;
+ _par->var.green.offset = 0;
+ _par->var.green.length = 6;
+ _par->var.blue.offset = 0;
+ _par->var.blue.length = 6;
+ break;
+
+ case 16:
+ _par->line_length = _par->var.xres_virtual * 2;
+ _par->visual = FB_VISUAL_DIRECTCOLOR;
+#ifdef CONFIG_PREP
+ _par->var.red.offset = 2;
+ _par->var.green.offset = -3;
+ _par->var.blue.offset = 8;
+#else
+ _par->var.red.offset = 10;
+ _par->var.green.offset = 5;
+ _par->var.blue.offset = 0;
+#endif
+ _par->var.red.length = 5;
+ _par->var.green.length = 5;
+ _par->var.blue.length = 5;
+ break;
+
+ case 24:
+ _par->line_length = _par->var.xres_virtual * 3;
+ _par->visual = FB_VISUAL_DIRECTCOLOR;
+#ifdef CONFIG_PREP
+ _par->var.red.offset = 8;
+ _par->var.green.offset = 16;
+ _par->var.blue.offset = 24;
+#else
+ _par->var.red.offset = 16;
+ _par->var.green.offset = 8;
+ _par->var.blue.offset = 0;
+#endif
+ _par->var.red.length = 8;
+ _par->var.green.length = 8;
+ _par->var.blue.length = 8;
+ break;
+
+ case 32:
+ _par->line_length = _par->var.xres_virtual * 4;
+ _par->visual = FB_VISUAL_DIRECTCOLOR;
+#ifdef CONFIG_PREP
+ _par->var.red.offset = 8;
+ _par->var.green.offset = 16;
+ _par->var.blue.offset = 24;
+#else
+ _par->var.red.offset = 16;
+ _par->var.green.offset = 8;
+ _par->var.blue.offset = 0;
+#endif
+ _par->var.red.length = 8;
+ _par->var.green.length = 8;
+ _par->var.blue.length = 8;
+ break;
+
+ default:
+ DPRINTK("Unsupported bpp size: %d\n", _par->var.bits_per_pixel);
+ assert (FALSE);
+ /* should never occur */
break;
}
- if (modes[i].xres == -1)
- {
- printk("clgen: could not find a virtual resolution that fits into video memory!!\n");
- return -EINVAL;
- }
- _par->var.xres_virtual = modes[i].xres;
- _par->var.yres_virtual = modes[i].yres;
-
- printk("clgen: virtual resolution set to maximum of %dx%d\n",
- _par->var.xres_virtual, _par->var.yres_virtual);
- }
- else if (_par->var.xres_virtual == -1)
- {
- }
- else if (_par->var.yres_virtual == -1)
- {
- }
-
- if (_par->var.xoffset < 0) _par->var.xoffset = 0;
- if (_par->var.yoffset < 0) _par->var.yoffset = 0;
-
- /* truncate xoffset and yoffset to maximum if too high */
- if (_par->var.xoffset > _par->var.xres_virtual-_par->var.xres)
- _par->var.xoffset = _par->var.xres_virtual-_par->var.xres -1;
-
- if (_par->var.yoffset > _par->var.yres_virtual-_par->var.yres)
- _par->var.yoffset = _par->var.yres_virtual-_par->var.yres -1;
-
- switch (var->bits_per_pixel)
- {
- case 1:
- _par->line_length = _par->var.xres_virtual / 8;
- _par->visual = FB_VISUAL_MONO10;
- break;
-
- case 8:
- _par->line_length = _par->var.xres_virtual;
- _par->visual = FB_VISUAL_PSEUDOCOLOR;
- _par->var.red.offset = 0;
- _par->var.red.length = 6;
- _par->var.green.offset = 0;
- _par->var.green.length = 6;
- _par->var.blue.offset = 0;
- _par->var.blue.length = 6;
- break;
-
- case 16:
- _par->line_length = _par->var.xres_virtual * 2;
- _par->visual = FB_VISUAL_DIRECTCOLOR;
- _par->var.red.offset = 10;
- _par->var.red.length = 5;
- _par->var.green.offset = 5;
- _par->var.green.length = 5;
- _par->var.blue.offset = 0;
- _par->var.blue.length = 5;
- break;
-
- case 24:
- _par->line_length = _par->var.xres_virtual * 3;
- _par->visual = FB_VISUAL_DIRECTCOLOR;
- _par->var.red.offset = 16;
- _par->var.red.length = 8;
- _par->var.green.offset = 8;
- _par->var.green.length = 8;
- _par->var.blue.offset = 0;
- _par->var.blue.length = 8;
- break;
-
- case 32:
- _par->line_length = _par->var.xres_virtual * 4;
- _par->visual = FB_VISUAL_DIRECTCOLOR;
- _par->var.red.offset = 16;
- _par->var.red.length = 8;
- _par->var.green.offset = 8;
- _par->var.green.length = 8;
- _par->var.blue.offset = 0;
- _par->var.blue.length = 8;
- break;
- }
- _par->var.red.msb_right = 0;
- _par->var.green.msb_right = 0;
- _par->var.blue.msb_right = 0;
- _par->var.transp.offset = 0;
- _par->var.transp.length = 0;
- _par->var.transp.msb_right = 0;
-
- _par->type = FB_TYPE_PACKED_PIXELS;
-
- /* convert from ps to kHz */
- freq = 1000000000 / var->pixclock;
-
- DEBUG printk("desired pixclock: %ld kHz\n", freq);
-
- /* the SD64/P4 have a higher max. videoclock */
- bestclock(freq, &_par->freq, &_par->nom, &_par->den, &_par->div,
- fb_info->btype == BT_SD64 || fb_info->btype == BT_PICASSO4
- ? 140000 : 90000);
-
- DEBUG printk("Best possible values for given frequency: best: %ld kHz nom: %ld den: %ld div: %ld\n",
- _par->freq, _par->nom, _par->den, _par->div);
-
- xres = _par->var.xres;
- hfront = _par->var.right_margin;
- hsync = _par->var.hsync_len;
- hback = _par->var.left_margin;
-
- yres = _par->var.yres;
- vfront = _par->var.lower_margin;
- vsync = _par->var.vsync_len;
- vback = _par->var.upper_margin;
-
- if (_par->var.vmode & FB_VMODE_DOUBLE)
- {
- yres *= 2;
- vfront *= 2;
- vsync *= 2;
- vback *= 2;
- }
- else if (_par->var.vmode & FB_VMODE_INTERLACED)
- {
- yres = ++yres / 2;
- vfront = ++vfront / 2;
- vsync = ++vsync / 2;
- vback = ++vback / 2;
- }
-
- _par->HorizRes = xres;
- _par->HorizTotal = (xres + hfront + hsync + hback)/8 - 5;
- _par->HorizDispEnd = xres/8 - 1;
- _par->HorizBlankStart = xres/8;
- _par->HorizBlankEnd = _par->HorizTotal+5; /* does not count with "-5" */
- _par->HorizSyncStart = (xres + hfront)/8 + 1;
- _par->HorizSyncEnd = (xres + hfront + hsync)/8 + 1;
-
- _par->VertRes = yres;
- _par->VertTotal = yres + vfront + vsync + vback -2;
- _par->VertDispEnd = yres - 1;
- _par->VertBlankStart = yres;
- _par->VertBlankEnd = _par->VertTotal;
- _par->VertSyncStart = yres + vfront - 1;
- _par->VertSyncEnd = yres + vfront + vsync - 1;
-
- if (_par->VertTotal >= 1024)
- {
- printk(KERN_WARNING "clgen: ERROR: VerticalTotal >= 1024; special treatment required! (TODO)\n");
- return -EINVAL;
- }
- return 0;
+ _par->var.red.msb_right =
+ _par->var.green.msb_right =
+ _par->var.blue.msb_right =
+ _par->var.transp.offset =
+ _par->var.transp.length =
+ _par->var.transp.msb_right = 0;
+
+ _par->type = FB_TYPE_PACKED_PIXELS;
+
+ /* convert from ps to kHz */
+ freq = 1000000000 / var->pixclock;
+
+ DPRINTK ("desired pixclock: %ld kHz\n", freq);
+
+ maxclock = clgen_board_info[fb_info->btype].maxclock;
+ _par->multiplexing = 0;
+
+ /* If the frequency is greater than we can support, we might be able
+ * to use multiplexing for the video mode */
+ if (freq > maxclock) {
+ switch (fb_info->btype) {
+ case BT_ALPINE:
+ case BT_GD5480:
+ _par->multiplexing = 1;
+ break;
+
+ default:
+ printk (KERN_WARNING "clgen: ERROR: Frequency greater than maxclock (%ld kHz)\n", maxclock);
+ DPRINTK ("EXIT - return -EINVAL\n");
+ return -EINVAL;
+ }
+ }
+#if 0
+ /* TODO: If we have a 1MB 5434, we need to put ourselves in a mode where
+ * the VCLK is double the pixel clock. */
+ switch (var->bits_per_pixel) {
+ case 16:
+ case 32:
+ if (_par->HorizRes <= 800)
+ freq /= 2; /* Xbh has this type of clock for 32-bit */
+ break;
+ }
+#endif
+
+ bestclock (freq, &_par->freq, &_par->nom, &_par->den, &_par->div,
+ maxclock);
+ _par->mclk = clgen_get_mclk (freq, _par->var.bits_per_pixel, &_par->divMCLK);
+
+ xres = _par->var.xres;
+ hfront = _par->var.right_margin;
+ hsync = _par->var.hsync_len;
+ hback = _par->var.left_margin;
+
+ yres = _par->var.yres;
+ vfront = _par->var.lower_margin;
+ vsync = _par->var.vsync_len;
+ vback = _par->var.upper_margin;
+
+ if (_par->var.vmode & FB_VMODE_DOUBLE) {
+ yres *= 2;
+ vfront *= 2;
+ vsync *= 2;
+ vback *= 2;
+ } else if (_par->var.vmode & FB_VMODE_INTERLACED) {
+ yres = ++yres / 2;
+ vfront = ++vfront / 2;
+ vsync = ++vsync / 2;
+ vback = ++vback / 2;
+ }
+ _par->HorizRes = xres;
+ _par->HorizTotal = (xres + hfront + hsync + hback) / 8 - 5;
+ _par->HorizDispEnd = xres / 8 - 1;
+ _par->HorizBlankStart = xres / 8;
+ _par->HorizBlankEnd = _par->HorizTotal + 5; /* does not count with "-5" */
+ _par->HorizSyncStart = (xres + hfront) / 8 + 1;
+ _par->HorizSyncEnd = (xres + hfront + hsync) / 8 + 1;
+
+ _par->VertRes = yres;
+ _par->VertTotal = yres + vfront + vsync + vback - 2;
+ _par->VertDispEnd = yres - 1;
+ _par->VertBlankStart = yres;
+ _par->VertBlankEnd = _par->VertTotal;
+ _par->VertSyncStart = yres + vfront - 1;
+ _par->VertSyncEnd = yres + vfront + vsync - 1;
+
+ if (_par->VertRes >= 1024) {
+ _par->VertTotal /= 2;
+ _par->VertSyncStart /= 2;
+ _par->VertSyncEnd /= 2;
+ _par->VertDispEnd /= 2;
+ }
+ if (_par->multiplexing) {
+ _par->HorizTotal /= 2;
+ _par->HorizSyncStart /= 2;
+ _par->HorizSyncEnd /= 2;
+ _par->HorizDispEnd /= 2;
+ }
+ if (_par->VertRes >= 1280) {
+ printk (KERN_WARNING "clgen: ERROR: VerticalTotal >= 1280; special treatment required! (TODO)\n");
+ DPRINTK ("EXIT - EINVAL error\n");
+ return -EINVAL;
+ }
+ DPRINTK ("EXIT\n");
+ return 0;
}
-static int clgen_encode_var(struct fb_var_screeninfo *var, const void *par,
- struct fb_info_gen *info)
+static int clgen_encode_var (struct fb_var_screeninfo *var, const void *par,
+ struct fb_info_gen *info)
{
- *var = ((struct clgenfb_par*)par)->var;
- return 0;
+ DPRINTK ("ENTER\n");
+
+ *var = ((struct clgenfb_par *) par)->var;
+
+ DPRINTK ("EXIT\n");
+ return 0;
}
/* get current video mode */
-static void clgen_get_par(void *par, struct fb_info_gen *info)
+static void clgen_get_par (void *par, struct fb_info_gen *info)
{
- struct clgenfb_par *_par = (struct clgenfb_par*)par;
- struct clgenfb_info*_info = (struct clgenfb_info*)fb_info;
+ struct clgenfb_par *_par = (struct clgenfb_par *) par;
+ struct clgenfb_info *_info = (struct clgenfb_info *) info;
+
+ DPRINTK ("ENTER\n");
- *_par = _info->currentmode;
+ *_par = _info->currentmode;
+
+ DPRINTK ("EXIT\n");
+}
+
+static void clgen_set_mclk (const struct clgenfb_info *fb_info, int val, int div)
+{
+ assert (fb_info != NULL);
+
+ if (div == 2) {
+ /* VCLK = MCLK/2 */
+ unsigned char old = vga_rseq (fb_info->regs, CL_SEQR1E);
+ vga_wseq (fb_info->regs, CL_SEQR1E, old | 0x1);
+ vga_wseq (fb_info->regs, CL_SEQR1F, 0x40 | (val & 0x3f));
+ } else if (div == 1) {
+ /* VCLK = MCLK */
+ unsigned char old = vga_rseq (fb_info->regs, CL_SEQR1E);
+ vga_wseq (fb_info->regs, CL_SEQR1E, old & ~0x1);
+ vga_wseq (fb_info->regs, CL_SEQR1F, 0x40 | (val & 0x3f));
+ } else {
+ vga_wseq (fb_info->regs, CL_SEQR1F, val & 0x3f);
+ }
}
/*************************************************************************
@@ -595,1340 +1158,2081 @@ static void clgen_get_par(void *par, struct fb_info_gen *info)
actually writes the values for a new video mode into the hardware,
**************************************************************************/
-static void clgen_set_par(const void *par, struct fb_info_gen *info)
+static void clgen_set_par (const void *par, struct fb_info_gen *info)
{
- unsigned char tmp;
- int offset = 0;
- struct clgenfb_par *_par = (struct clgenfb_par*)par;
-
- printk(KERN_INFO">clgen_set_par()\n");
- printk(KERN_INFO"Requested mode: %dx%dx%d\n",
- _par->var.xres, _par->var.yres, _par->var.bits_per_pixel);
- printk(KERN_INFO"pixclock: %d\n", _par->var.pixclock);
-
- fb_info = (struct clgenfb_info *)info;
-
- /* unlock register CRT0..CRT7 */
- WCrt(CRT11, 0x20); /* previously: 0x00) */
-
- /* if DEBUG is set, all parameters get output before writing */
- DEBUG printk("CRT0: %ld\n", _par->HorizTotal);
- WCrt(CRT0, _par->HorizTotal);
-
- DEBUG printk("CRT1: %ld\n", _par->HorizDispEnd);
- WCrt(CRT1, _par->HorizDispEnd);
-
- DEBUG printk("CRT2: %ld\n", _par->HorizBlankStart);
- WCrt(CRT2, _par->HorizBlankStart);
-
- DEBUG printk("CRT3: 128+%ld\n", _par->HorizBlankEnd % 32); /* + 128: Compatible read */
- WCrt(CRT3, 128 + (_par->HorizBlankEnd % 32));
-
- DEBUG printk("CRT4: %ld\n", _par->HorizSyncStart);
- WCrt(CRT4, _par->HorizSyncStart);
-
- tmp = _par->HorizSyncEnd % 32;
- if (_par->HorizBlankEnd & 32)
- tmp += 128;
- DEBUG printk("CRT5: %d\n", tmp);
- WCrt(CRT5, tmp);
-
- DEBUG printk("CRT6: %ld\n", _par->VertTotal & 0xff);
- WCrt(CRT6, (_par->VertTotal & 0xff));
-
- tmp = 16; /* LineCompare bit #9 */
- if (_par->VertTotal & 256) tmp |= 1;
- if (_par->VertDispEnd & 256) tmp |= 2;
- if (_par->VertSyncStart & 256) tmp |= 4;
- if (_par->VertBlankStart & 256) tmp |= 8;
- if (_par->VertTotal & 512) tmp |= 32;
- if (_par->VertDispEnd & 512) tmp |= 64;
- if (_par->VertSyncStart & 512) tmp |= 128;
- DEBUG printk("CRT7: %d\n", tmp);
- WCrt(CRT7, tmp);
-
- tmp = 0x40; /* LineCompare bit #8 */
- if (_par->VertBlankStart & 512) tmp |= 0x20;
- if (_par->var.vmode & FB_VMODE_DOUBLE) tmp |= 0x80;
- DEBUG printk("CRT9: %d\n", tmp);
- WCrt(CRT9, tmp);
-
- DEBUG printk("CRT10: %ld\n", _par->VertSyncStart & 0xff);
- WCrt(CRT10, (_par->VertSyncStart & 0xff));
-
- DEBUG printk("CRT11: 64+32+%ld\n", _par->VertSyncEnd % 16);
- WCrt(CRT11, (_par->VertSyncEnd % 16 + 64 + 32));
-
- DEBUG printk("CRT12: %ld\n", _par->VertDispEnd & 0xff);
- WCrt(CRT12, (_par->VertDispEnd & 0xff));
-
- DEBUG printk("CRT15: %ld\n", _par->VertBlankStart & 0xff);
- WCrt(CRT15, (_par->VertBlankStart & 0xff));
-
- DEBUG printk("CRT16: %ld\n", _par->VertBlankEnd & 0xff);
- WCrt(CRT16, (_par->VertBlankEnd & 0xff));
-
- DEBUG printk("CRT18: 0xff\n");
- WCrt(CRT18, 0xff);
-
- tmp = 0;
- if (_par->var.vmode & FB_VMODE_INTERLACED) tmp |= 1;
- if (_par->HorizBlankEnd & 64) tmp |= 16;
- if (_par->HorizBlankEnd & 128) tmp |= 32;
- if (_par->VertBlankEnd & 256) tmp |= 64;
- if (_par->VertBlankEnd & 512) tmp |= 128;
-
- DEBUG printk("CRT1a: %d\n", tmp);
- WCrt(CRT1A, tmp);
-
- /* set VCLK0 */
- /* hardware RefClock: 14.31818 MHz */
- /* formula: VClk = (OSC * N) / (D * (1+P)) */
- /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
-
- WSeq(SEQRB, _par->nom);
- tmp = _par->den<<1;
- if (_par->div != 0) tmp |= 1;
-
- if (fb_info->btype == BT_SD64)
- tmp |= 0x80; /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
-
- WSeq(SEQR1B, tmp);
-
- WCrt(CRT17, 0xc3); /* mode control: CRTC enable, ROTATE(?), 16bit address wrap, no compat. */
-
-/* HAEH? WCrt(CRT11, 0x20); * previously: 0x00 unlock CRT0..CRT7 */
-
- /* don't know if it would hurt to also program this if no interlaced */
- /* mode is used, but I feel better this way.. :-) */
- if (_par->var.vmode & FB_VMODE_INTERLACED)
- WCrt(CRT19, _par->HorizTotal / 2);
- else
- WCrt(CRT19, 0x00); /* interlace control */
-
- WSeq(SEQR3, 0);
-
- /* adjust horizontal/vertical sync type (low/high) */
- tmp = 0x03; /* enable display memory & CRTC I/O address for color mode */
- if (_par->var.sync & FB_SYNC_HOR_HIGH_ACT) tmp |= 0x40;
- if (_par->var.sync & FB_SYNC_VERT_HIGH_ACT) tmp |= 0x80;
- WGen(MISC_W, tmp);
-
- WCrt(CRT8, 0); /* Screen A Preset Row-Scan register */
- WCrt(CRTA, 0); /* text cursor on and start line */
- WCrt(CRTB, 31); /* text cursor end line */
-
- /* programming for different color depths */
- if (_par->var.bits_per_pixel == 1)
- {
- DEBUG printk(KERN_INFO "clgen: preparing for 1 bit deep display\n");
-#if 0
- /* restore first 2 color registers for mono mode */
- WClut( 0, 0x00, 0x00, 0x00); /* background: black */
- WClut( 1, 0x3f, 0x3f, 0x3f); /* foreground: white */
-#endif
- WGfx(GR5, 0); /* mode register */
-
- /* Extended Sequencer Mode */
- switch(fb_info->btype)
- {
- case BT_SD64:
- /* setting the SEQRF on SD64 is not necessary (only during init) */
- DEBUG printk(KERN_INFO "(for SD64)\n");
- WSeq(SEQR7, 0xf0);
- WSeq(SEQR1F, 0x1a); /* MCLK select */
- break;
+ unsigned char tmp;
+ int offset = 0;
+ struct clgenfb_par *_par = (struct clgenfb_par *) par;
+ struct clgenfb_info *fb_info = (struct clgenfb_info *) info;
+ const struct clgen_board_info_rec *bi;
+
+ DPRINTK ("ENTER\n");
+ DPRINTK ("Requested mode: %dx%dx%d\n",
+ _par->var.xres, _par->var.yres, _par->var.bits_per_pixel);
+ DPRINTK ("pixclock: %d\n", _par->var.pixclock);
+
+ bi = &clgen_board_info[fb_info->btype];
+
+
+ /* unlock register VGA_CRTC_H_TOTAL..CRT7 */
+ vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */
+
+ /* if debugging is enabled, all parameters get output before writing */
+ DPRINTK ("CRT0: %ld\n", _par->HorizTotal);
+ vga_wcrt (fb_info->regs, VGA_CRTC_H_TOTAL, _par->HorizTotal);
+
+ DPRINTK ("CRT1: %ld\n", _par->HorizDispEnd);
+ vga_wcrt (fb_info->regs, VGA_CRTC_H_DISP, _par->HorizDispEnd);
+
+ DPRINTK ("CRT2: %ld\n", _par->HorizBlankStart);
+ vga_wcrt (fb_info->regs, VGA_CRTC_H_BLANK_START, _par->HorizBlankStart);
+
+ DPRINTK ("CRT3: 128+%ld\n", _par->HorizBlankEnd % 32); /* + 128: Compatible read */
+ vga_wcrt (fb_info->regs, VGA_CRTC_H_BLANK_END, 128 + (_par->HorizBlankEnd % 32));
+
+ DPRINTK ("CRT4: %ld\n", _par->HorizSyncStart);
+ vga_wcrt (fb_info->regs, VGA_CRTC_H_SYNC_START, _par->HorizSyncStart);
+
+ tmp = _par->HorizSyncEnd % 32;
+ if (_par->HorizBlankEnd & 32)
+ tmp += 128;
+ DPRINTK ("CRT5: %d\n", tmp);
+ vga_wcrt (fb_info->regs, VGA_CRTC_H_SYNC_END, tmp);
+
+ DPRINTK ("CRT6: %ld\n", _par->VertTotal & 0xff);
+ vga_wcrt (fb_info->regs, VGA_CRTC_V_TOTAL, (_par->VertTotal & 0xff));
+
+ tmp = 16; /* LineCompare bit #9 */
+ if (_par->VertTotal & 256)
+ tmp |= 1;
+ if (_par->VertDispEnd & 256)
+ tmp |= 2;
+ if (_par->VertSyncStart & 256)
+ tmp |= 4;
+ if (_par->VertBlankStart & 256)
+ tmp |= 8;
+ if (_par->VertTotal & 512)
+ tmp |= 32;
+ if (_par->VertDispEnd & 512)
+ tmp |= 64;
+ if (_par->VertSyncStart & 512)
+ tmp |= 128;
+ DPRINTK ("CRT7: %d\n", tmp);
+ vga_wcrt (fb_info->regs, VGA_CRTC_OVERFLOW, tmp);
+
+ tmp = 0x40; /* LineCompare bit #8 */
+ if (_par->VertBlankStart & 512)
+ tmp |= 0x20;
+ if (_par->var.vmode & FB_VMODE_DOUBLE)
+ tmp |= 0x80;
+ DPRINTK ("CRT9: %d\n", tmp);
+ vga_wcrt (fb_info->regs, VGA_CRTC_MAX_SCAN, tmp);
+
+ DPRINTK ("CRT10: %ld\n", _par->VertSyncStart & 0xff);
+ vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_START, (_par->VertSyncStart & 0xff));
+
+ DPRINTK ("CRT11: 64+32+%ld\n", _par->VertSyncEnd % 16);
+ vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_END, (_par->VertSyncEnd % 16 + 64 + 32));
+
+ DPRINTK ("CRT12: %ld\n", _par->VertDispEnd & 0xff);
+ vga_wcrt (fb_info->regs, VGA_CRTC_V_DISP_END, (_par->VertDispEnd & 0xff));
+
+ DPRINTK ("CRT15: %ld\n", _par->VertBlankStart & 0xff);
+ vga_wcrt (fb_info->regs, VGA_CRTC_V_BLANK_START, (_par->VertBlankStart & 0xff));
+
+ DPRINTK ("CRT16: %ld\n", _par->VertBlankEnd & 0xff);
+ vga_wcrt (fb_info->regs, VGA_CRTC_V_BLANK_END, (_par->VertBlankEnd & 0xff));
+
+ DPRINTK ("CRT18: 0xff\n");
+ vga_wcrt (fb_info->regs, VGA_CRTC_LINE_COMPARE, 0xff);
+
+ tmp = 0;
+ if (_par->var.vmode & FB_VMODE_INTERLACED)
+ tmp |= 1;
+ if (_par->HorizBlankEnd & 64)
+ tmp |= 16;
+ if (_par->HorizBlankEnd & 128)
+ tmp |= 32;
+ if (_par->VertBlankEnd & 256)
+ tmp |= 64;
+ if (_par->VertBlankEnd & 512)
+ tmp |= 128;
+
+ DPRINTK ("CRT1a: %d\n", tmp);
+ vga_wcrt (fb_info->regs, CL_CRT1A, tmp);
+
+ /* set VCLK0 */
+ /* hardware RefClock: 14.31818 MHz */
+ /* formula: VClk = (OSC * N) / (D * (1+P)) */
+ /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
+
+ vga_wseq (fb_info->regs, CL_SEQRB, _par->nom);
+ tmp = _par->den << 1;
+ if (_par->div != 0)
+ tmp |= 1;
+
+ if ((fb_info->btype == BT_SD64) ||
+ (fb_info->btype == BT_ALPINE) ||
+ (fb_info->btype == BT_GD5480))
+ tmp |= 0x80; /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
+
+ DPRINTK ("CL_SEQR1B: %ld\n", (long) tmp);
+ vga_wseq (fb_info->regs, CL_SEQR1B, tmp);
+
+ if (_par->VertRes >= 1024)
+ /* 1280x1024 */
+ vga_wcrt (fb_info->regs, VGA_CRTC_MODE, 0xc7);
+ else
+ /* mode control: VGA_CRTC_START_HI enable, ROTATE(?), 16bit
+ * address wrap, no compat. */
+ vga_wcrt (fb_info->regs, VGA_CRTC_MODE, 0xc3);
- case BT_PICCOLO:
- DEBUG printk(KERN_INFO "(for Piccolo)\n");
- WSeq(SEQR7, 0x80);
-/* ### ueberall 0x22? */
- WSeq(SEQR1F, 0x22); /* ##vorher 1c MCLK select */
- WSeq(SEQRF, 0xb0); /* evtl d0 bei 1 bit? avoid FIFO underruns..? */
- break;
+/* HAEH? vga_wcrt (fb_info->regs, VGA_CRTC_V_SYNC_END, 0x20); * previously: 0x00 unlock VGA_CRTC_H_TOTAL..CRT7 */
- case BT_PICASSO:
- DEBUG printk(KERN_INFO "(for Picasso)\n");
- WSeq(SEQR7, 0x20);
- WSeq(SEQR1F, 0x22); /* ##vorher 22 MCLK select */
- WSeq(SEQRF, 0xd0); /* ## vorher d0 avoid FIFO underruns..? */
- break;
+ /* don't know if it would hurt to also program this if no interlaced */
+ /* mode is used, but I feel better this way.. :-) */
+ if (_par->var.vmode & FB_VMODE_INTERLACED)
+ vga_wcrt (fb_info->regs, VGA_CRTC_REGS, _par->HorizTotal / 2);
+ else
+ vga_wcrt (fb_info->regs, VGA_CRTC_REGS, 0x00); /* interlace control */
+
+ vga_wseq (fb_info->regs, VGA_SEQ_CHARACTER_MAP, 0);
+
+ /* adjust horizontal/vertical sync type (low/high) */
+ tmp = 0x03; /* enable display memory & CRTC I/O address for color mode */
+ if (_par->var.sync & FB_SYNC_HOR_HIGH_ACT)
+ tmp |= 0x40;
+ if (_par->var.sync & FB_SYNC_VERT_HIGH_ACT)
+ tmp |= 0x80;
+ WGen (fb_info, VGA_MIS_W, tmp);
+
+ vga_wcrt (fb_info->regs, VGA_CRTC_PRESET_ROW, 0); /* Screen A Preset Row-Scan register */
+ vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_START, 0); /* text cursor on and start line */
+ vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_END, 31); /* text cursor end line */
+
+ /******************************************************
+ *
+ * 1 bpp
+ *
+ */
+
+ /* programming for different color depths */
+ if (_par->var.bits_per_pixel == 1) {
+ DPRINTK ("clgen: preparing for 1 bit deep display\n");
+ vga_wgfx (fb_info->regs, VGA_GFX_MODE, 0); /* mode register */
+
+ /* SR07 */
+ switch (fb_info->btype) {
+ case BT_SD64:
+ case BT_PICCOLO:
+ case BT_PICASSO:
+ case BT_SPECTRUM:
+ case BT_PICASSO4:
+ case BT_ALPINE:
+ case BT_GD5480:
+ DPRINTK (" (for GD54xx)\n");
+ vga_wseq (fb_info->regs, CL_SEQR7,
+ _par->multiplexing ?
+ bi->sr07_1bpp_mux : bi->sr07_1bpp);
+ break;
+
+ case BT_LAGUNA:
+ DPRINTK (" (for GD546x)\n");
+ vga_wseq (fb_info->regs, CL_SEQR7,
+ vga_rseq (fb_info->regs, CL_SEQR7) & ~0x01);
+ break;
+
+ default:
+ printk (KERN_WARNING "clgen: unknown Board\n");
+ break;
+ }
- case BT_SPECTRUM:
- DEBUG printk(KERN_INFO "(for Spectrum)\n");
- WSeq(SEQR7, 0x80);
+ /* Extended Sequencer Mode */
+ switch (fb_info->btype) {
+ case BT_SD64:
+ /* setting the SEQRF on SD64 is not necessary (only during init) */
+ DPRINTK ("(for SD64)\n");
+ vga_wseq (fb_info->regs, CL_SEQR1F, 0x1a); /* MCLK select */
+ break;
+
+ case BT_PICCOLO:
+ DPRINTK ("(for Piccolo)\n");
+/* ### ueberall 0x22? */
+ vga_wseq (fb_info->regs, CL_SEQR1F, 0x22); /* ##vorher 1c MCLK select */
+ vga_wseq (fb_info->regs, CL_SEQRF, 0xb0); /* evtl d0 bei 1 bit? avoid FIFO underruns..? */
+ break;
+
+ case BT_PICASSO:
+ DPRINTK ("(for Picasso)\n");
+ vga_wseq (fb_info->regs, CL_SEQR1F, 0x22); /* ##vorher 22 MCLK select */
+ vga_wseq (fb_info->regs, CL_SEQRF, 0xd0); /* ## vorher d0 avoid FIFO underruns..? */
+ break;
+
+ case BT_SPECTRUM:
+ DPRINTK ("(for Spectrum)\n");
/* ### ueberall 0x22? */
- WSeq(SEQR1F, 0x22); /* ##vorher 1c MCLK select */
- WSeq(SEQRF, 0xb0); /* evtl d0? avoid FIFO underruns..? */
- break;
+ vga_wseq (fb_info->regs, CL_SEQR1F, 0x22); /* ##vorher 1c MCLK select */
+ vga_wseq (fb_info->regs, CL_SEQRF, 0xb0); /* evtl d0? avoid FIFO underruns..? */
+ break;
+
+ case BT_PICASSO4:
+ case BT_ALPINE:
+ case BT_GD5480:
+ case BT_LAGUNA:
+ DPRINTK (" (for GD54xx)\n");
+ /* do nothing */
+ break;
+
+ default:
+ printk (KERN_WARNING "clgen: unknown Board\n");
+ break;
+ }
- case BT_PICASSO4:
- DEBUG printk(KERN_INFO "(for Picasso 4)\n");
- WSeq(SEQR7, 0x20);
-/* WSeq(SEQR1F, 0x1c); */
-/* SEQRF not being set here... WSeq(SEQRF, 0xd0); */
- break;
+ WGen (fb_info, VGA_PEL_MSK, 0x01); /* pixel mask: pass-through for first plane */
+ if (_par->multiplexing)
+ WHDR (fb_info, 0x4a); /* hidden dac reg: 1280x1024 */
+ else
+ WHDR (fb_info, 0); /* hidden dac: nothing */
+ vga_wseq (fb_info->regs, VGA_SEQ_MEMORY_MODE, 0x06); /* memory mode: odd/even, ext. memory */
+ vga_wseq (fb_info->regs, VGA_SEQ_PLANE_WRITE, 0x01); /* plane mask: only write to first plane */
+ offset = _par->var.xres_virtual / 16;
+ }
+
+ /******************************************************
+ *
+ * 8 bpp
+ *
+ */
+
+ else if (_par->var.bits_per_pixel == 8) {
+ DPRINTK ("clgen: preparing for 8 bit deep display\n");
+ switch (fb_info->btype) {
+ case BT_SD64:
+ case BT_PICCOLO:
+ case BT_PICASSO:
+ case BT_SPECTRUM:
+ case BT_PICASSO4:
+ case BT_ALPINE:
+ case BT_GD5480:
+ DPRINTK (" (for GD54xx)\n");
+ vga_wseq (fb_info->regs, CL_SEQR7,
+ _par->multiplexing ?
+ bi->sr07_8bpp_mux : bi->sr07_8bpp);
+ break;
+
+ case BT_LAGUNA:
+ DPRINTK (" (for GD546x)\n");
+ vga_wseq (fb_info->regs, CL_SEQR7,
+ vga_rseq (fb_info->regs, CL_SEQR7) | 0x01);
+ break;
+
+ default:
+ printk (KERN_WARNING "clgen: unknown Board\n");
+ break;
+ }
- default:
- printk(KERN_WARNING "clgen: unknown Board\n");
- break;
- }
-
- WGen(M_3C6,0x01); /* pixel mask: pass-through for first plane */
- WHDR(0); /* hidden dac reg: nothing special */
- WSeq(SEQR4, 0x06); /* memory mode: odd/even, ext. memory */
- WSeq(SEQR2, 0x01); /* plane mask: only write to first plane */
- offset = _par->var.xres_virtual / 16;
- }
- else if (_par->var.bits_per_pixel == 8)
- {
- DEBUG printk(KERN_INFO "clgen: preparing for 8 bit deep display\n");
- switch(fb_info->btype)
- {
- case BT_SD64:
- WSeq(SEQR7, 0xf1); /* Extended Sequencer Mode: 256c col. mode */
- WSeq(SEQR1F, 0x1d); /* MCLK select */
- break;
+ switch (fb_info->btype) {
+ case BT_SD64:
+ vga_wseq (fb_info->regs, CL_SEQR1F, 0x1d); /* MCLK select */
+ break;
+
+ case BT_PICCOLO:
+ vga_wseq (fb_info->regs, CL_SEQR1F, 0x22); /* ### vorher 1c MCLK select */
+ vga_wseq (fb_info->regs, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
+ break;
+
+ case BT_PICASSO:
+ vga_wseq (fb_info->regs, CL_SEQR1F, 0x22); /* ### vorher 1c MCLK select */
+ vga_wseq (fb_info->regs, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
+ break;
+
+ case BT_SPECTRUM:
+ vga_wseq (fb_info->regs, CL_SEQR1F, 0x22); /* ### vorher 1c MCLK select */
+ vga_wseq (fb_info->regs, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
+ break;
+
+ case BT_PICASSO4:
+ vga_wseq (fb_info->regs, CL_SEQRF, 0xb8); /* ### INCOMPLETE!! */
+/* vga_wseq (fb_info->regs, CL_SEQR1F, 0x1c); */
+ break;
+
+ case BT_ALPINE:
+ DPRINTK (" (for GD543x)\n");
+ clgen_set_mclk (fb_info, _par->mclk, _par->divMCLK);
+ /* We already set SRF and SR1F */
+ break;
+
+ case BT_GD5480:
+ case BT_LAGUNA:
+ DPRINTK (" (for GD54xx)\n");
+ /* do nothing */
+ break;
+
+ default:
+ printk (KERN_WARNING "clgen: unknown Board\n");
+ break;
+ }
- case BT_PICCOLO:
- WSeq(SEQR7, 0x81);
- WSeq(SEQR1F, 0x22); /* ### vorher 1c MCLK select */
- WSeq(SEQRF, 0xb0); /* Fast Page-Mode writes */
- break;
+ vga_wgfx (fb_info->regs, VGA_GFX_MODE, 64); /* mode register: 256 color mode */
+ WGen (fb_info, VGA_PEL_MSK, 0xff); /* pixel mask: pass-through all planes */
+ if (_par->multiplexing)
+ WHDR (fb_info, 0x4a); /* hidden dac reg: 1280x1024 */
+ else
+ WHDR (fb_info, 0); /* hidden dac: nothing */
+ vga_wseq (fb_info->regs, VGA_SEQ_MEMORY_MODE, 0x0a); /* memory mode: chain4, ext. memory */
+ vga_wseq (fb_info->regs, VGA_SEQ_PLANE_WRITE, 0xff); /* plane mask: enable writing to all 4 planes */
+ offset = _par->var.xres_virtual / 8;
+ }
+
+ /******************************************************
+ *
+ * 16 bpp
+ *
+ */
+
+ else if (_par->var.bits_per_pixel == 16) {
+ DPRINTK ("clgen: preparing for 16 bit deep display\n");
+ switch (fb_info->btype) {
+ case BT_SD64:
+ vga_wseq (fb_info->regs, CL_SEQR7, 0xf7); /* Extended Sequencer Mode: 256c col. mode */
+ vga_wseq (fb_info->regs, CL_SEQR1F, 0x1e); /* MCLK select */
+ break;
+
+ case BT_PICCOLO:
+ vga_wseq (fb_info->regs, CL_SEQR7, 0x87);
+ vga_wseq (fb_info->regs, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
+ vga_wseq (fb_info->regs, CL_SEQR1F, 0x22); /* MCLK select */
+ break;
+
+ case BT_PICASSO:
+ vga_wseq (fb_info->regs, CL_SEQR7, 0x27);
+ vga_wseq (fb_info->regs, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
+ vga_wseq (fb_info->regs, CL_SEQR1F, 0x22); /* MCLK select */
+ break;
+
+ case BT_SPECTRUM:
+ vga_wseq (fb_info->regs, CL_SEQR7, 0x87);
+ vga_wseq (fb_info->regs, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
+ vga_wseq (fb_info->regs, CL_SEQR1F, 0x22); /* MCLK select */
+ break;
+
+ case BT_PICASSO4:
+ vga_wseq (fb_info->regs, CL_SEQR7, 0x27);
+/* vga_wseq (fb_info->regs, CL_SEQR1F, 0x1c); */
+ break;
+
+ case BT_ALPINE:
+ DPRINTK (" (for GD543x)\n");
+ if (_par->HorizRes >= 1024)
+ vga_wseq (fb_info->regs, CL_SEQR7, 0xa7);
+ else
+ vga_wseq (fb_info->regs, CL_SEQR7, 0xa3);
+ clgen_set_mclk (fb_info, _par->mclk, _par->divMCLK);
+ break;
+
+ case BT_GD5480:
+ DPRINTK (" (for GD5480)\n");
+ vga_wseq (fb_info->regs, CL_SEQR7, 0x17);
+ /* We already set SRF and SR1F */
+ break;
+
+ case BT_LAGUNA:
+ DPRINTK (" (for GD546x)\n");
+ vga_wseq (fb_info->regs, CL_SEQR7,
+ vga_rseq (fb_info->regs, CL_SEQR7) & ~0x01);
+ break;
+
+ default:
+ printk (KERN_WARNING "CLGEN: unknown Board\n");
+ break;
+ }
- case BT_PICASSO:
- WSeq(SEQR7, 0x21);
- WSeq(SEQR1F, 0x22); /* ### vorher 1c MCLK select */
- WSeq(SEQRF, 0xb0); /* Fast Page-Mode writes */
- break;
+ vga_wgfx (fb_info->regs, VGA_GFX_MODE, 64); /* mode register: 256 color mode */
+ WGen (fb_info, VGA_PEL_MSK, 0xff); /* pixel mask: pass-through all planes */
+#ifdef CONFIG_PCI
+ WHDR (fb_info, 0xc0); /* Copy Xbh */
+#elif CONFIG_ZORRO
+ WHDR (fb_info, 0xa0); /* hidden dac reg: nothing special */
+#endif
+ vga_wseq (fb_info->regs, VGA_SEQ_MEMORY_MODE, 0x0a); /* memory mode: chain4, ext. memory */
+ vga_wseq (fb_info->regs, VGA_SEQ_PLANE_WRITE, 0xff); /* plane mask: enable writing to all 4 planes */
+ offset = _par->var.xres_virtual / 4;
+ }
+
+ /******************************************************
+ *
+ * 32 bpp
+ *
+ */
+
+ else if (_par->var.bits_per_pixel == 32) {
+ DPRINTK ("clgen: preparing for 24/32 bit deep display\n");
+ switch (fb_info->btype) {
+ case BT_SD64:
+ vga_wseq (fb_info->regs, CL_SEQR7, 0xf9); /* Extended Sequencer Mode: 256c col. mode */
+ vga_wseq (fb_info->regs, CL_SEQR1F, 0x1e); /* MCLK select */
+ break;
+
+ case BT_PICCOLO:
+ vga_wseq (fb_info->regs, CL_SEQR7, 0x85);
+ vga_wseq (fb_info->regs, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
+ vga_wseq (fb_info->regs, CL_SEQR1F, 0x22); /* MCLK select */
+ break;
+
+ case BT_PICASSO:
+ vga_wseq (fb_info->regs, CL_SEQR7, 0x25);
+ vga_wseq (fb_info->regs, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
+ vga_wseq (fb_info->regs, CL_SEQR1F, 0x22); /* MCLK select */
+ break;
+
+ case BT_SPECTRUM:
+ vga_wseq (fb_info->regs, CL_SEQR7, 0x85);
+ vga_wseq (fb_info->regs, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
+ vga_wseq (fb_info->regs, CL_SEQR1F, 0x22); /* MCLK select */
+ break;
+
+ case BT_PICASSO4:
+ vga_wseq (fb_info->regs, CL_SEQR7, 0x25);
+/* vga_wseq (fb_info->regs, CL_SEQR1F, 0x1c); */
+ break;
+
+ case BT_ALPINE:
+ DPRINTK (" (for GD543x)\n");
+ vga_wseq (fb_info->regs, CL_SEQR7, 0xa9);
+ clgen_set_mclk (fb_info, _par->mclk, _par->divMCLK);
+ break;
+
+ case BT_GD5480:
+ DPRINTK (" (for GD5480)\n");
+ vga_wseq (fb_info->regs, CL_SEQR7, 0x19);
+ /* We already set SRF and SR1F */
+ break;
+
+ case BT_LAGUNA:
+ DPRINTK (" (for GD546x)\n");
+ vga_wseq (fb_info->regs, CL_SEQR7,
+ vga_rseq (fb_info->regs, CL_SEQR7) & ~0x01);
+ break;
+
+ default:
+ printk (KERN_WARNING "clgen: unknown Board\n");
+ break;
+ }
- case BT_SPECTRUM:
- WSeq(SEQR7, 0x81);
- WSeq(SEQR1F, 0x22); /* ### vorher 1c MCLK select */
- WSeq(SEQRF, 0xb0); /* Fast Page-Mode writes */
- break;
+ vga_wgfx (fb_info->regs, VGA_GFX_MODE, 64); /* mode register: 256 color mode */
+ WGen (fb_info, VGA_PEL_MSK, 0xff); /* pixel mask: pass-through all planes */
+ WHDR (fb_info, 0xc5); /* hidden dac reg: 8-8-8 mode (24 or 32) */
+ vga_wseq (fb_info->regs, VGA_SEQ_MEMORY_MODE, 0x0a); /* memory mode: chain4, ext. memory */
+ vga_wseq (fb_info->regs, VGA_SEQ_PLANE_WRITE, 0xff); /* plane mask: enable writing to all 4 planes */
+ offset = _par->var.xres_virtual / 4;
+ }
+
+ /******************************************************
+ *
+ * unknown/unsupported bpp
+ *
+ */
+
+ else {
+ printk (KERN_ERR "clgen: What's this?? requested color depth == %d.\n",
+ _par->var.bits_per_pixel);
+ }
+
+ vga_wcrt (fb_info->regs, VGA_CRTC_OFFSET, offset & 0xff);
+ tmp = 0x22;
+ if (offset & 0x100)
+ tmp |= 0x10; /* offset overflow bit */
+
+ vga_wcrt (fb_info->regs, CL_CRT1B, tmp); /* screen start addr #16-18, fastpagemode cycles */
+
+ if (fb_info->btype == BT_SD64 ||
+ fb_info->btype == BT_PICASSO4 ||
+ fb_info->btype == BT_ALPINE ||
+ fb_info->btype == BT_GD5480)
+ vga_wcrt (fb_info->regs, CL_CRT1D, 0x00); /* screen start address bit 19 */
+
+ vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_HI, 0); /* text cursor location high */
+ vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_LO, 0); /* text cursor location low */
+ vga_wcrt (fb_info->regs, VGA_CRTC_UNDERLINE, 0); /* underline row scanline = at very bottom */
+
+ vga_wattr (fb_info->regs, VGA_ATC_MODE, 1); /* controller mode */
+ vga_wattr (fb_info->regs, VGA_ATC_OVERSCAN, 0); /* overscan (border) color */
+ vga_wattr (fb_info->regs, VGA_ATC_PLANE_ENABLE, 15); /* color plane enable */
+ vga_wattr (fb_info->regs, CL_AR33, 0); /* pixel panning */
+ vga_wattr (fb_info->regs, VGA_ATC_COLOR_PAGE, 0); /* color select */
+
+ /* [ EGS: SetOffset(); ] */
+ /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */
+ AttrOn (fb_info);
+
+ vga_wgfx (fb_info->regs, VGA_GFX_SR_VALUE, 0); /* set/reset register */
+ vga_wgfx (fb_info->regs, VGA_GFX_SR_ENABLE, 0); /* set/reset enable */
+ vga_wgfx (fb_info->regs, VGA_GFX_COMPARE_VALUE, 0); /* color compare */
+ vga_wgfx (fb_info->regs, VGA_GFX_DATA_ROTATE, 0); /* data rotate */
+ vga_wgfx (fb_info->regs, VGA_GFX_PLANE_READ, 0); /* read map select */
+ vga_wgfx (fb_info->regs, VGA_GFX_MISC, 1); /* miscellaneous register */
+ vga_wgfx (fb_info->regs, VGA_GFX_COMPARE_MASK, 15); /* color don't care */
+ vga_wgfx (fb_info->regs, VGA_GFX_BIT_MASK, 255); /* bit mask */
+
+ vga_wseq (fb_info->regs, CL_SEQR12, 0x0); /* graphics cursor attributes: nothing special */
+
+ /* finally, turn on everything - turn off "FullBandwidth" bit */
+ /* also, set "DotClock%2" bit where requested */
+ tmp = 0x01;
- case BT_PICASSO4:
- WSeq(SEQR7, 0x21);
- WSeq(SEQRF, 0xb8); /* ### INCOMPLETE!! */
-/* WSeq(SEQR1F, 0x1c); */
- break;
+/*** FB_VMODE_CLOCK_HALVE in linux/fb.h not defined anymore ?
+ if (var->vmode & FB_VMODE_CLOCK_HALVE)
+ tmp |= 0x08;
+*/
- default:
- printk(KERN_WARNING "clgen: unknown Board\n");
- break;
- }
-
- WGfx(GR5, 64); /* mode register: 256 color mode */
- WGen(M_3C6,0xff); /* pixel mask: pass-through all planes */
- WHDR(0); /* hidden dac reg: nothing special */
- WSeq(SEQR4, 0x0a); /* memory mode: chain4, ext. memory */
- WSeq(SEQR2, 0xff); /* plane mask: enable writing to all 4 planes */
- offset = _par->var.xres_virtual / 8;
- }
- else if (_par->var.bits_per_pixel == 16)
- {
- DEBUG printk(KERN_INFO "clgen: preparing for 16 bit deep display\n");
- switch(fb_info->btype)
- {
- case BT_SD64:
- WSeq(SEQR7, 0xf7); /* Extended Sequencer Mode: 256c col. mode */
- WSeq(SEQR1F, 0x1e); /* MCLK select */
- break;
+ vga_wseq (fb_info->regs, VGA_SEQ_CLOCK_MODE, tmp);
+ DPRINTK ("CL_SEQR1: %d\n", tmp);
- case BT_PICCOLO:
- WSeq(SEQR7, 0x87);
- WSeq(SEQRF, 0xb0); /* Fast Page-Mode writes */
- WSeq(SEQR1F, 0x22); /* MCLK select */
- break;
+ fb_info->currentmode = *_par;
- case BT_PICASSO:
- WSeq(SEQR7, 0x27);
- WSeq(SEQRF, 0xb0); /* Fast Page-Mode writes */
- WSeq(SEQR1F, 0x22); /* MCLK select */
- break;
+ DPRINTK ("virtual offset: (%d,%d)\n", _par->var.xoffset, _par->var.yoffset);
+ /* pan to requested offset */
+ clgen_pan_display (&fb_info->currentmode.var, (struct fb_info_gen *) fb_info);
- case BT_SPECTRUM:
- WSeq(SEQR7, 0x87);
- WSeq(SEQRF, 0xb0); /* Fast Page-Mode writes */
- WSeq(SEQR1F, 0x22); /* MCLK select */
- break;
+#ifdef CLGEN_DEBUG
+ clgen_dump ();
+#endif
- case BT_PICASSO4:
- WSeq(SEQR7, 0x27);
-/* WSeq(SEQR1F, 0x1c); */
- break;
+ DPRINTK ("EXIT\n");
+ return;
+}
- default:
- printk(KERN_WARNING "CLGEN: unknown Board\n");
- break;
- }
-
- WGfx(GR5, 64); /* mode register: 256 color mode */
- WGen(M_3C6,0xff); /* pixel mask: pass-through all planes */
- WHDR(0xa0); /* hidden dac reg: nothing special */
- WSeq(SEQR4, 0x0a); /* memory mode: chain4, ext. memory */
- WSeq(SEQR2, 0xff); /* plane mask: enable writing to all 4 planes */
- offset = _par->var.xres_virtual / 4;
- }
- else if (_par->var.bits_per_pixel == 32)
- {
- DEBUG printk(KERN_INFO "clgen: preparing for 24/32 bit deep display\n");
- switch(fb_info->btype)
- {
- case BT_SD64:
- WSeq(SEQR7, 0xf9); /* Extended Sequencer Mode: 256c col. mode */
- WSeq(SEQR1F, 0x1e); /* MCLK select */
- break;
- case BT_PICCOLO:
- WSeq(SEQR7, 0x85);
- WSeq(SEQRF, 0xb0); /* Fast Page-Mode writes */
- WSeq(SEQR1F, 0x22); /* MCLK select */
- break;
+static int clgen_getcolreg (unsigned regno, unsigned *red, unsigned *green,
+ unsigned *blue, unsigned *transp,
+ struct fb_info *info)
+{
+ struct clgenfb_info *fb_info = (struct clgenfb_info *)info;
- case BT_PICASSO:
- WSeq(SEQR7, 0x25);
- WSeq(SEQRF, 0xb0); /* Fast Page-Mode writes */
- WSeq(SEQR1F, 0x22); /* MCLK select */
- break;
+ if (regno > 255)
+ return 1;
+ *red = fb_info->palette[regno].red;
+ *green = fb_info->palette[regno].green;
+ *blue = fb_info->palette[regno].blue;
+ *transp = 0;
+ return 0;
+}
- case BT_SPECTRUM:
- WSeq(SEQR7, 0x85);
- WSeq(SEQRF, 0xb0); /* Fast Page-Mode writes */
- WSeq(SEQR1F, 0x22); /* MCLK select */
- break;
- case BT_PICASSO4:
- WSeq(SEQR7, 0x25);
-/* WSeq(SEQR1F, 0x1c); */
- break;
+static int clgen_setcolreg (unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp,
+ struct fb_info *info)
+{
+ struct clgenfb_info *fb_info = (struct clgenfb_info *) info;
+
+ if (regno > 255)
+ return -EINVAL;
+#ifdef FBCON_HAS_CFB8
+ switch (fb_info->currentmode.var.bits_per_pixel) {
+ case 8:
+ /* "transparent" stuff is completely ignored. */
+ WClut (fb_info, regno, red >> 10, green >> 10, blue >> 10);
+ break;
default:
- printk(KERN_WARNING "clgen: unknown Board\n");
- break;
- }
-
- WGfx(GR5, 64); /* mode register: 256 color mode */
- WGen(M_3C6,0xff); /* pixel mask: pass-through all planes */
- WHDR(0xc5); /* hidden dac reg: 8-8-8 mode (24 or 32) */
- WSeq(SEQR4, 0x0a); /* memory mode: chain4, ext. memory */
- WSeq(SEQR2, 0xff); /* plane mask: enable writing to all 4 planes */
- offset = _par->var.xres_virtual / 4;
- }
- else
- printk(KERN_ERR "clgen: What's this?? requested color depth == %d.\n",
- _par->var.bits_per_pixel);
-
- WCrt(CRT13, offset & 0xff);
- tmp = 0x22;
- if (offset & 0x100) tmp |= 0x10; /* offset overflow bit */
-
- WCrt(CRT1B,tmp); /* screen start addr #16-18, fastpagemode cycles */
-
- if (fb_info->btype == BT_SD64 || fb_info->btype == BT_PICASSO4)
- WCrt(CRT1D, 0x00); /* screen start address bit 19 */
-
- WCrt(CRTE, 0); /* text cursor location high */
- WCrt(CRTF, 0); /* text cursor location low */
- WCrt(CRT14, 0); /* underline row scanline = at very bottom */
-
- WAttr(AR10, 1); /* controller mode */
- WAttr(AR11, 0); /* overscan (border) color */
- WAttr(AR12, 15); /* color plane enable */
- WAttr(AR33, 0); /* pixel panning */
- WAttr(AR14, 0); /* color select */
-
- /* [ EGS: SetOffset(); ] */
- /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */
- AttrOn();
-
- WGfx(GR0, 0); /* set/reset register */
- WGfx(GR1, 0); /* set/reset enable */
- WGfx(GR2, 0); /* color compare */
- WGfx(GR3, 0); /* data rotate */
- WGfx(GR4, 0); /* read map select */
- WGfx(GR6, 1); /* miscellaneous register */
- WGfx(GR7, 15); /* color don't care */
- WGfx(GR8, 255); /* bit mask */
-
- WSeq(SEQR12, 0x0); /* graphics cursor attributes: nothing special */
-
- /* finally, turn on everything - turn off "FullBandwidth" bit */
- /* also, set "DotClock%2" bit where requested */
- tmp = 0x01;
+ /* do nothing */
+ break;
+ }
+#endif /* FBCON_HAS_CFB8 */
-/*** FB_VMODE_CLOCK_HALVE in linux/fb.h not defined anymore ?
- if (var->vmode & FB_VMODE_CLOCK_HALVE)
- tmp |= 0x08;
-*/
+ fb_info->palette[regno].red = red;
+ fb_info->palette[regno].green = green;
+ fb_info->palette[regno].blue = blue;
- WSeq(SEQR1, tmp);
- DEBUG printk("SEQR1: %d\n", tmp);
+ if (regno >= 16)
+ return 0;
+
+ switch (fb_info->currentmode.var.bits_per_pixel) {
-#if 0
- DEBUG printk(KERN_INFO "clgen: clearing display...");
- clgen_RectFill(0, 0, _par->HorizRes, _par->VertRes, 0, _par->line_length);
- clgen_WaitBLT();
- DEBUG printk("done.\n");
+#ifdef FBCON_HAS_CFB16
+ case 16:
+ assert (regno < 16);
+#ifdef CONFIG_PREP
+ fb_info->fbcon_cmap.cfb16[regno] =
+ ((red & 0xf800) >> 9) |
+ ((green & 0xf800) >> 14) |
+ ((green & 0xf800) << 2) |
+ ((blue & 0xf800) >> 3);
+#else
+ fb_info->fbcon_cmap.cfb16[regno] =
+ ((red & 0xf800) >> 1) |
+ ((green & 0xf800) >> 6) |
+ ((blue & 0xf800) >> 11);
#endif
+#endif /* FBCON_HAS_CFB16 */
- fb_info->currentmode = *_par;
+#ifdef FBCON_HAS_CFB24
+ case 24:
+ assert (regno < 16);
+ fb_info->fbcon_cmap.cfb24[regno] =
+ (red << fb_info->currentmode.var.red.offset) |
+ (green << fb_info->currentmode.var.green.offset) |
+ (blue << fb_info->currentmode.var.blue.offset);
+ break;
+#endif /* FBCON_HAS_CFB24 */
- printk("virtual offset: (%d,%d)\n", _par->var.xoffset,_par->var.yoffset);
- /* pan to requested offset */
- clgen_pan_display (&fb_info->currentmode.var, (struct fb_info_gen*)fb_info);
+#ifdef FBCON_HAS_CFB32
+ case 32:
+ assert (regno < 16);
+#ifdef CONFIG_PREP
+ fb_info->fbcon_cmap.cfb32[regno] =
+ ((red & 0xff00)) |
+ ((green & 0xff00) << 8) |
+ ((blue & 0xff00) << 16);
+#else
+ fb_info->fbcon_cmap.cfb32[regno] =
+ ((red & 0xff00) << 8) |
+ ((green & 0xff00)) |
+ ((blue & 0xff00) >> 8);
+#endif
+ break;
+#endif /* FBCON_HAS_CFB32 */
+ default:
+ /* do nothing */
+ break;
+ }
- DEBUG printk("<clgen_set_par()\n");
- return;
+ return 0;
}
-static int clgen_getcolreg(unsigned regno, unsigned *red, unsigned *green,
- unsigned *blue, unsigned *transp,
- struct fb_info *info)
+/*************************************************************************
+ clgen_pan_display()
+
+ performs display panning - provided hardware permits this
+**************************************************************************/
+static int clgen_pan_display (const struct fb_var_screeninfo *var,
+ struct fb_info_gen *info)
{
- unsigned char bred, bgreen, bblue;
+ int xoffset = 0;
+ int yoffset = 0;
+ unsigned long base;
+ unsigned char tmp = 0, tmp2 = 0, xpix;
+ struct clgenfb_info *fb_info = (struct clgenfb_info *) info;
- if (regno > 255)
- return (1);
+ DPRINTK ("ENTER\n");
- fb_info = (struct clgenfb_info *)info;
+ /* no range checks for xoffset and yoffset, */
+ /* as fbgen_pan_display has already done this */
- RClut(regno, &bred, &bgreen, &bblue);
+ fb_info->currentmode.var.xoffset = var->xoffset;
+ fb_info->currentmode.var.yoffset = var->yoffset;
- *red = (bred<<10) | (bred<<4) | (bred>>2);
- *green = (bgreen<<10) | (bgreen<<4) | (bgreen>>2);
- *blue = (bblue<<10) | (bblue<<4) | (bblue>>2);
- *transp = 0;
- return (0);
-}
+ xoffset = var->xoffset * fb_info->currentmode.var.bits_per_pixel / 8;
+ yoffset = var->yoffset;
-static int clgen_setcolreg(unsigned regno, unsigned red, unsigned green,
- unsigned blue, unsigned transp,
- struct fb_info *info)
-{
- if (regno > 255)
- return (1);
+ base = yoffset * fb_info->currentmode.line_length + xoffset;
- fb_info = (struct clgenfb_info *)info;
-
- /* "transparent" stuff is completely ignored. */
- WClut(regno, red>>10, green>>10, blue>>10);
+ if (fb_info->currentmode.var.bits_per_pixel == 1) {
+ /* base is already correct */
+ xpix = (unsigned char) (var->xoffset % 8);
+ } else {
+ base /= 4;
+ xpix = (unsigned char) ((xoffset % 4) * 2);
+ }
- return (0);
-}
+ /* lower 8 + 8 bits of screen start address */
+ vga_wcrt (fb_info->regs, VGA_CRTC_START_LO, (unsigned char) (base & 0xff));
+ vga_wcrt (fb_info->regs, VGA_CRTC_START_HI, (unsigned char) (base >> 8));
+
+ /* construct bits 16, 17 and 18 of screen start address */
+ if (base & 0x10000)
+ tmp |= 0x01;
+ if (base & 0x20000)
+ tmp |= 0x04;
+ if (base & 0x40000)
+ tmp |= 0x08;
+
+ tmp2 = (vga_rcrt (fb_info->regs, CL_CRT1B) & 0xf2) | tmp; /* 0xf2 is %11110010, exclude tmp bits */
+ vga_wcrt (fb_info->regs, CL_CRT1B, tmp2);
+
+ /* construct bit 19 of screen start address */
+ if (clgen_board_info[fb_info->btype].scrn_start_bit19) {
+ tmp2 = 0;
+ if (base & 0x80000)
+ tmp2 = 0x80;
+ vga_wcrt (fb_info->regs, CL_CRT1D, tmp2);
+ }
-/*************************************************************************
- clgen_pan_display()
+ /* write pixel panning value to AR33; this does not quite work in 8bpp */
+ /* ### Piccolo..? Will this work? */
+ if (fb_info->currentmode.var.bits_per_pixel == 1)
+ vga_wattr (fb_info->regs, CL_AR33, xpix);
- performs display panning - provided hardware permits this
-**************************************************************************/
-static int clgen_pan_display(const struct fb_var_screeninfo *var,
- struct fb_info_gen *info)
-{
- int xoffset = 0;
- int yoffset = 0;
- unsigned long base;
- unsigned char tmp = 0, tmp2 = 0, xpix;
-
- fb_info = (struct clgenfb_info*)fb_info;
-
- /* no range checks for xoffset and yoffset, */
- /* as fbgen_pan_display has already done this */
-
- fb_info->currentmode.var.xoffset = var->xoffset;
- fb_info->currentmode.var.yoffset = var->yoffset;
-
- xoffset = var->xoffset * fb_info->currentmode.var.bits_per_pixel / 8;
- yoffset = var->yoffset;
-
- base = yoffset * fb_info->currentmode.line_length + xoffset;
-
- if (fb_info->currentmode.var.bits_per_pixel == 1)
- {
- /* base is already correct */
- xpix = (unsigned char)(var->xoffset % 8);
- }
- else
- {
- base /= 4;
- xpix = (unsigned char)((xoffset % 4) * 2);
- }
-
- /* lower 8 + 8 bits of screen start address */
- WCrt(CRTD, (unsigned char)(base & 0xff));
- WCrt(CRTC, (unsigned char)(base >> 8));
-
- /* construct bits 16, 17 and 18 of screen start address */
- if (base & 0x10000) tmp |= 0x01;
- if (base & 0x20000) tmp |= 0x04;
- if (base & 0x40000) tmp |= 0x08;
-
- tmp2 = (RCrt(CRT1B) & 0xf2) | tmp; /* 0xf2 is %11110010, exclude tmp bits */
- WCrt(CRT1B, tmp2);
- /* construct bit 19 of screen start address (only on SD64) */
- if (fb_info->btype == BT_SD64 ||
- fb_info->btype == BT_PICASSO4)
- {
- tmp2 = 0;
- if (base & 0x80000) tmp2 = 0x80;
- WCrt(CRT1D, tmp2);
- }
-
- /* write pixel panning value to AR33; this does not quite work in 8bpp */
- /* ### Piccolo..? Will this work? */
- if (fb_info->currentmode.var.bits_per_pixel == 1)
- WAttr(AR33, xpix);
-
- return(0);
+
+ DPRINTK ("EXIT\n");
+ return (0);
}
-static int clgen_blank(int blank_mode, struct fb_info_gen *info)
+static int clgen_blank (int blank_mode, struct fb_info_gen *info)
{
- unsigned char val;
- printk(">clgen_blank(%d)\n",blank_mode);
+ /*
+ * Blank the screen if blank_mode != 0, else unblank. If blank == NULL
+ * then the caller blanks by setting the CLUT (Color Look Up Table) to all
+ * black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due
+ * to e.g. a video mode which doesn't support it. Implements VESA suspend
+ * and powerdown modes on hardware that supports disabling hsync/vsync:
+ * blank_mode == 2: suspend vsync
+ * blank_mode == 3: suspend hsync
+ * blank_mode == 4: powerdown
+ */
+ unsigned char val;
+ static int current_mode = 0;
+ struct clgenfb_info *fb_info = (struct clgenfb_info *) info;
+
+ DPRINTK ("ENTER, blank mode = %d\n", blank_mode);
+
+ if (current_mode == blank_mode) {
+ DPRINTK ("EXIT, returning 0\n");
+ return 0;
+ }
- fb_info = (struct clgenfb_info *)info;
+ /* Undo current */
+ switch (current_mode) {
+ case 0: /* Screen is normal */
+ break;
+ case 1: /* Screen is blanked */
+ val = vga_rseq (fb_info->regs, VGA_SEQ_CLOCK_MODE);
+ vga_wseq (fb_info->regs, VGA_SEQ_CLOCK_MODE, val & 0xdf); /* clear "FullBandwidth" bit */
+ break;
+ case 2: /* vsync suspended */
+ case 3: /* hsync suspended */
+ case 4: /* sceen is powered down */
+ vga_wgfx (fb_info->regs, CL_GRE, 0x00);
+ break;
+ default:
+ DPRINTK ("EXIT, returning 1\n");
+ return 1;
+ }
- val = RSeq(SEQR1);
- if (blank_mode)
- WSeq(SEQR1, val | 0x20); /* set "FullBandwidth" bit */
- else
- WSeq(SEQR1, val & 0xdf); /* clear "FullBandwidth" bit */
+ /* set new */
+ switch (blank_mode) {
+ case 0: /* Unblank screen */
+ break;
+ case 1: /* Blank screen */
+ val = vga_rseq (fb_info->regs, VGA_SEQ_CLOCK_MODE);
+ vga_wseq (fb_info->regs, VGA_SEQ_CLOCK_MODE, val | 0x20); /* set "FullBandwidth" bit */
+ break;
+ case 2: /* suspend vsync */
+ vga_wgfx (fb_info->regs, CL_GRE, 0x04);
+ break;
+ case 3: /* suspend hsync */
+ vga_wgfx (fb_info->regs, CL_GRE, 0x02);
+ break;
+ case 4: /* powerdown */
+ vga_wgfx (fb_info->regs, CL_GRE, 0x06);
+ break;
+ default:
+ DPRINTK ("EXIT, returning 1\n");
+ return 1;
+ }
- printk("<clgen_blank()\n");
- return 0;
+ current_mode = blank_mode;
+ DPRINTK ("EXIT, returning 0\n");
+ return 0;
}
-
/**** END Hardware specific Routines **************************************/
/****************************************************************************/
/**** BEGIN Internal Routines ***********************************************/
-static void init_vgachip(void)
+static void __init init_vgachip (struct clgenfb_info *fb_info)
{
- printk(">init_vgachip()\n");
-
- /* reset board globally */
- switch(fb_info->btype)
- {
- case BT_SD64: WSFR(0x1f); udelay(500); WSFR(0x4f); udelay(500); break;
- case BT_PICCOLO: WSFR(0x01); udelay(500); WSFR(0x51); udelay(500); break;
- case BT_PICASSO: WSFR2(0xff); udelay(500); break;
- case BT_SPECTRUM: WSFR(0x1f); udelay(500); WSFR(0x4f); udelay(500); break;
- case BT_PICASSO4:
- WCrt(CRT51, 0x00); /* disable flickerfixer */
- udelay(100000);
- WGfx(GR2F, 0x00); /* from Klaus' NetBSD driver: */
- WGfx(GR33, 0x00); /* put blitter into 542x compat */
- WGfx(GR31, 0x00); /* mode */
- break;
-
- default:
- printk(KERN_ERR "clgen: Warning: Unknown board type\n");
- break;
- }
-
- /* "pre-set" a RAMsize; if the test succeeds, double it */
- if (fb_info->btype == BT_SD64 ||
- fb_info->btype == BT_PICASSO4)
- fb_info->size = 0x400000;
- else
- fb_info->size = 0x200000;
-
- /* assume it's a "large memory" board (2/4 MB) */
- fb_info->smallboard = FALSE;
-
- /* the P4 is not fully initialized here; I rely on it having been */
- /* inited under AmigaOS already, which seems to work just fine */
- /* (Klaus advised to do it this way) */
-
- if (fb_info->btype != BT_PICASSO4)
- {
- WGen(VSSM, 0x10); /* EGS: 0x16 */
- WGen(POS102, 0x01);
- WGen(VSSM, 0x08); /* EGS: 0x0e */
-
- if(fb_info->btype != BT_SD64)
- WGen(VSSM2, 0x01);
-
- WSeq(SEQR0, 0x03); /* reset sequencer logic */
-
- WSeq(SEQR1, 0x21); /* FullBandwidth (video off) and 8/9 dot clock */
- WGen(MISC_W, 0xc1); /* polarity (-/-), disable access to display memory, CRTC base address: color */
-
-/* WGfx(GRA, 0xce); "magic cookie" - doesn't make any sense to me.. */
- WSeq(SEQR6, 0x12); /* unlock all extension registers */
-
- WGfx(GR31, 0x04); /* reset blitter */
-
- if (fb_info->btype == BT_SD64)
- {
- WSeq(SEQRF, 0xb8); /* 4 MB Ram SD64, disable CRT fifo(!), 64 bit bus */
+ const struct clgen_board_info_rec *bi;
+
+ DPRINTK ("ENTER\n");
+
+ assert (fb_info != NULL);
+
+ bi = &clgen_board_info[fb_info->btype];
+
+ /* reset board globally */
+ switch (fb_info->btype) {
+ case BT_PICCOLO:
+ WSFR (fb_info, 0x01);
+ udelay (500);
+ WSFR (fb_info, 0x51);
+ udelay (500);
+ break;
+ case BT_PICASSO:
+ WSFR2 (fb_info, 0xff);
+ udelay (500);
+ break;
+ case BT_SD64:
+ case BT_SPECTRUM:
+ WSFR (fb_info, 0x1f);
+ udelay (500);
+ WSFR (fb_info, 0x4f);
+ udelay (500);
+ break;
+ case BT_PICASSO4:
+ vga_wcrt (fb_info->regs, CL_CRT51, 0x00); /* disable flickerfixer */
+ udelay (100000);
+ vga_wgfx (fb_info->regs, CL_GR2F, 0x00); /* from Klaus' NetBSD driver: */
+ vga_wgfx (fb_info->regs, CL_GR33, 0x00); /* put blitter into 542x compat */
+ vga_wgfx (fb_info->regs, CL_GR31, 0x00); /* mode */
+ break;
+
+ case BT_GD5480:
+ vga_wgfx (fb_info->regs, CL_GR2F, 0x00); /* from Klaus' NetBSD driver: */
+ break;
+
+ case BT_ALPINE:
+ /* Nothing to do to reset the board. */
+ break;
+
+ default:
+ printk (KERN_ERR "clgen: Warning: Unknown board type\n");
+ break;
}
+
+#ifdef CLGEN_USE_HARDCODED_RAM_SETTINGS
+ /* "pre-set" a RAMsize; if the test succeeds, double it */
+ if (fb_info->btype == BT_SD64 ||
+ fb_info->btype == BT_PICASSO4)
+ fb_info->size = 0x400000;
else
- {
- WSeq(SEQR16, 0x0f); /* Perf. Tuning: Fix value..(?) */
- WSeq(SEQRF, 0xb0); /* 2 MB DRAM, 8level write buffer, 32bit bus */
- }
- }
-
- WSeq(SEQR2, 0xff); /* plane mask: nothing */
- WSeq(SEQR3, 0x00); /* character map select: doesn't even matter in gx mode */
- WSeq(SEQR4, 0x0e); /* memory mode: chain-4, no odd/even, ext. memory */
-
- /* controller-internal base address of video memory */
- switch(fb_info->btype)
- {
- case BT_SD64: WSeq(SEQR7, 0xf0); break;
- case BT_PICCOLO: WSeq(SEQR7, 0x80); break;
- case BT_SPECTRUM: WSeq(SEQR7, 0x80); break;
- case BT_PICASSO: WSeq(SEQR7, 0x20); break;
- case BT_PICASSO4: WSeq(SEQR7, 0x20); break;
- }
-
-/* WSeq(SEQR8, 0x00);*/ /* EEPROM control: shouldn't be necessary to write to this at all.. */
-
- WSeq(SEQR10, 0x00); /* graphics cursor X position (incomplete; position gives rem. 3 bits */
- WSeq(SEQR11, 0x00); /* graphics cursor Y position (..."... ) */
- WSeq(SEQR12, 0x00); /* graphics cursor attributes */
- WSeq(SEQR13, 0x00); /* graphics cursor pattern address */
-
- /* writing these on a P4 might give problems.. */
- if (fb_info->btype != BT_PICASSO4)
- {
- WSeq(SEQR17, 0x00); /* configuration readback and ext. color */
- WSeq(SEQR18, 0x02); /* signature generator */
- }
-
- /* MCLK select etc. */
- switch(fb_info->btype)
- {
- case BT_PICCOLO:
- case BT_PICASSO:
- case BT_SPECTRUM: WSeq(SEQR1F, 0x22); break;
- case BT_SD64: WSeq(SEQR1F, 0x20); break;
- case BT_PICASSO4:/*WSeq(SEQR1F, 0x1c); */ break;
- }
-
- WCrt(CRT8, 0x00); /* Screen A preset row scan: none */
- WCrt(CRTA, 0x20); /* Text cursor start: disable text cursor */
- WCrt(CRTB, 0x00); /* Text cursor end: - */
- WCrt(CRTC, 0x00); /* Screen start address high: 0 */
- WCrt(CRTD, 0x00); /* Screen start address low: 0 */
- WCrt(CRTE, 0x00); /* text cursor location high: 0 */
- WCrt(CRTF, 0x00); /* text cursor location low: 0 */
-
- WCrt(CRT14, 0x00); /* Underline Row scanline: - */
- WCrt(CRT17, 0xc3); /* mode control: timing enable, byte mode, no compat modes */
- WCrt(CRT18, 0x00); /* Line Compare: not needed */
- /* ### add 0x40 for text modes with > 30 MHz pixclock */
- WCrt(CRT1B, 0x02); /* ext. display controls: ext.adr. wrap */
-
- WGfx(GR0, 0x00); /* Set/Reset registes: - */
- WGfx(GR1, 0x00); /* Set/Reset enable: - */
- WGfx(GR2, 0x00); /* Color Compare: - */
- WGfx(GR3, 0x00); /* Data Rotate: - */
- WGfx(GR4, 0x00); /* Read Map Select: - */
- WGfx(GR5, 0x00); /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */
- WGfx(GR6, 0x01); /* Miscellaneous: memory map base address, graphics mode */
- WGfx(GR7, 0x0f); /* Color Don't care: involve all planes */
- WGfx(GR8, 0xff); /* Bit Mask: no mask at all */
- WGfx(GRB, 0x28); /* Graphics controller mode extensions: finer granularity, 8byte data latches */
-
- WGfx(GRC, 0xff); /* Color Key compare: - */
- WGfx(GRD, 0x00); /* Color Key compare mask: - */
- WGfx(GRE, 0x00); /* Miscellaneous control: - */
-/* WGfx(GR10, 0x00);*/ /* Background color byte 1: - */
-/* WGfx(GR11, 0x00); */
-
- WAttr(AR0, 0x00); /* Attribute Controller palette registers: "identity mapping" */
- WAttr(AR1, 0x01);
- WAttr(AR2, 0x02);
- WAttr(AR3, 0x03);
- WAttr(AR4, 0x04);
- WAttr(AR5, 0x05);
- WAttr(AR6, 0x06);
- WAttr(AR7, 0x07);
- WAttr(AR8, 0x08);
- WAttr(AR9, 0x09);
- WAttr(ARA, 0x0a);
- WAttr(ARB, 0x0b);
- WAttr(ARC, 0x0c);
- WAttr(ARD, 0x0d);
- WAttr(ARE, 0x0e);
- WAttr(ARF, 0x0f);
-
- WAttr(AR10, 0x01); /* Attribute Controller mode: graphics mode */
- WAttr(AR11, 0x00); /* Overscan color reg.: reg. 0 */
- WAttr(AR12, 0x0f); /* Color Plane enable: Enable all 4 planes */
-/* ### WAttr(AR33, 0x00); * Pixel Panning: - */
- WAttr(AR14, 0x00); /* Color Select: - */
-
- WGen(M_3C6, 0xff); /* Pixel mask: no mask */
-
- WGen(MISC_W, 0xc3); /* polarity (-/-), enable display mem, CRTC i/o base = color */
-
- WGfx(GR31, 0x04); /* BLT Start/status: Blitter reset */
- WGfx(GR31, 0x00); /* - " - : "end-of-reset" */
-
- /* CLUT setup */
- WClut( 0, 0x00, 0x00, 0x00); /* background: black */
- WClut( 1, 0x3f, 0x3f, 0x3f); /* foreground: white */
- WClut( 2, 0x00, 0x20, 0x00);
- WClut( 3, 0x00, 0x20, 0x20);
- WClut( 4, 0x20, 0x00, 0x00);
- WClut( 5, 0x20, 0x00, 0x20);
- WClut( 6, 0x20, 0x10, 0x00);
- WClut( 7, 0x20, 0x20, 0x20);
- WClut( 8, 0x10, 0x10, 0x10);
- WClut( 9, 0x10, 0x10, 0x30);
- WClut(10, 0x10, 0x30, 0x10);
- WClut(11, 0x10, 0x30, 0x30);
- WClut(12, 0x30, 0x10, 0x10);
- WClut(13, 0x30, 0x10, 0x30);
- WClut(14, 0x30, 0x30, 0x10);
- WClut(15, 0x30, 0x30, 0x30);
-
- /* the rest a grey ramp */
- {
- int i;
+ fb_info->size = 0x200000;
+#else
+ assert (fb_info->size > 0); /* make sure RAM size set by this point */
+#endif
- for (i = 16; i < 256; i++)
- WClut(i, i>>2, i>>2, i>>2);
- }
+ /* assume it's a "large memory" board (2/4 MB) */
+ fb_info->smallboard = FALSE;
+ /* the P4 is not fully initialized here; I rely on it having been */
+ /* inited under AmigaOS already, which seems to work just fine */
+ /* (Klaus advised to do it this way) */
- /* misc... */
- WHDR(0); /* Hidden DAC register: - */
+ if (fb_info->btype != BT_PICASSO4) {
+ WGen (fb_info, CL_VSSM, 0x10); /* EGS: 0x16 */
+ WGen (fb_info, CL_POS102, 0x01);
+ WGen (fb_info, CL_VSSM, 0x08); /* EGS: 0x0e */
-#if 0
- /* check for 1/2 MB Piccolo/Picasso/Spectrum resp. 2/4 MB SD64 */
- /* DRAM register has already been pre-set for "large", so it is*/
- /* only modified if we find that this is a "small" version */
- {
- unsigned volatile char *ram = fb_info->fbmem;
- int i, flag = 0;
+ if (fb_info->btype != BT_SD64)
+ WGen (fb_info, CL_VSSM2, 0x01);
- ram += (fb_info->size >> 1);
+ vga_wseq (fb_info->regs, CL_SEQR0, 0x03); /* reset sequencer logic */
- for (i = 0; i < 256; i++)
- ram[i] = (unsigned char)i;
+ vga_wseq (fb_info->regs, VGA_SEQ_CLOCK_MODE, 0x21); /* FullBandwidth (video off) and 8/9 dot clock */
+ WGen (fb_info, VGA_MIS_W, 0xc1); /* polarity (-/-), disable access to display memory, VGA_CRTC_START_HI base address: color */
- for (i = 0; i < 256; i++)
- {
- if (ram[i] != i)
- flag = 1;
+/* vga_wgfx (fb_info->regs, CL_GRA, 0xce); "magic cookie" - doesn't make any sense to me.. */
+ vga_wseq (fb_info->regs, CL_SEQR6, 0x12); /* unlock all extension registers */
+
+ vga_wgfx (fb_info->regs, CL_GR31, 0x04); /* reset blitter */
+
+ switch (fb_info->btype) {
+ case BT_GD5480:
+ vga_wseq (fb_info->regs, CL_SEQRF, 0x98);
+ break;
+ case BT_ALPINE:
+ break;
+ case BT_SD64:
+ vga_wseq (fb_info->regs, CL_SEQRF, 0xb8);
+ break;
+ default:
+ vga_wseq (fb_info->regs, CL_SEQR16, 0x0f);
+ vga_wseq (fb_info->regs, CL_SEQRF, 0xb0);
+ break;
+ }
}
+ vga_wseq (fb_info->regs, VGA_SEQ_PLANE_WRITE, 0xff); /* plane mask: nothing */
+ vga_wseq (fb_info->regs, VGA_SEQ_CHARACTER_MAP, 0x00); /* character map select: doesn't even matter in gx mode */
+ vga_wseq (fb_info->regs, VGA_SEQ_MEMORY_MODE, 0x0e); /* memory mode: chain-4, no odd/even, ext. memory */
- /* if the DRAM test failed, halve RAM value */
- if (flag)
+ /* controller-internal base address of video memory */
+ if (bi->init_sr07)
+ vga_wseq (fb_info->regs, CL_SEQR7, bi->sr07);
+
+ /* vga_wseq (fb_info->regs, CL_SEQR8, 0x00); *//* EEPROM control: shouldn't be necessary to write to this at all.. */
+
+ vga_wseq (fb_info->regs, CL_SEQR10, 0x00); /* graphics cursor X position (incomplete; position gives rem. 3 bits */
+ vga_wseq (fb_info->regs, CL_SEQR11, 0x00); /* graphics cursor Y position (..."... ) */
+ vga_wseq (fb_info->regs, CL_SEQR12, 0x00); /* graphics cursor attributes */
+ vga_wseq (fb_info->regs, CL_SEQR13, 0x00); /* graphics cursor pattern address */
+
+ /* writing these on a P4 might give problems.. */
+ if (fb_info->btype != BT_PICASSO4) {
+ vga_wseq (fb_info->regs, CL_SEQR17, 0x00); /* configuration readback and ext. color */
+ vga_wseq (fb_info->regs, CL_SEQR18, 0x02); /* signature generator */
+ }
+
+ /* MCLK select etc. */
+ if (bi->init_sr1f)
+ vga_wseq (fb_info->regs, CL_SEQR1F, bi->sr1f);
+
+ vga_wcrt (fb_info->regs, VGA_CRTC_PRESET_ROW, 0x00); /* Screen A preset row scan: none */
+ vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_START, 0x20); /* Text cursor start: disable text cursor */
+ vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_END, 0x00); /* Text cursor end: - */
+ vga_wcrt (fb_info->regs, VGA_CRTC_START_HI, 0x00); /* Screen start address high: 0 */
+ vga_wcrt (fb_info->regs, VGA_CRTC_START_LO, 0x00); /* Screen start address low: 0 */
+ vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_HI, 0x00); /* text cursor location high: 0 */
+ vga_wcrt (fb_info->regs, VGA_CRTC_CURSOR_LO, 0x00); /* text cursor location low: 0 */
+
+ vga_wcrt (fb_info->regs, VGA_CRTC_UNDERLINE, 0x00); /* Underline Row scanline: - */
+ vga_wcrt (fb_info->regs, VGA_CRTC_MODE, 0xc3); /* mode control: timing enable, byte mode, no compat modes */
+ vga_wcrt (fb_info->regs, VGA_CRTC_LINE_COMPARE, 0x00); /* Line Compare: not needed */
+ /* ### add 0x40 for text modes with > 30 MHz pixclock */
+ vga_wcrt (fb_info->regs, CL_CRT1B, 0x02); /* ext. display controls: ext.adr. wrap */
+
+ vga_wgfx (fb_info->regs, VGA_GFX_SR_VALUE, 0x00); /* Set/Reset registes: - */
+ vga_wgfx (fb_info->regs, VGA_GFX_SR_ENABLE, 0x00); /* Set/Reset enable: - */
+ vga_wgfx (fb_info->regs, VGA_GFX_COMPARE_VALUE, 0x00); /* Color Compare: - */
+ vga_wgfx (fb_info->regs, VGA_GFX_DATA_ROTATE, 0x00); /* Data Rotate: - */
+ vga_wgfx (fb_info->regs, VGA_GFX_PLANE_READ, 0x00); /* Read Map Select: - */
+ vga_wgfx (fb_info->regs, VGA_GFX_MODE, 0x00); /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */
+ vga_wgfx (fb_info->regs, VGA_GFX_MISC, 0x01); /* Miscellaneous: memory map base address, graphics mode */
+ vga_wgfx (fb_info->regs, VGA_GFX_COMPARE_MASK, 0x0f); /* Color Don't care: involve all planes */
+ vga_wgfx (fb_info->regs, VGA_GFX_BIT_MASK, 0xff); /* Bit Mask: no mask at all */
+ if (fb_info->btype == BT_ALPINE)
+ vga_wgfx (fb_info->regs, CL_GRB, 0x20); /* (5434 can't have bit 3 set for bitblt) */
+ else
+ vga_wgfx (fb_info->regs, CL_GRB, 0x28); /* Graphics controller mode extensions: finer granularity, 8byte data latches */
+
+ vga_wgfx (fb_info->regs, CL_GRC, 0xff); /* Color Key compare: - */
+ vga_wgfx (fb_info->regs, CL_GRD, 0x00); /* Color Key compare mask: - */
+ vga_wgfx (fb_info->regs, CL_GRE, 0x00); /* Miscellaneous control: - */
+ /* vga_wgfx (fb_info->regs, CL_GR10, 0x00); *//* Background color byte 1: - */
+/* vga_wgfx (fb_info->regs, CL_GR11, 0x00); */
+
+ vga_wattr (fb_info->regs, VGA_ATC_PALETTE0, 0x00); /* Attribute Controller palette registers: "identity mapping" */
+ vga_wattr (fb_info->regs, VGA_ATC_PALETTE1, 0x01);
+ vga_wattr (fb_info->regs, VGA_ATC_PALETTE2, 0x02);
+ vga_wattr (fb_info->regs, VGA_ATC_PALETTE3, 0x03);
+ vga_wattr (fb_info->regs, VGA_ATC_PALETTE4, 0x04);
+ vga_wattr (fb_info->regs, VGA_ATC_PALETTE5, 0x05);
+ vga_wattr (fb_info->regs, VGA_ATC_PALETTE6, 0x06);
+ vga_wattr (fb_info->regs, VGA_ATC_PALETTE7, 0x07);
+ vga_wattr (fb_info->regs, VGA_ATC_PALETTE8, 0x08);
+ vga_wattr (fb_info->regs, VGA_ATC_PALETTE9, 0x09);
+ vga_wattr (fb_info->regs, VGA_ATC_PALETTEA, 0x0a);
+ vga_wattr (fb_info->regs, VGA_ATC_PALETTEB, 0x0b);
+ vga_wattr (fb_info->regs, VGA_ATC_PALETTEC, 0x0c);
+ vga_wattr (fb_info->regs, VGA_ATC_PALETTED, 0x0d);
+ vga_wattr (fb_info->regs, VGA_ATC_PALETTEE, 0x0e);
+ vga_wattr (fb_info->regs, VGA_ATC_PALETTEF, 0x0f);
+
+ vga_wattr (fb_info->regs, VGA_ATC_MODE, 0x01); /* Attribute Controller mode: graphics mode */
+ vga_wattr (fb_info->regs, VGA_ATC_OVERSCAN, 0x00); /* Overscan color reg.: reg. 0 */
+ vga_wattr (fb_info->regs, VGA_ATC_PLANE_ENABLE, 0x0f); /* Color Plane enable: Enable all 4 planes */
+/* ### vga_wattr (fb_info->regs, CL_AR33, 0x00); * Pixel Panning: - */
+ vga_wattr (fb_info->regs, VGA_ATC_COLOR_PAGE, 0x00); /* Color Select: - */
+
+ WGen (fb_info, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */
+
+ if (fb_info->btype != BT_ALPINE && fb_info->btype != BT_GD5480)
+ WGen (fb_info, VGA_MIS_W, 0xc3); /* polarity (-/-), enable display mem, VGA_CRTC_START_HI i/o base = color */
+
+ vga_wgfx (fb_info->regs, CL_GR31, 0x04); /* BLT Start/status: Blitter reset */
+ vga_wgfx (fb_info->regs, CL_GR31, 0x00); /* - " - : "end-of-reset" */
+
+ /* CLUT setup */
+ WClut (fb_info, 0, 0x00, 0x00, 0x00); /* background: black */
+ WClut (fb_info, 1, 0x3f, 0x3f, 0x3f); /* foreground: white */
+ WClut (fb_info, 2, 0x00, 0x20, 0x00);
+ WClut (fb_info, 3, 0x00, 0x20, 0x20);
+ WClut (fb_info, 4, 0x20, 0x00, 0x00);
+ WClut (fb_info, 5, 0x20, 0x00, 0x20);
+ WClut (fb_info, 6, 0x20, 0x10, 0x00);
+ WClut (fb_info, 7, 0x20, 0x20, 0x20);
+ WClut (fb_info, 8, 0x10, 0x10, 0x10);
+ WClut (fb_info, 9, 0x10, 0x10, 0x30);
+ WClut (fb_info, 10, 0x10, 0x30, 0x10);
+ WClut (fb_info, 11, 0x10, 0x30, 0x30);
+ WClut (fb_info, 12, 0x30, 0x10, 0x10);
+ WClut (fb_info, 13, 0x30, 0x10, 0x30);
+ WClut (fb_info, 14, 0x30, 0x30, 0x10);
+ WClut (fb_info, 15, 0x30, 0x30, 0x30);
+
+ /* the rest a grey ramp */
{
- fb_info->size /= 2;
- fb_info->smallboard = TRUE;
- switch(fb_info->btype)
- {
- case BT_SD64: WSeq(SEQRF, 0x38); break; /* 2 MB Ram SD64 */
- case BT_PICASSO4: WSeq(SEQRF, 0x38); break; /* ### like SD64? */
- case BT_PICCOLO:
- case BT_PICASSO:
- case BT_SPECTRUM: WSeq(SEQRF, 0x30); break; /* 1 MB DRAM */
- default:
- printk(KERN_WARNING "clgen: Uuhh..could not determine RAM size!\n");
- }
- }
-
- }
-#endif
- printk(KERN_INFO "clgen: This board has %ld bytes of DRAM memory\n", fb_info->size);
- printk("<init_vgachip()\n");
- return;
-}
+ int i;
+
+ for (i = 16; i < 256; i++)
+ WClut (fb_info, i, i >> 2, i >> 2, i >> 2);
+ }
-static void switch_monitor(int on)
-{
- static int IsOn = 0; /* XXX not ok for multiple boards */
- if (fb_info->btype == BT_PICASSO4) return; /* nothing to switch */
- if (fb_info->btype == BT_PICASSO)
- {
- if ((on && !IsOn) || (!on && IsOn))
- WSFR(0xff);
+ /* misc... */
+ WHDR (fb_info, 0); /* Hidden DAC register: - */
+
+ printk (KERN_INFO "clgen: This board has %ld bytes of DRAM memory\n", fb_info->size);
+ DPRINTK ("EXIT\n");
return;
- }
- if (on)
- switch(fb_info->btype)
- {
- case BT_SD64: WSFR(fb_info->SFR | 0x21); break;
- case BT_PICCOLO: WSFR(fb_info->SFR | 0x28); break;
- case BT_SPECTRUM: WSFR(0x6f); break;
+}
+
+static void switch_monitor (struct clgenfb_info *fb_info, int on)
+{
+#ifdef CONFIG_ZORRO /* only works on Zorro boards */
+ static int IsOn = 0; /* XXX not ok for multiple boards */
+
+ DPRINTK ("ENTER\n");
+
+ if (fb_info->btype == BT_PICASSO4)
+ return; /* nothing to switch */
+ if (fb_info->btype == BT_ALPINE)
+ return; /* nothing to switch */
+ if (fb_info->btype == BT_GD5480)
+ return; /* nothing to switch */
+ if (fb_info->btype == BT_PICASSO) {
+ if ((on && !IsOn) || (!on && IsOn))
+ WSFR (fb_info, 0xff);
+
+ DPRINTK ("EXIT\n");
+ return;
}
- else
- switch(fb_info->btype)
- {
- case BT_SD64: WSFR(fb_info->SFR & 0xde); break;
- case BT_PICCOLO: WSFR(fb_info->SFR & 0xd7); break;
- case BT_SPECTRUM: WSFR(0x4f); break;
+ if (on) {
+ switch (fb_info->btype) {
+ case BT_SD64:
+ WSFR (fb_info, fb_info->SFR | 0x21);
+ break;
+ case BT_PICCOLO:
+ WSFR (fb_info, fb_info->SFR | 0x28);
+ break;
+ case BT_SPECTRUM:
+ WSFR (fb_info, 0x6f);
+ break;
+ default: /* do nothing */ break;
+ }
+ } else {
+ switch (fb_info->btype) {
+ case BT_SD64:
+ WSFR (fb_info, fb_info->SFR & 0xde);
+ break;
+ case BT_PICCOLO:
+ WSFR (fb_info, fb_info->SFR & 0xd7);
+ break;
+ case BT_SPECTRUM:
+ WSFR (fb_info, 0x4f);
+ break;
+ default: /* do nothing */ break;
+ }
}
+
+ DPRINTK ("EXIT\n");
+#endif /* CONFIG_ZORRO */
}
-static void clgen_set_disp(const void *par, struct display *disp,
- struct fb_info_gen *info)
+static void clgen_set_disp (const void *par, struct display *disp,
+ struct fb_info_gen *info)
{
- struct clgenfb_par *_par = (struct clgenfb_par*) par;
- struct clgenfb_info *info2 = (struct clgenfb_info *)info;
+ struct clgenfb_par *_par = (struct clgenfb_par *) par;
+ struct clgenfb_info *fb_info = (struct clgenfb_info *) info;
+ int accel_text;
+
+ DPRINTK ("ENTER\n");
+
+ assert (_par != NULL);
+ assert (fb_info != NULL);
+
+ accel_text = _par->var.accel_flags & FB_ACCELF_TEXT;
- printk("clgen_set_disp(): ");
- disp->screen_base = info2->fbmem;
- switch (_par->var.bits_per_pixel)
- {
+ printk ("Cirrus Logic video mode: ");
+ disp->screen_base = (char *) fb_info->fbmem;
+ switch (_par->var.bits_per_pixel) {
#ifdef FBCON_HAS_MFB
- case 1:
- printk("monochrome\n");
- disp->dispsw = &fbcon_mfb;
- break;
+ case 1:
+ printk ("monochrome\n");
+ if (fb_info->btype == BT_GD5480)
+ disp->screen_base = (char *) fb_info->fbmem;
+ disp->dispsw = &fbcon_mfb;
+ break;
#endif
#ifdef FBCON_HAS_CFB8
- case 8:
- printk("8 bit color depth\n");
- disp->dispsw = &fbcon_clgen_8;
- break;
+ case 8:
+ printk ("8 bit color depth\n");
+ if (fb_info->btype == BT_GD5480)
+ disp->screen_base = (char *) fb_info->fbmem;
+ if (accel_text)
+ disp->dispsw = &fbcon_clgen_8;
+ else
+ disp->dispsw = &fbcon_cfb8;
+ break;
#endif
#ifdef FBCON_HAS_CFB16
- case 16:
- printk("16 bit color depth\n");
- disp->dispsw = &fbcon_cfb16;
- disp->dispsw_data = info2->fbcon_cmap.cfb16;
- break;
+ case 16:
+ printk ("16 bit color depth\n");
+ if (accel_text)
+ disp->dispsw = &fbcon_clgen_16;
+ else
+ disp->dispsw = &fbcon_cfb16;
+ if (fb_info->btype == BT_GD5480)
+ disp->screen_base = (char *) fb_info->fbmem + 1 * MB_;
+ disp->dispsw_data = fb_info->fbcon_cmap.cfb16;
+ break;
#endif
#ifdef FBCON_HAS_CFB24
- case 24:
- printk("24 bit color depth\n");
- disp->dispsw = &fbcon_cfb24;
- disp->dispsw_data = info2->fbcon_cmap.cfb24;
- break;
+ case 24:
+ printk ("24 bit color depth\n");
+ disp->dispsw = &fbcon_cfb24;
+ if (fb_info->btype == BT_GD5480)
+ disp->screen_base = (char *) fb_info->fbmem + 2 * MB_;
+ disp->dispsw_data = fb_info->fbcon_cmap.cfb24;
+ break;
#endif
#ifdef FBCON_HAS_CFB32
- case 32:
- printk("32 bit color depth\n");
- disp->dispsw = &fbcon_cfb32;
- disp->dispsw_data = info2->fbcon_cmap.cfb32;
- break;
+ case 32:
+ printk ("32 bit color depth\n");
+ if (accel_text)
+ disp->dispsw = &fbcon_clgen_32;
+ else
+ disp->dispsw = &fbcon_cfb32;
+ if (fb_info->btype == BT_GD5480)
+ disp->screen_base = (char *) fb_info->fbmem + 2 * MB_;
+ disp->dispsw_data = fb_info->fbcon_cmap.cfb32;
+ break;
#endif
- default:
- printk("unsupported color depth\n");
- disp->dispsw = &fbcon_dummy;
- break;
- }
+ default:
+ printk ("unsupported color depth\n");
+ disp->dispsw = &fbcon_dummy;
+ disp->dispsw_data = NULL;
+ break;
+ }
+
+ DPRINTK ("EXIT\n");
}
-static void fbcon_clgen8_bmove(struct display *p, int sy, int sx,
+#ifdef FBCON_HAS_CFB8
+static void fbcon_clgen8_bmove (struct display *p, int sy, int sx,
int dy, int dx, int height, int width)
{
- sx *= fontwidth(p);
- sy *= fontheight(p);
- dx *= fontwidth(p);
- dy *= fontheight(p);
- width *= fontwidth(p);
- height *= fontheight(p);
-
- fb_info = (struct clgenfb_info*)p->fb_info;
-
- clgen_BitBLT((unsigned short)sx, (unsigned short)sy,
- (unsigned short)dx, (unsigned short)dy,
- (unsigned short)width, (unsigned short)height,
- fb_info->currentmode.line_length);
- clgen_WaitBLT();
+ struct clgenfb_info *fb_info = (struct clgenfb_info *) p->fb_info;
+
+ DPRINTK ("ENTER\n");
+
+ sx *= fontwidth (p);
+ sy *= fontheight (p);
+ dx *= fontwidth (p);
+ dy *= fontheight (p);
+ width *= fontwidth (p);
+ height *= fontheight (p);
+
+ clgen_BitBLT (fb_info->regs, (unsigned short) sx, (unsigned short) sy,
+ (unsigned short) dx, (unsigned short) dy,
+ (unsigned short) width, (unsigned short) height,
+ fb_info->currentmode.line_length);
+
+ DPRINTK ("EXIT\n");
}
-static void fbcon_clgen8_clear(struct vc_data *conp, struct display *p,
+static void fbcon_clgen8_clear (struct vc_data *conp, struct display *p,
int sy, int sx, int height, int width)
{
- unsigned short col;
-
- fb_info = (struct clgenfb_info*)p->fb_info;
-
- sx *= fontwidth(p);
- sy *= fontheight(p);
- width *= fontwidth(p);
- height *= fontheight(p);
-
- col = attr_bgcol_ec(p, conp);
- col &= 0xff;
-
- clgen_RectFill((unsigned short)sx, (unsigned short)sy,
- (unsigned short)width,(unsigned short)height,
- col, fb_info->currentmode.line_length);
- clgen_WaitBLT();
+ struct clgenfb_info *fb_info = (struct clgenfb_info *) p->fb_info;
+ unsigned short col;
+
+ DPRINTK ("ENTER\n");
+
+ sx *= fontwidth (p);
+ sy *= fontheight (p);
+ width *= fontwidth (p);
+ height *= fontheight (p);
+
+ col = attr_bgcol_ec (p, conp);
+ col &= 0xff;
+
+ clgen_RectFill (fb_info, (unsigned short) sx, (unsigned short) sy,
+ (unsigned short) width, (unsigned short) height,
+ col, fb_info->currentmode.line_length);
+
+ DPRINTK ("EXIT\n");
}
+#endif
-/********************************************************************/
-/* clgenfb_init() - master initialization function */
-/********************************************************************/
-__initfunc(void clgenfb_init(void))
+#ifdef FBCON_HAS_CFB16
+static void fbcon_clgen16_bmove (struct display *p, int sy, int sx,
+ int dy, int dx, int height, int width)
{
- const struct ConfigDev *cd = NULL;
- const struct ConfigDev *cd2 = NULL;
- int err;
- int btype;
- int key,key2;
- unsigned long board_addr,board_size;
-
- printk(">clgenfb_init()\n");
- printk(KERN_INFO "clgen: Driver for Cirrus Logic based graphic boards, v" CLGEN_VERSION "\n");
-
- btype = -1;
-
- if ((key = zorro_find(ZORRO_PROD_HELFRICH_SD64_RAM, 0, 0)))
- {
- key2 = zorro_find(ZORRO_PROD_HELFRICH_SD64_REG, 0, 0);
- btype = BT_SD64;
- printk(KERN_INFO "clgen: SD64 board detected; ");
- }
- else if ((key = zorro_find(ZORRO_PROD_HELFRICH_PICCOLO_RAM, 0, 0)))
- {
- key2 = zorro_find(ZORRO_PROD_HELFRICH_PICCOLO_REG, 0, 0);
- btype = BT_PICCOLO;
- printk(KERN_INFO "clgen: Piccolo board detected; ");
- }
- else if ((key = zorro_find(ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM, 0, 0)))
- {
- key2 = zorro_find(ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG, 0, 0);
- btype = BT_PICASSO;
- printk(KERN_INFO "clgen: Picasso II board detected; ");
- }
- else if ((key = zorro_find(ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM, 0, 0)))
- {
- key2 = zorro_find(ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG, 0, 0);
- btype = BT_SPECTRUM;
- printk(KERN_INFO "clgen: Spectrum board detected; ");
- }
- else if ((key = zorro_find(ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3, 0, 0)))
- {
- btype = BT_PICASSO4;
- printk(KERN_INFO "clgen: Picasso 4 board detected; ");
- }
- else
- {
- printk(KERN_NOTICE "clgen: no supported board found.\n");
- return;
- }
-
- fb_info = &boards[0]; /* FIXME support multiple boards ...*/
-
- fb_info->keyRAM = key;
- fb_info->keyREG = key2;
- fb_info->btype = btype;
-
- cd = zorro_get_board(key);
- board_addr = (unsigned long)cd->cd_BoardAddr;
- board_size = (unsigned long)cd->cd_BoardSize;
- printk(" RAM (%lu MB) at $%lx, ", board_size/0x100000, board_addr);
-
- if (btype == BT_PICASSO4)
- {
- printk(" REG at $%lx\n", board_addr + 0x600000);
-
- /* To be precise, for the P4 this is not the */
- /* begin of the board, but the begin of RAM. */
- /* for P4, map in its address space in 2 chunks (### TEST! ) */
- /* (note the ugly hardcoded 16M number) */
- fb_info->regs = ioremap(board_addr, 16777216);
- DEBUG printk(KERN_INFO "clgen: Virtual address for board set to: $%p\n", fb_info->regs);
- fb_info->regs += 0x600000;
- fb_info->fbregs_phys = board_addr + 0x600000;
-
- fb_info->fbmem_phys = board_addr + 16777216;
- fb_info->fbmem = ioremap(fb_info->fbmem_phys, 16777216);
- DEBUG printk(KERN_INFO "clgen: (RAM start set to: $%lx)\n", fb_info->fbmem);
- }
- else
- {
- cd2 = zorro_get_board(key2);
- printk(" REG at $%lx\n", (unsigned long)cd2->cd_BoardAddr);
-
- fb_info->fbmem_phys = board_addr;
- if (board_addr > 0x01000000)
- fb_info->fbmem = ioremap(board_addr, board_size);
- else
- fb_info->fbmem = ZTWO_VADDR(board_addr);
-
- /* set address for REG area of board */
- fb_info->regs = (unsigned char *)ZTWO_VADDR(cd2->cd_BoardAddr);
- fb_info->fbregs_phys = (unsigned long) cd2->cd_BoardAddr;
-
- DEBUG printk(KERN_INFO "clgen: Virtual address for board set to: $%p\n", fb_info->regs);
- DEBUG printk(KERN_INFO "clgen: (RAM start set to: $%lx)\n", fb_info->fbmem);
- }
-
- init_vgachip();
-
- /* set up a few more things, register framebuffer driver etc */
- fb_info->gen.parsize = sizeof(struct clgenfb_par);
- fb_info->gen.fbhw = &clgen_hwswitch;
- strcpy (fb_info->gen.info.modename, clgenfb_name);
- fb_info->gen.info.node = -1;
- fb_info->gen.info.fbops = &clgenfb_ops;
- fb_info->gen.info.disp = &disp;
- fb_info->gen.info.changevar = NULL;
- fb_info->gen.info.switch_con = &fbgen_switch;
- fb_info->gen.info.updatevar = &fbgen_update_var;
- fb_info->gen.info.blank = &fbgen_blank;
- fb_info->gen.info.flags = FBINFO_FLAG_DEFAULT;
-
- /* mark this board as "autoconfigured" */
- zorro_config_board(key, 0);
- if (btype != BT_PICASSO4)
- zorro_config_board(key2, 0);
-
- /* now that we know the board has been registered n' stuff, we */
- /* can finally initialize it to a default mode (640x480) */
- clgenfb_default = clgenfb_predefined[1].var;
- clgenfb_default.activate = FB_ACTIVATE_NOW;
- clgenfb_default.yres_virtual = 480*3; /* for fast scrolling (YPAN-Mode) */
- err = fbgen_do_set_var(&clgenfb_default, 1, &fb_info->gen);
-
- if (err)
- return;
+ struct clgenfb_info *fb_info = (struct clgenfb_info *) p->fb_info;
- disp.var = clgenfb_default;
- fbgen_set_disp(-1, &fb_info->gen);
- fbgen_install_cmap(0, &fb_info->gen);
+ DPRINTK ("ENTER\n");
- err = register_framebuffer(&fb_info->gen.info);
- if (err)
- {
- printk(KERN_ERR "clgen: ERROR - could not register fb device; err = %d!\n", err);
- return;
- }
+ sx *= fontwidth (p) * 2; /* 2 bytes/pixel */
+ sy *= fontheight (p);
+ dx *= fontwidth (p) * 2; /* 2 bytes/pixel */
+ dy *= fontheight (p);
+ width *= fontwidth (p) * 2; /* 2 bytes/pixel */
+ height *= fontheight (p);
+
+ clgen_BitBLT (fb_info->regs, (unsigned short) sx, (unsigned short) sy,
+ (unsigned short) dx, (unsigned short) dy,
+ (unsigned short) width, (unsigned short) height,
+ fb_info->currentmode.line_length);
- printk("<clgenfb_init()\n");
- return;
+ DPRINTK ("EXIT\n");
}
- /*
- * Cleanup
- */
+static void fbcon_clgen16_clear (struct vc_data *conp, struct display *p,
+ int sy, int sx, int height, int width)
+{
+ struct clgenfb_info *fb_info = (struct clgenfb_info *) p->fb_info;
+ unsigned short col;
+
+ DPRINTK ("ENTER\n");
+
+ sx *= fontwidth (p) * 2; /* 2 bytes/pixel */
+ sy *= fontheight (p);
+ width *= fontwidth (p) * 2; /* 2 bytes/pixel? */
+ height *= fontheight (p);
+
+ col = attr_bgcol_ec (p, conp);
+ col &= 0xff;
+
+ clgen_RectFill (fb_info, (unsigned short) sx, (unsigned short) sy,
+ (unsigned short) width, (unsigned short) height,
+ col, fb_info->currentmode.line_length);
+
+ DPRINTK ("EXIT\n");
+}
+
+#endif
-void clgenfb_cleanup(struct clgenfb_info *info)
+#ifdef FBCON_HAS_CFB32
+static void fbcon_clgen32_bmove (struct display *p, int sy, int sx,
+ int dy, int dx, int height, int width)
+{
+ struct clgenfb_info *fb_info = (struct clgenfb_info *) p->fb_info;
+
+ DPRINTK ("ENTER\n");
+
+ sx *= fontwidth (p) * 4; /* 4 bytes/pixel */
+ sy *= fontheight (p);
+ dx *= fontwidth (p) * 4; /* 4 bytes/pixel */
+ dy *= fontheight (p);
+ width *= fontwidth (p) * 4; /* 4 bytes/pixel */
+ height *= fontheight (p);
+
+ clgen_BitBLT (fb_info->regs, (unsigned short) sx, (unsigned short) sy,
+ (unsigned short) dx, (unsigned short) dy,
+ (unsigned short) width, (unsigned short) height,
+ fb_info->currentmode.line_length);
+
+ DPRINTK ("EXIT\n");
+}
+
+static void fbcon_clgen32_clear (struct vc_data *conp, struct display *p,
+ int sy, int sx, int height, int width)
{
- printk(">clgenfb_cleanup()\n");
+ struct clgenfb_info *fb_info = (struct clgenfb_info *) p->fb_info;
+
+ unsigned short col;
- fb_info = info;
+ DPRINTK ("ENTER\n");
- switch_monitor(0);
+ sx *= fontwidth (p) * 4; /* 4 bytes/pixel */
+ sy *= fontheight (p);
+ width *= fontwidth (p) * 4; /* 4 bytes/pixel? */
+ height *= fontheight (p);
- zorro_unconfig_board(info->keyRAM, 0);
- if (fb_info->btype != BT_PICASSO4)
- zorro_unconfig_board(info->keyREG, 0);
+ col = attr_bgcol_ec (p, conp);
+ col &= 0xff;
- unregister_framebuffer(&info->gen.info);
- printk("Framebuffer unregistered\n");
- printk("<clgenfb_cleanup()\n");
+ clgen_RectFill (fb_info, (unsigned short) sx, (unsigned short) sy,
+ (unsigned short) width, (unsigned short) height,
+ col, fb_info->currentmode.line_length);
+
+ DPRINTK ("EXIT\n");
}
+#endif /* FBCON_HAS_CFB32 */
+
+
-/* A strtok which returns empty strings, too */
-static char *strtoke(char *s,const char *ct)
+
+#ifdef CONFIG_PREP
+#define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000)
+#define PREP_IO_BASE ((volatile unsigned char *) 0x80000000)
+static void __init get_prep_addrs (unsigned long *display, unsigned long *registers)
{
- char *sbegin, *send;
- static char *ssave = NULL;
-
- sbegin = s ? s : ssave;
- if (!sbegin)
- return NULL;
- if (*sbegin == '\0') {
- ssave = NULL;
- return NULL;
- }
- send = strpbrk(sbegin, ct);
- if (send && *send != '\0')
- *send++ = '\0';
- ssave = send;
- return sbegin;
+ DPRINTK ("ENTER\n");
+
+ *display = PREP_VIDEO_BASE;
+ *registers = (unsigned long) PREP_IO_BASE;
+
+ DPRINTK ("EXIT\n");
}
-/*****************************************************************/
-/* clgenfb_setup() might be used later for parsing possible */
-/* arguments to the video= bootstrap parameter. Right now, there */
-/* is nothing I do here. */
-/*****************************************************************/
-__initfunc(void clgenfb_setup(char *options, int *ints))
+#endif /* CONFIG_PREP */
+
+
+
+
+#ifdef CONFIG_FB_OF
+static void __init get_of_addrs (const struct device_node *dp,
+ unsigned long *display, unsigned long *registers)
{
-// char *this_opt;
+ int i;
+
+ DPRINTK ("ENTER\n");
+
+ /* Map in frame buffer and registers */
+ for (i = 0; i < dp->n_addrs; ++i) {
+ unsigned long addr = dp->addrs[i].address;
+ unsigned long size = dp->addrs[i].size;
+ printk ("dp->addrs[%d].address = $lx, dp->addrs[%d].size = %lx\n",
+ i, addr, i, size);
+ if (size >= 0x800000) {
+ *display = addr;
+ } else {
+ *registers = addr;
+ }
+ }
-// printk("clgenfb_setup(): options: %s\n", options);
+ DPRINTK ("EXIT\n");
}
+#endif /* CONFIG_FB_OF */
- /*
- * Modularization
- */
-#ifdef MODULE
-int init_module(void)
+
+#ifdef CONFIG_PCI
+/* Pulled the logic from XFree86 Cirrus driver to get the memory size,
+ * based on the DRAM bandwidth bit and DRAM bank switching bit. This
+ * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
+ * seem to have. */
+static unsigned int __init clgen_get_memsize (caddr_t regbase)
{
- printk("init_module()\n");
- clgenfb_init();
- return 0;
+ unsigned long mem = 1 * MB_;
+ unsigned char SRF;
+
+ DPRINTK ("ENTER\n");
+
+ SRF = vga_rseq (regbase, CL_SEQRF);
+ if ((SRF & 0x18) == 0x18) {
+ /* 64-bit DRAM data bus width; assume 2MB. Also indicates 2MB memory
+ * on the 5430. */
+ mem *= 2;
+ }
+ if (SRF & 0x80) {
+ /* If DRAM bank switching is enabled, there must be twice as much
+ * memory installed. (4MB on the 5434) */
+ mem *= 2;
+ }
+ return mem;
+
+ DPRINTK ("EXIT\n");
}
-void cleanup_module(void)
+
+
+static struct pci_dev * __init clgen_pci_dev_get (clgen_board_t *btype)
{
- printk("module_cleanup()\n");
- clgenfb_cleanup(fb_info);
+ struct pci_dev *pdev = NULL;
+ int i;
+
+ DPRINTK ("ENTER\n");
+
+ for (i = 0; i < arraysize(clgen_pci_probe_list) && !pdev; i++)
+ pdev = pci_find_device (PCI_VENDOR_ID_CIRRUS,
+ clgen_pci_probe_list[i].device, NULL);
+
+ if (pdev)
+ *btype = clgen_pci_probe_list[i - 1].btype;
+
+ DPRINTK ("EXIT, returning %p\n", pdev);
+ return pdev;
}
-#endif /* MODULE */
-/**********************************************************************/
-/* about the following functions - I have used the same names for the */
-/* functions as Markus Wild did in his Retina driver for NetBSD as */
-/* they just made sense for this purpose. Apart from that, I wrote */
-/* these functions myself. */
-/**********************************************************************/
-/*** WGen() - write into one of the external/general registers ***/
-void WGen(int regnum, unsigned char val)
+static void __init get_pci_addrs (const struct pci_dev *pdev,
+ unsigned long *display, unsigned long *registers)
{
- unsigned volatile char *reg = fb_info->regs + regnum;
+ assert (pdev != NULL);
+ assert (display != NULL);
+ assert (registers != NULL);
- if(fb_info->btype == BT_PICASSO)
- {
- /* Picasso II specific hack */
-/* if (regnum == M_3C7_W || regnum == M_3C9 || regnum == VSSM2) */
- if (regnum == M_3C7_W || regnum == M_3C9)
- reg += 0xfff;
+ DPRINTK ("ENTER\n");
+
+ *display = 0;
+ *registers = 0;
+
+ /* This is a best-guess for now */
+
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13)
+
+ *display = pdev->base_address[0];
+ if ((*display & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_IO) {
+ *registers = *display;
+ *display = pdev->base_address[1];
+ } else {
+ *registers = pdev->base_address[1];
}
- *reg = val;
+#else
+
+ if (pdev->resource[0].flags & IORESOURCE_IO) {
+ *display = pdev->resource[1].start;
+ *registers = pdev->resource[0].start;
+ } else {
+ *display = pdev->resource[0].start;
+ *registers = pdev->resource[1].start;
+ }
+
+#endif /* kernel older than 2.3.13 */
+
+ assert (*display != 0);
+
+ DPRINTK ("EXIT\n");
}
-/*** RGen() - read out one of the external/general registers ***/
-unsigned char RGen(int regnum)
+
+
+
+/* clgen_pci_unmap only used in modules */
+#ifdef MODULE
+static void clgen_pci_unmap (struct clgenfb_info *info)
{
- unsigned volatile char *reg = fb_info->regs + regnum;
+ iounmap (info->fbmem);
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,13)
+ __release_region (&iomem_resource, info->fbmem_phys, info->size);
+ __release_region (&iomem_resource, 0xA0000, 65535);
+ if (release_io_ports)
+ __release_region (&ioport_resource, 0x3C0, 32);
+#endif
+}
+#endif /* MODULE */
+
+
+static int __init clgen_pci_setup (struct clgenfb_info *info,
+ clgen_board_t *btype)
+{
+#ifdef CONFIG_FB_OF
+ struct device_node *dp;
+#endif /* CONFIG_FB_OF */
+ struct pci_dev *pdev;
+ unsigned long board_addr, board_size;
+ u16 tmp16;
+
+ DPRINTK ("ENTER\n");
+
+ pdev = clgen_pci_dev_get (btype);
+ if (!pdev) {
+ printk (KERN_ERR " Couldn't find PCI device\n");
+ DPRINTK ("EXIT, returning 1\n");
+ return 1;
+ }
+ DPRINTK (" Found PCI device, base address 0 is 0x%lx, btype set to %d\n",
+ pdev->resource[0].start, *btype);
+ DPRINTK (" base address 1 is 0x%lx\n", pdev->resource[1].start);
+
+ info->pdev = pdev;
- if(fb_info->btype == BT_PICASSO)
+#ifdef CONFIG_PREP
+ /* Xbh does this, though 0 seems to be the init value */
+ pcibios_write_config_dword (0, pdev->devfn, PCI_BASE_ADDRESS_0, 0x00000000);
+#endif
+
+ pci_read_config_word (pdev, PCI_COMMAND, &tmp16);
+ if (!(tmp16 & (PCI_COMMAND_MEMORY | PCI_COMMAND_IO))) {
+ u16 tmp16_o = tmp16 | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
+ pci_write_config_word (pdev, PCI_COMMAND, tmp16_o);
+ }
+
+#ifdef CONFIG_FB_OF
+ /* Ok, so its an ugly hack, since we could have passed it down from
+ * clgen_of_init() if we'd done it right. */
+ DPRINTK ("Attempt to get OF info for MacPicasso\n");
+ dp = find_devices ("MacPicasso");
+ if (dp != 0) {
+ if (dp->n_addrs != 2) {
+ printk (KERN_ERR "expecting 2 address for clgen (got %d)\n", dp->n_addrs);
+ DPRINTK ("EXIT, returning 1\n");
+ return 1;
+ }
+ get_of_addrs (dp, &board_addr, &info->fbregs_phys);
+ } else
+#endif
{
- /* Picasso II specific hack */
-/* if (regnum == M_3C7_W || regnum == M_3C9 || regnum == VSSM2) */
- if (regnum == M_3C7_W || regnum == M_3C9)
- reg += 0xfff;
+
+#ifdef CONFIG_PREP
+ get_prep_addrs (&board_addr, &info->fbregs_phys);
+#else /* CONFIG_PREP */
+ DPRINTK ("Attempt to get PCI info for Cirrus Graphics Card\n");
+ get_pci_addrs (pdev, &board_addr, &info->fbregs_phys);
+#endif /* CONFIG_PREP */
+ }
+
+ DPRINTK ("Board address: 0x%lx, register address: 0x%lx\n", board_addr, info->fbregs_phys);
+
+#ifdef CONFIG_PREP
+ /* PReP dies if we ioremap the IO registers, but it works w/out... */
+ info->regs = (char *) info->fbregs_phys;
+#else
+ info->regs = 0; /* FIXME: this forces VGA. alternatives? */
+#endif
+
+ if (*btype == BT_GD5480) {
+ board_size = 32 * MB_;
+ } else {
+ board_size = clgen_get_memsize (info->regs);
+ }
+
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,13)
+
+ if (!__request_region (&iomem_resource, board_addr,
+ board_size, "clgenfb")) {
+ pci_write_config_word (pdev, PCI_COMMAND, tmp16);
+ printk(KERN_ERR "clgen: cannot reserve region 0x%lu, abort\n",
+ board_addr);
+ return -1;
}
+ if (!__request_region (&iomem_resource, 0xA0000, 65535, "clgenfb")) {
+ pci_write_config_word (pdev, PCI_COMMAND, tmp16);
+ printk(KERN_ERR "clgen: cannot reserve region 0x%lu, abort\n",
+ 0xA0000L);
+ __release_region(&iomem_resource, board_addr, board_size);
+ return -1;
+ }
+ if (__request_region(&ioport_resource, 0x3C0, 32, "clgenfb"))
+ release_io_ports = 1;
+
+#endif /* kernel > 2.3.13 */
+
+ info->fbmem = ioremap (board_addr, board_size);
+ info->fbmem_phys = board_addr;
+ info->size = board_size;
- return *reg;
+ printk (" RAM (%lu MB) at 0x%lx, ", info->size / MB_, board_addr);
+
+ printk (KERN_INFO "Cirrus Logic chipset on PCI bus\n");
+
+ DPRINTK ("EXIT, returning 0\n");
+ return 0;
}
+#endif /* CONFIG_PCI */
+
+
+
+
+#ifdef CONFIG_ZORRO
+static int __init clgen_zorro_find (int *key_o, int *key2_o, clgen_board_t *btype)
+{
+ int i, key = 0;
+
+ assert (key_o != NULL);
+ assert (btype != NULL);
+
+ for (i = 0; i < arraysize(clgen_zorro_probe_list) && !key; i++)
+ key = zorro_find (clgen_zorro_probe_list[i].key, 0, 0);
+
+ if (key) {
+ *key_o = key;
+ if (clgen_zorro_probe_list[i].key2)
+ *key2_o = zorro_find (clgen_zorro_probe_list[i].key2, 0, 0);
+ else
+ *key2_o = 0;
+ *btype = clgen_zorro_probe_list[i - 1].btype;
+
+ printk (KERN_INFO "clgen: %s board detected; ",
+ clgen_board_info[*btype].name);
+
+ return 0;
+ }
+
+ printk (KERN_NOTICE "clgen: no supported board found.\n");
+ return -1;
+}
+
+
+
+/* clgen_zorro_unmap only used in modules */
+#ifdef MODULE
+static void clgen_zorro_unmap (struct clgenfb_info *info)
+{
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,13)
+ __release_region(&iomem_resource, info->board_addr, info->board_size);
+#endif
+ if (info->btype == BT_PICASSO4) {
+ iounmap (info->board_addr);
+ iounmap (info->fbmem_phys);
+ } else {
+ if (info->board_addr > 0x01000000)
+ iounmap (info->board_addr);
+ }
+}
+#endif /* MODULE */
+
+
+
+static int __init clgen_zorro_setup (struct clgenfb_info *info,
+ clgen_board_t *btype)
+{
+ int key = 0, key2 = 0;
+ const struct ConfigDev *cd = NULL;
+ const struct ConfigDev *cd2 = NULL;
+ unsigned long board_addr, board_size;
+
+ assert (info != NULL);
+ assert (btype != NULL);
+
+ if (clgen_zorro_find (&key, &key2, btype))
+ return -1;
+
+ assert (key > 0);
+ assert (key2 >= 0);
+ assert (*btype != BT_NONE);
+
+ info->keyRAM = key;
+ info->keyREG = key2;
+ cd = zorro_get_board (key);
+ info->board_addr = board_addr = (unsigned long) cd->cd_BoardAddr;
+ info->board_size = board_size = (unsigned long) cd->cd_BoardSize;
+
+ if (!__request_region(&iomem_resource, board_addr,
+ board_size, "clgenfb")) {
+ printk(KERN_ERR "clgen: cannot reserve region 0x%lu, abort\n",
+ board_addr);
+ return -1;
+ }
+
+ printk (" RAM (%lu MB) at $%lx, ", board_size / MB_, board_addr);
+
+ if (*btype == BT_PICASSO4) {
+ printk (" REG at $%lx\n", board_addr + 0x600000);
+
+ /* To be precise, for the P4 this is not the */
+ /* begin of the board, but the begin of RAM. */
+ /* for P4, map in its address space in 2 chunks (### TEST! ) */
+ /* (note the ugly hardcoded 16M number) */
+ info->regs = ioremap (board_addr, 16777216);
+ DPRINTK ("clgen: Virtual address for board set to: $%p\n", info->regs);
+ info->regs += 0x600000;
+ info->fbregs_phys = board_addr + 0x600000;
+
+ info->fbmem_phys = board_addr + 16777216;
+ info->fbmem = ioremap (info->fbmem_phys, 16777216);
+ } else {
+ cd2 = zorro_get_board (key2);
+ printk (" REG at $%lx\n", (unsigned long) cd2->cd_BoardAddr);
+
+ info->fbmem_phys = board_addr;
+ if (board_addr > 0x01000000)
+ info->fbmem = ioremap (board_addr, board_size);
+ else
+ info->fbmem = (caddr_t) ZTWO_VADDR (board_addr);
+
+ /* set address for REG area of board */
+ info->regs = (caddr_t) ZTWO_VADDR (cd2->cd_BoardAddr);
+ info->fbregs_phys = (unsigned long) cd2->cd_BoardAddr;
+
+ DPRINTK ("clgen: Virtual address for board set to: $%p\n", info->regs);
+ }
+
+ /* mark this board as "autoconfigured" */
+ zorro_config_board (key, 0);
+ if (*btype != BT_PICASSO4)
+ zorro_config_board (key2, 0);
+
+ printk (KERN_INFO "Cirrus Logic chipset on Zorro bus\n");
+
+ return 0;
+}
+#endif /* CONFIG_ZORRO */
+
-/*** WSeq() - write into a register of the sequencer ***/
-void WSeq(unsigned char regnum, unsigned char val)
+
+/********************************************************************/
+/* clgenfb_init() - master initialization function */
+/********************************************************************/
+int __init clgenfb_init(void)
{
- fb_info->regs[SEQRX] = regnum;
- fb_info->regs[SEQRX+1] = val;
+ int err, j, k;
+
+ clgen_board_t btype = BT_NONE;
+ struct clgenfb_info *fb_info = NULL;
+
+ DPRINTK ("ENTER\n");
+
+ printk (KERN_INFO "clgen: Driver for Cirrus Logic based graphic boards, v" CLGEN_VERSION "\n");
+
+ fb_info = &boards[0]; /* FIXME support multiple boards ... */
+
+#ifdef CONFIG_PCI
+ if (clgen_pci_setup (fb_info, &btype)) { /* Also does OF setup */
+ DPRINTK ("EXIT, returning -ENXIO\n");
+ return -ENXIO;
+ }
+
+#elif CONFIG_ZORRO
+ if (clgen_zorro_setup (fb_info, &btype)) {
+ DPRINTK ("EXIT, returning -ENXIO\n");
+ return -ENXIO;
+ }
+
+#else
+#error Unsupported bus. Supported: PCI, Zorro
+#endif /* !CONFIG_PCI, !CONFIG_ZORRO */
+
+ /* sanity checks */
+ assert (btype != BT_NONE);
+ assert (btype == clgen_board_info[btype].btype);
+
+ fb_info->btype = btype;
+
+ DPRINTK ("clgen: (RAM start set to: 0x%p)\n", fb_info->fbmem);
+
+ init_vgachip (fb_info);
+
+ /* set up a few more things, register framebuffer driver etc */
+ fb_info->gen.parsize = sizeof (struct clgenfb_par);
+ fb_info->gen.fbhw = &clgen_hwswitch;
+
+ strncpy (fb_info->gen.info.modename, clgen_board_info[btype].name,
+ sizeof (fb_info->gen.info.modename));
+ fb_info->gen.info.modename [sizeof (fb_info->gen.info.modename) - 1] = 0;
+
+ fb_info->gen.info.node = -1;
+ fb_info->gen.info.fbops = &clgenfb_ops;
+ fb_info->gen.info.disp = &disp;
+ fb_info->gen.info.changevar = NULL;
+ fb_info->gen.info.switch_con = &fbgen_switch;
+ fb_info->gen.info.updatevar = &fbgen_update_var;
+ fb_info->gen.info.blank = &fbgen_blank;
+ fb_info->gen.info.flags = FBINFO_FLAG_DEFAULT;
+
+ for (j = 0; j < 256; j++) {
+ if (j < 16) {
+ k = color_table[j];
+ fb_info->palette[j].red = default_red[k];
+ fb_info->palette[j].green = default_grn[k];
+ fb_info->palette[j].blue = default_blu[k];
+ } else {
+ fb_info->palette[j].red =
+ fb_info->palette[j].green =
+ fb_info->palette[j].blue = j;
+ }
+ }
+
+ /* now that we know the board has been registered n' stuff, we */
+ /* can finally initialize it to a default mode */
+ clgenfb_default = clgenfb_predefined[clgen_def_mode].var;
+ clgenfb_default.activate = FB_ACTIVATE_NOW;
+ clgenfb_default.yres_virtual = 480 * 3; /* for fast scrolling (YPAN-Mode) */
+ err = fbgen_do_set_var (&clgenfb_default, 1, &fb_info->gen);
+
+ if (err) {
+ DPRINTK ("EXIT, returning -EINVAL\n");
+ return -EINVAL;
+ }
+
+ disp.var = clgenfb_default;
+ fbgen_set_disp (-1, &fb_info->gen);
+ fbgen_install_cmap (0, &fb_info->gen);
+
+ err = register_framebuffer (&fb_info->gen.info);
+ if (err) {
+ printk (KERN_ERR "clgen: ERROR - could not register fb device; err = %d!\n", err);
+ DPRINTK ("EXIT, returning -EINVAL\n");
+ return -EINVAL;
+ }
+ DPRINTK ("EXIT, returning 0\n");
+ return 0;
}
-/*** RSeq() - read out one of the Sequencer registers ***/
-unsigned char RSeq(unsigned char regnum)
+
+
+#if defined(CONFIG_FB_OF)
+int __init clgen_of_init (struct device_node *dp)
{
- fb_info->regs[SEQRX] = regnum;
- return fb_info->regs[SEQRX+1];
+ int rc;
+
+ DPRINTK ("ENTER\n");
+
+ rc = clgenfb_init ();
+
+ DPRINTK ("EXIT, returning %d\n", rc);
+
+ return rc;
}
+#endif /* CONFIG_FB_OF */
+
+
-/*** WCrt() - write into a register of the CRT controller ***/
-void WCrt(unsigned char regnum, unsigned char val)
+ /*
+ * Cleanup (only needed for module)
+ */
+#ifdef MODULE
+static void clgenfb_cleanup (struct clgenfb_info *info)
{
- fb_info->regs[CRTX] = regnum;
- fb_info->regs[CRTX+1] = val;
+ DPRINTK ("ENTER\n");
+
+#ifdef CONFIG_ZORRO
+ switch_monitor (info, 0);
+
+ clgen_zorro_unmap (info);
+
+ zorro_unconfig_board (info->keyRAM, 0);
+ if (info->btype != BT_PICASSO4)
+ zorro_unconfig_board (info->keyREG, 0);
+#else
+ clgen_pci_unmap (info);
+#endif /* CONFIG_ZORRO */
+
+ unregister_framebuffer ((struct fb_info *) info);
+ printk ("Framebuffer unregistered\n");
+
+ DPRINTK ("EXIT\n");
+}
+#endif
+
+
+
+
+#ifndef MODULE
+int __init clgenfb_setup(char *options) {
+ char *this_opt, s[32];
+ int i;
+
+ DPRINTK ("ENTER\n");
+
+ if (!options || !*options)
+ return 0;
+
+ for (this_opt = strtok (options, ","); this_opt != NULL;
+ this_opt = strtok (NULL, ",")) {
+ if (!*this_opt) continue;
+
+ DPRINTK("clgenfb_setup: option '%s'\n", this_opt);
+
+ for (i = 0; i < NUM_TOTAL_MODES; i++) {
+ sprintf (s, "mode:%s", clgenfb_predefined[i].name);
+ if (strcmp (this_opt, s) == 0)
+ clgen_def_mode = i;
+ }
+ }
+ return 0;
}
+#endif
+
-/*** RCrt() - read out one of the CRT controller registers ***/
-unsigned char RCrt(unsigned char regnum)
+
+
+
+ /*
+ * Modularization
+ */
+
+#ifdef MODULE
+MODULE_AUTHOR("Copyright 1999 Jeff Garzik <jgarzik@pobox.com>");
+MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
+
+int init_module (void)
{
- fb_info->regs[CRTX] = regnum;
- return fb_info->regs[CRTX+1];
+#if defined(CONFIG_FB_OF)
+/* Nothing to do, must be called from offb */
+ return 0;
+#else
+ int i;
+
+ DPRINTK ("ENTER\n");
+ i = clgenfb_init ();
+ DPRINTK ("EXIT\n");
+ return i;
+#endif
}
-/*** WGfx() - write into a register of the Gfx controller ***/
-void WGfx(unsigned char regnum, unsigned char val)
+void cleanup_module (void)
{
- fb_info->regs[GRX] = regnum;
- fb_info->regs[GRX+1] = val;
+ DPRINTK ("ENTER\n");
+
+ clgenfb_cleanup (&boards[0]); /* FIXME: support multiple boards */
+
+ DPRINTK ("EXIT\n");
}
-/*** RGfx() - read out one of the Gfx controller registers ***/
-unsigned char RGfx(unsigned char regnum)
+#endif /* MODULE */
+
+
+/**********************************************************************/
+/* about the following functions - I have used the same names for the */
+/* functions as Markus Wild did in his Retina driver for NetBSD as */
+/* they just made sense for this purpose. Apart from that, I wrote */
+/* these functions myself. */
+/**********************************************************************/
+
+/*** WGen() - write into one of the external/general registers ***/
+static void WGen (const struct clgenfb_info *fb_info,
+ int regnum, unsigned char val)
{
- fb_info->regs[GRX] = regnum;
- return fb_info->regs[GRX+1];
+ unsigned long regofs = 0;
+
+ if (fb_info->btype == BT_PICASSO) {
+ /* Picasso II specific hack */
+/* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D || regnum == CL_VSSM2) */
+ if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
+ regofs = 0xfff;
+ }
+
+ vga_w (fb_info->regs, regofs + regnum, val);
}
-/*** WAttr() - write into a register of the Attribute controller ***/
-void WAttr(unsigned char regnum, unsigned char val)
+/*** RGen() - read out one of the external/general registers ***/
+static unsigned char RGen (const struct clgenfb_info *fb_info, int regnum)
{
- /* if the next access to the attribute controller is a data write access, */
- /* simply write back the information that was already there before, so that */
- /* the next write access after that will be an index write. */
- if (RCrt(CRT24) & 0x80)
- /* can't use WAttr() here - we would go into a recursive loop otherwise */
- fb_info->regs[ARX] = fb_info->regs[ARX+1];
-
- if (RCrt(CRT24) & 0x80)
- printk(KERN_WARNING "clgen: *** AttrIdx BAD!***\n");
-
- /* now, first set index and after that the value - both to the same address (!) */
- fb_info->regs[ARX] = regnum;
- fb_info->regs[ARX] = val;
+ unsigned long regofs = 0;
+
+ if (fb_info->btype == BT_PICASSO) {
+ /* Picasso II specific hack */
+/* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D || regnum == CL_VSSM2) */
+ if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
+ regofs = 0xfff;
+ }
+
+ return vga_r (fb_info->regs, regofs + regnum);
}
/*** AttrOn() - turn on VideoEnable for Attribute controller ***/
-void AttrOn()
+static void AttrOn (const struct clgenfb_info *fb_info)
{
- if (RCrt(CRT24) & 0x80)
+ assert (fb_info != NULL);
+
+ DPRINTK ("ENTER\n");
+
+ if (vga_rcrt (fb_info->regs, CL_CRT24) & 0x80) {
/* if we're just in "write value" mode, write back the */
/* same value as before to not modify anything */
- fb_info->regs[ARX] = fb_info->regs[ARX+1];
-
+ vga_w (fb_info->regs, VGA_ATT_IW,
+ vga_r (fb_info->regs, VGA_ATT_R));
+ }
/* turn on video bit */
-/* fb_info->regs[ARX] = 0x20; */
- fb_info->regs[ARX] = 0x33;
+/* vga_w (fb_info->regs, VGA_ATT_IW, 0x20); */
+ vga_w (fb_info->regs, VGA_ATT_IW, 0x33);
/* dummy write on Reg0 to be on "write index" mode next time */
- fb_info->regs[ARX] = 0x00;
-}
-
-/*** RAttr() - read out a register of the Attribute controller ***/
-unsigned char RAttr(unsigned char regnum)
-{
- /* (explanation see above in WAttr() ) */
- if (RCrt(CRT24) & 0x80)
- fb_info->regs[ARX] = fb_info->regs[ARX+1];
+ vga_w (fb_info->regs, VGA_ATT_IW, 0x00);
- fb_info->regs[ARX] = regnum;
- return fb_info->regs[ARX+1];
+ DPRINTK ("EXIT\n");
}
-
/*** WHDR() - write into the Hidden DAC register ***/
/* as the HDR is the only extension register that requires special treatment
* (the other extension registers are accessible just like the "ordinary"
* registers of their functional group) here is a specialized routine for
* accessing the HDR
*/
-void WHDR(unsigned char val)
+static void WHDR (const struct clgenfb_info *fb_info, unsigned char val)
{
unsigned char dummy;
- if(fb_info->btype == BT_PICASSO)
- {
+ if (fb_info->btype == BT_PICASSO) {
/* Klaus' hint for correct access to HDR on some boards */
/* first write 0 to pixel mask (3c6) */
- WGen(M_3C6, 0x00); udelay(200);
+ WGen (fb_info, VGA_PEL_MSK, 0x00);
+ udelay (200);
/* next read dummy from pixel address (3c8) */
- dummy = RGen(M_3C8); udelay(200);
+ dummy = RGen (fb_info, VGA_PEL_IW);
+ udelay (200);
}
-
/* now do the usual stuff to access the HDR */
- dummy = RGen(M_3C6); udelay(200);
- dummy = RGen(M_3C6); udelay(200);
- dummy = RGen(M_3C6); udelay(200);
- dummy = RGen(M_3C6); udelay(200);
+ dummy = RGen (fb_info, VGA_PEL_MSK);
+ udelay (200);
+ dummy = RGen (fb_info, VGA_PEL_MSK);
+ udelay (200);
+ dummy = RGen (fb_info, VGA_PEL_MSK);
+ udelay (200);
+ dummy = RGen (fb_info, VGA_PEL_MSK);
+ udelay (200);
- WGen(M_3C6, val); udelay(200);
+ WGen (fb_info, VGA_PEL_MSK, val);
+ udelay (200);
- if(fb_info->btype == BT_PICASSO)
- {
+ if (fb_info->btype == BT_PICASSO) {
/* now first reset HDR access counter */
- dummy = RGen(M_3C8); udelay(200);
+ dummy = RGen (fb_info, VGA_PEL_IW);
+ udelay (200);
/* and at the end, restore the mask value */
/* ## is this mask always 0xff? */
- WGen(M_3C6, 0xff); udelay(200);
+ WGen (fb_info, VGA_PEL_MSK, 0xff);
+ udelay (200);
}
}
-/*** RHDR() - read out the Hidden DAC register ***/
-/* I hope this does not break on the GD5428 - cannot test it. */
-/* (Is there any board for the Amiga that uses the 5428 ?) */
-unsigned char RHDR()
-{
- unsigned char dummy;
-
- dummy = RGen(M_3C6);
- dummy = RGen(M_3C6);
- dummy = RGen(M_3C6);
- dummy = RGen(M_3C6);
-
- return RGen(M_3C6);
-}
/*** WSFR() - write to the "special function register" (SFR) ***/
-void WSFR(unsigned char val)
+static void WSFR (struct clgenfb_info *fb_info, unsigned char val)
{
- fb_info->SFR = val;
- fb_info->regs[0x8000] = val;
+#ifdef CONFIG_ZORRO
+ assert (fb_info->regs != NULL);
+ fb_info->SFR = val;
+ writeb (val, fb_info->regs + 0x8000);
+#endif
}
/* The Picasso has a second register for switching the monitor bit */
-void WSFR2(unsigned char val)
+static void WSFR2 (struct clgenfb_info *fb_info, unsigned char val)
{
+#ifdef CONFIG_ZORRO
/* writing an arbitrary value to this one causes the monitor switcher */
/* to flip to Amiga display */
- fb_info->SFR = val;
- fb_info->regs[0x9000] = val;
+ assert (fb_info->regs != NULL);
+ fb_info->SFR = val;
+ writeb (val, fb_info->regs + 0x9000);
+#endif
}
+
/*** WClut - set CLUT entry (range: 0..63) ***/
-void WClut(unsigned char regnum, unsigned char red, unsigned char green, unsigned char blue)
+static void WClut (struct clgenfb_info *fb_info, unsigned char regnum, unsigned char red,
+ unsigned char green, unsigned char blue)
{
- unsigned int data = 0x3c9;
+ unsigned int data = VGA_PEL_D;
/* address write mode register is not translated.. */
- fb_info->regs[0x3c8] = regnum;
+ vga_w (fb_info->regs, VGA_PEL_IW, regnum);
- if(fb_info->btype == BT_PICASSO || fb_info->btype == BT_PICASSO4)
- {
+ if (fb_info->btype == BT_PICASSO || fb_info->btype == BT_PICASSO4 ||
+ fb_info->btype == BT_ALPINE || fb_info->btype == BT_GD5480) {
/* but DAC data register IS, at least for Picasso II */
- if(fb_info->btype == BT_PICASSO)
+ if (fb_info->btype == BT_PICASSO)
data += 0xfff;
- fb_info->regs[data] = red;
- fb_info->regs[data] = green;
- fb_info->regs[data] = blue;
- }
- else
- {
- fb_info->regs[data] = blue;
- fb_info->regs[data] = green;
- fb_info->regs[data] = red;
+ vga_w (fb_info->regs, data, red);
+ vga_w (fb_info->regs, data, green);
+ vga_w (fb_info->regs, data, blue);
+ } else {
+ vga_w (fb_info->regs, data, blue);
+ vga_w (fb_info->regs, data, green);
+ vga_w (fb_info->regs, data, red);
}
}
+
+
+#if 0
/*** RClut - read CLUT entry (range 0..63) ***/
-void RClut(unsigned char regnum, unsigned char *red, unsigned char *green, unsigned char *blue)
+static void RClut (struct clgenfb_info *fb_info, unsigned char regnum, unsigned char *red,
+ unsigned char *green, unsigned char *blue)
{
- unsigned int data = 0x3c9;
+ unsigned int data = VGA_PEL_D;
- fb_info->regs[0x3c7] = regnum;
+ vga_w (fb_info->regs, VGA_PEL_IR, regnum);
- if(fb_info->btype == BT_PICASSO || fb_info->btype == BT_PICASSO4)
- {
- if(fb_info->btype == BT_PICASSO)
+ if (fb_info->btype == BT_PICASSO || fb_info->btype == BT_PICASSO4 ||
+ fb_info->btype == BT_ALPINE || fb_info->btype == BT_GD5480) {
+ if (fb_info->btype == BT_PICASSO)
data += 0xfff;
- *red = fb_info->regs[data];
- *green = fb_info->regs[data];
- *blue = fb_info->regs[data];
- }
- else
- {
- *blue = fb_info->regs[data];
- *green = fb_info->regs[data];
- *red = fb_info->regs[data];
+ *red = vga_r (fb_info->regs, data);
+ *green = vga_r (fb_info->regs, data);
+ *blue = vga_r (fb_info->regs, data);
+ } else {
+ *blue = vga_r (fb_info->regs, data);
+ *green = vga_r (fb_info->regs, data);
+ *red = vga_r (fb_info->regs, data);
}
}
+#endif
/*******************************************************************
@@ -1937,11 +3241,12 @@ void RClut(unsigned char regnum, unsigned char *red, unsigned char *green, unsig
Wait for the BitBLT engine to complete a possible earlier job
*********************************************************************/
-void clgen_WaitBLT()
+/* FIXME: use interrupts instead */
+extern inline void clgen_WaitBLT (caddr_t regbase)
{
/* now busy-wait until we're done */
- while (RGfx(GR31) & 0x08)
- ;
+ while (vga_rgfx (regbase, CL_GR31) & 0x08)
+ /* do nothing */ ;
}
/*******************************************************************
@@ -1950,90 +3255,87 @@ void clgen_WaitBLT()
perform accelerated "scrolling"
********************************************************************/
-void clgen_BitBLT (u_short curx, u_short cury, u_short destx, u_short desty,
- u_short width, u_short height, u_short line_length)
+static void clgen_BitBLT (caddr_t regbase, u_short curx, u_short cury, u_short destx, u_short desty,
+ u_short width, u_short height, u_short line_length)
{
u_short nwidth, nheight;
u_long nsrc, ndest;
u_char bltmode;
+ DPRINTK ("ENTER\n");
+
nwidth = width - 1;
nheight = height - 1;
bltmode = 0x00;
/* if source adr < dest addr, do the Blt backwards */
- if (cury <= desty)
- {
- if (cury == desty)
- {
+ if (cury <= desty) {
+ if (cury == desty) {
/* if src and dest are on the same line, check x */
if (curx < destx)
bltmode |= 0x01;
- }
- else
+ } else
bltmode |= 0x01;
}
-
- if (!bltmode)
- {
+ if (!bltmode) {
/* standard case: forward blitting */
nsrc = (cury * line_length) + curx;
ndest = (desty * line_length) + destx;
- }
- else
- {
+ } else {
/* this means start addresses are at the end, counting backwards */
nsrc = cury * line_length + curx + nheight * line_length + nwidth;
ndest = desty * line_length + destx + nheight * line_length + nwidth;
}
-// clgen_WaitBLT(); /* ### NOT OK for multiple boards! */
+ clgen_WaitBLT(regbase);
/*
- run-down of registers to be programmed:
- destination pitch
- source pitch
- BLT width/height
- source start
- destination start
- BLT mode
- BLT ROP
- GR0 / GR1: "fill color"
- start/stop
- */
+ run-down of registers to be programmed:
+ destination pitch
+ source pitch
+ BLT width/height
+ source start
+ destination start
+ BLT mode
+ BLT ROP
+ VGA_GFX_SR_VALUE / VGA_GFX_SR_ENABLE: "fill color"
+ start/stop
+ */
/* pitch: set to line_length */
- WGfx(GR24, line_length & 0xff); /* dest pitch low */
- WGfx(GR25, (line_length >> 8)); /* dest pitch hi */
- WGfx(GR26, line_length & 0xff); /* source pitch low */
- WGfx(GR27, (line_length >> 8)); /* source pitch hi */
+ vga_wgfx (regbase, CL_GR24, line_length & 0xff); /* dest pitch low */
+ vga_wgfx (regbase, CL_GR25, (line_length >> 8)); /* dest pitch hi */
+ vga_wgfx (regbase, CL_GR26, line_length & 0xff); /* source pitch low */
+ vga_wgfx (regbase, CL_GR27, (line_length >> 8)); /* source pitch hi */
/* BLT width: actual number of pixels - 1 */
- WGfx(GR20, nwidth & 0xff); /* BLT width low */
- WGfx(GR21, (nwidth >> 8)); /* BLT width hi */
+ vga_wgfx (regbase, CL_GR20, nwidth & 0xff); /* BLT width low */
+ vga_wgfx (regbase, CL_GR21, (nwidth >> 8)); /* BLT width hi */
/* BLT height: actual number of lines -1 */
- WGfx(GR22, nheight & 0xff); /* BLT height low */
- WGfx(GR23, (nheight >> 8)); /* BLT width hi */
+ vga_wgfx (regbase, CL_GR22, nheight & 0xff); /* BLT height low */
+ vga_wgfx (regbase, CL_GR23, (nheight >> 8)); /* BLT width hi */
/* BLT destination */
- WGfx(GR28, (u_char)(ndest & 0xff)); /* BLT dest low */
- WGfx(GR29, (u_char)(ndest >> 8)); /* BLT dest mid */
- WGfx(GR2A, (u_char)(ndest >> 16)); /* BLT dest hi */
+ vga_wgfx (regbase, CL_GR28, (u_char) (ndest & 0xff)); /* BLT dest low */
+ vga_wgfx (regbase, CL_GR29, (u_char) (ndest >> 8)); /* BLT dest mid */
+ vga_wgfx (regbase, CL_GR2A, (u_char) (ndest >> 16)); /* BLT dest hi */
/* BLT source */
- WGfx(GR2C, (u_char)(nsrc & 0xff)); /* BLT src low */
- WGfx(GR2D, (u_char)(nsrc >> 8)); /* BLT src mid */
- WGfx(GR2E, (u_char)(nsrc >> 16)); /* BLT src hi */
+ vga_wgfx (regbase, CL_GR2C, (u_char) (nsrc & 0xff)); /* BLT src low */
+ vga_wgfx (regbase, CL_GR2D, (u_char) (nsrc >> 8)); /* BLT src mid */
+ vga_wgfx (regbase, CL_GR2E, (u_char) (nsrc >> 16)); /* BLT src hi */
/* BLT mode */
- WGfx(GR30, bltmode); /* BLT mode */
+ vga_wgfx (regbase, CL_GR30, bltmode); /* BLT mode */
/* BLT ROP: SrcCopy */
- WGfx(GR32, 0x0d); /* BLT ROP */
+ vga_wgfx (regbase, CL_GR32, 0x0d); /* BLT ROP */
/* and finally: GO! */
- WGfx(GR31, 0x02); /* BLT Start/status */
+ vga_wgfx (regbase, CL_GR31, 0x02); /* BLT Start/status */
+
+ DPRINTK ("EXIT\n");
}
/*******************************************************************
@@ -2042,56 +3344,78 @@ void clgen_BitBLT (u_short curx, u_short cury, u_short destx, u_short desty,
perform accelerated rectangle fill
********************************************************************/
-void clgen_RectFill (u_short x, u_short y, u_short width, u_short height,
- u_char color, u_short line_length)
+static void clgen_RectFill (struct clgenfb_info *fb_info,
+ u_short x, u_short y, u_short width, u_short height,
+ u_char color, u_short line_length)
{
u_short nwidth, nheight;
u_long ndest;
+ u_char op;
+
+ DPRINTK ("ENTER\n");
nwidth = width - 1;
nheight = height - 1;
ndest = (y * line_length) + x;
-// clgen_WaitBLT(); /* ### NOT OK for multiple boards! */
+ clgen_WaitBLT(fb_info->regs);
/* pitch: set to line_length */
- WGfx(GR24, line_length & 0xff); /* dest pitch low */
- WGfx(GR25, (line_length >> 8)); /* dest pitch hi */
- WGfx(GR26, line_length & 0xff); /* source pitch low */
- WGfx(GR27, (line_length >> 8)); /* source pitch hi */
+ vga_wgfx (fb_info->regs, CL_GR24, line_length & 0xff); /* dest pitch low */
+ vga_wgfx (fb_info->regs, CL_GR25, (line_length >> 8)); /* dest pitch hi */
+ vga_wgfx (fb_info->regs, CL_GR26, line_length & 0xff); /* source pitch low */
+ vga_wgfx (fb_info->regs, CL_GR27, (line_length >> 8)); /* source pitch hi */
/* BLT width: actual number of pixels - 1 */
- WGfx(GR20, nwidth & 0xff); /* BLT width low */
- WGfx(GR21, (nwidth >> 8)); /* BLT width hi */
+ vga_wgfx (fb_info->regs, CL_GR20, nwidth & 0xff); /* BLT width low */
+ vga_wgfx (fb_info->regs, CL_GR21, (nwidth >> 8)); /* BLT width hi */
/* BLT height: actual number of lines -1 */
- WGfx(GR22, nheight & 0xff); /* BLT height low */
- WGfx(GR23, (nheight >> 8)); /* BLT width hi */
+ vga_wgfx (fb_info->regs, CL_GR22, nheight & 0xff); /* BLT height low */
+ vga_wgfx (fb_info->regs, CL_GR23, (nheight >> 8)); /* BLT width hi */
/* BLT destination */
- WGfx(GR28, (u_char)(ndest & 0xff)); /* BLT dest low */
- WGfx(GR29, (u_char)(ndest >> 8)); /* BLT dest mid */
- WGfx(GR2A, (u_char)(ndest >> 16)); /* BLT dest hi */
+ vga_wgfx (fb_info->regs, CL_GR28, (u_char) (ndest & 0xff)); /* BLT dest low */
+ vga_wgfx (fb_info->regs, CL_GR29, (u_char) (ndest >> 8)); /* BLT dest mid */
+ vga_wgfx (fb_info->regs, CL_GR2A, (u_char) (ndest >> 16)); /* BLT dest hi */
/* BLT source: set to 0 (is a dummy here anyway) */
- WGfx(GR2C, 0x00); /* BLT src low */
- WGfx(GR2D, 0x00); /* BLT src mid */
- WGfx(GR2E, 0x00); /* BLT src hi */
+ vga_wgfx (fb_info->regs, CL_GR2C, 0x00); /* BLT src low */
+ vga_wgfx (fb_info->regs, CL_GR2D, 0x00); /* BLT src mid */
+ vga_wgfx (fb_info->regs, CL_GR2E, 0x00); /* BLT src hi */
/* This is a ColorExpand Blt, using the */
/* same color for foreground and background */
- WGfx(GR0, color); /* foreground color */
- WGfx(GR1, color); /* background color */
-
+ vga_wgfx (fb_info->regs, VGA_GFX_SR_VALUE, color); /* foreground color */
+ vga_wgfx (fb_info->regs, VGA_GFX_SR_ENABLE, color); /* background color */
+
+ op = 0xc0;
+ if (fb_info->currentmode.var.bits_per_pixel == 16) {
+ vga_wgfx (fb_info->regs, CL_GR10, color); /* foreground color */
+ vga_wgfx (fb_info->regs, CL_GR11, color); /* background color */
+ op = 0x50;
+ op = 0xd0;
+ } else if (fb_info->currentmode.var.bits_per_pixel == 32) {
+ vga_wgfx (fb_info->regs, CL_GR10, color); /* foreground color */
+ vga_wgfx (fb_info->regs, CL_GR11, color); /* background color */
+ vga_wgfx (fb_info->regs, CL_GR12, color); /* foreground color */
+ vga_wgfx (fb_info->regs, CL_GR13, color); /* background color */
+ vga_wgfx (fb_info->regs, CL_GR14, 0); /* foreground color */
+ vga_wgfx (fb_info->regs, CL_GR15, 0); /* background color */
+ op = 0x50;
+ op = 0xf0;
+ }
/* BLT mode: color expand, Enable 8x8 copy (faster?) */
- WGfx(GR30, 0xc0); /* BLT mode */
+ vga_wgfx (fb_info->regs, CL_GR30, op); /* BLT mode */
/* BLT ROP: SrcCopy */
- WGfx(GR32, 0x0d); /* BLT ROP */
+ vga_wgfx (fb_info->regs, CL_GR32, 0x0d); /* BLT ROP */
/* and finally: GO! */
- WGfx(GR31, 0x02); /* BLT Start/status */
+ vga_wgfx (fb_info->regs, CL_GR31, 0x02); /* BLT Start/status */
+
+ DPRINTK ("EXIT\n");
}
/**************************************************************************
@@ -2099,70 +3423,283 @@ void clgen_RectFill (u_short x, u_short y, u_short width, u_short height,
* desired pixel clock
**************************************************************************/
#define abs(x) ((x)<0 ? -(x) : (x))
-static void bestclock(long freq, long *best, long *nom,
- long *den, long *div, long maxfreq)
+static void bestclock (long freq, long *best, long *nom,
+ long *den, long *div, long maxfreq)
{
- long n, h, d, f;
-
- *nom = 0;
- *den = 0;
- *div = 0;
-
- if (freq < 8000)
- freq = 8000;
-
- if (freq > maxfreq)
- freq = maxfreq;
-
- *best = 0;
- f = freq * 10;
-
- for(n = 32; n < 128; n++)
- {
- d = (143181 * n) / f;
- if ( (d >= 7) && (d <= 63) )
- {
- if (d > 31)
- d = (d / 2) * 2;
- h = (14318 * n) / d;
- if ( abs(h - freq) < abs(*best - freq) )
- {
- *best = h;
- *nom = n;
- if (d < 32)
- {
- *den = d;
- *div = 0;
+ long n, h, d, f;
+
+ assert (best != NULL);
+ assert (nom != NULL);
+ assert (den != NULL);
+ assert (div != NULL);
+ assert (maxfreq > 0);
+
+ *nom = 0;
+ *den = 0;
+ *div = 0;
+
+ DPRINTK ("ENTER\n");
+
+ if (freq < 8000)
+ freq = 8000;
+
+ if (freq > maxfreq)
+ freq = maxfreq;
+
+ *best = 0;
+ f = freq * 10;
+
+ for (n = 32; n < 128; n++) {
+ d = (143181 * n) / f;
+ if ((d >= 7) && (d <= 63)) {
+ if (d > 31)
+ d = (d / 2) * 2;
+ h = (14318 * n) / d;
+ if (abs (h - freq) < abs (*best - freq)) {
+ *best = h;
+ *nom = n;
+ if (d < 32) {
+ *den = d;
+ *div = 0;
+ } else {
+ *den = d / 2;
+ *div = 1;
+ }
+ }
}
- else
- {
- *den = d / 2;
- *div = 1;
+ d = ((143181 * n) + f - 1) / f;
+ if ((d >= 7) && (d <= 63)) {
+ if (d > 31)
+ d = (d / 2) * 2;
+ h = (14318 * n) / d;
+ if (abs (h - freq) < abs (*best - freq)) {
+ *best = h;
+ *nom = n;
+ if (d < 32) {
+ *den = d;
+ *div = 0;
+ } else {
+ *den = d / 2;
+ *div = 1;
+ }
+ }
}
- }
- }
- d = ( (143181 * n)+f-1) / f;
- if ( (d >= 7) && (d <= 63) )
- {
- if (d > 31)
- d = (d / 2) * 2;
- h = (14318 * n) / d;
- if ( abs(h - freq) < abs(*best - freq) )
- {
- *best = h;
- *nom = n;
- if (d < 32)
- {
- *den = d;
- *div = 0;
- }
- else
- {
- *den = d / 2;
- *div = 1;
- }
- }
- }
- }
+ }
+
+ DPRINTK ("Best possible values for given frequency:\n");
+ DPRINTK (" best: %ld kHz nom: %ld den: %ld div: %ld\n",
+ freq, *nom, *den, *div);
+
+ DPRINTK ("EXIT\n");
}
+
+
+
+
+
+/* -------------------------------------------------------------------------
+ *
+ * debugging functions
+ *
+ * -------------------------------------------------------------------------
+ */
+
+#ifdef CLGEN_DEBUG
+
+/**
+ * clgen_dbg_print_byte
+ * @name: name associated with byte value to be displayed
+ * @val: byte value to be displayed
+ *
+ * DESCRIPTION:
+ * Display an indented string, along with a hexidecimal byte value, and
+ * its decoded bits. Bits 7 through 0 are listed in left-to-right
+ * order.
+ */
+
+static
+void clgen_dbg_print_byte (const char *name, unsigned char val)
+{
+ DPRINTK ("%8s = 0x%02X (bits 7-0: %c%c%c%c%c%c%c%c)\n",
+ name, val,
+ val & 0x80 ? '1' : '0',
+ val & 0x40 ? '1' : '0',
+ val & 0x20 ? '1' : '0',
+ val & 0x10 ? '1' : '0',
+ val & 0x08 ? '1' : '0',
+ val & 0x04 ? '1' : '0',
+ val & 0x02 ? '1' : '0',
+ val & 0x01 ? '1' : '0');
+}
+
+
+
+/**
+ * clgen_dbg_print_regs
+ * @base: If using newmmio, the newmmio base address, otherwise %NULL
+ * @reg_class: type of registers to read: %CRT, or %SEQ
+ *
+ * DESCRIPTION:
+ * Dumps the given list of VGA CRTC registers. If @base is %NULL,
+ * old-style I/O ports are queried for information, otherwise MMIO is
+ * used at the given @base address to query the information.
+ */
+
+static
+void clgen_dbg_print_regs (caddr_t regbase, clgen_dbg_reg_class_t reg_class,...)
+{
+ va_list list;
+ unsigned char val = 0;
+ unsigned reg;
+ char *name;
+
+ va_start (list, reg_class);
+
+ name = va_arg (list, char *);
+ while (name != NULL) {
+ reg = va_arg (list, int);
+
+ switch (reg_class) {
+ case CRT:
+ val = vga_rcrt (regbase, (unsigned char) reg);
+ break;
+ case SEQ:
+ val = vga_rseq (regbase, (unsigned char) reg);
+ break;
+ default:
+ /* should never occur */
+ assert (FALSE);
+ break;
+ }
+
+ clgen_dbg_print_byte (name, val);
+
+ name = va_arg (list, char *);
+ }
+
+ va_end (list);
+}
+
+
+
+
+
+/**
+ * clgen_dump
+ * @clgeninfo:
+ *
+ * DESCRIPTION:
+ */
+
+static
+void clgen_dump (void)
+{
+ clgen_dbg_reg_dump (NULL);
+}
+
+
+
+/**
+ * clgen_dbg_reg_dump
+ * @base: If using newmmio, the newmmio base address, otherwise %NULL
+ *
+ * DESCRIPTION:
+ * Dumps a list of interesting VGA and CLGEN registers. If @base is %NULL,
+ * old-style I/O ports are queried for information, otherwise MMIO is
+ * used at the given @base address to query the information.
+ */
+
+static
+void clgen_dbg_reg_dump (caddr_t regbase)
+{
+ DPRINTK ("CLGEN VGA CRTC register dump:\n");
+
+ clgen_dbg_print_regs (regbase, CRT,
+ "CR00", 0x00,
+ "CR01", 0x01,
+ "CR02", 0x02,
+ "CR03", 0x03,
+ "CR04", 0x04,
+ "CR05", 0x05,
+ "CR06", 0x06,
+ "CR07", 0x07,
+ "CR08", 0x08,
+ "CR09", 0x09,
+ "CR0A", 0x0A,
+ "CR0B", 0x0B,
+ "CR0C", 0x0C,
+ "CR0D", 0x0D,
+ "CR0E", 0x0E,
+ "CR0F", 0x0F,
+ "CR10", 0x10,
+ "CR11", 0x11,
+ "CR12", 0x12,
+ "CR13", 0x13,
+ "CR14", 0x14,
+ "CR15", 0x15,
+ "CR16", 0x16,
+ "CR17", 0x17,
+ "CR18", 0x18,
+ "CR22", 0x22,
+ "CR24", 0x24,
+ "CR26", 0x26,
+ "CR2D", 0x2D,
+ "CR2E", 0x2E,
+ "CR2F", 0x2F,
+ "CR30", 0x30,
+ "CR31", 0x31,
+ "CR32", 0x32,
+ "CR33", 0x33,
+ "CR34", 0x34,
+ "CR35", 0x35,
+ "CR36", 0x36,
+ "CR37", 0x37,
+ "CR38", 0x38,
+ "CR39", 0x39,
+ "CR3A", 0x3A,
+ "CR3B", 0x3B,
+ "CR3C", 0x3C,
+ "CR3D", 0x3D,
+ "CR3E", 0x3E,
+ "CR3F", 0x3F,
+ NULL);
+
+ DPRINTK ("\n");
+
+ DPRINTK ("CLGEN VGA SEQ register dump:\n");
+
+ clgen_dbg_print_regs (regbase, SEQ,
+ "SR00", 0x00,
+ "SR01", 0x01,
+ "SR02", 0x02,
+ "SR03", 0x03,
+ "SR04", 0x04,
+ "SR08", 0x08,
+ "SR09", 0x09,
+ "SR0A", 0x0A,
+ "SR0B", 0x0B,
+ "SR0D", 0x0D,
+ "SR10", 0x10,
+ "SR11", 0x11,
+ "SR12", 0x12,
+ "SR13", 0x13,
+ "SR14", 0x14,
+ "SR15", 0x15,
+ "SR16", 0x16,
+ "SR17", 0x17,
+ "SR18", 0x18,
+ "SR19", 0x19,
+ "SR1A", 0x1A,
+ "SR1B", 0x1B,
+ "SR1C", 0x1C,
+ "SR1D", 0x1D,
+ "SR1E", 0x1E,
+ "SR1F", 0x1F,
+ NULL);
+
+ DPRINTK ("\n");
+}
+
+
+#endif /* CLGEN_DEBUG */
diff --git a/drivers/video/clgenfb.h b/drivers/video/clgenfb.h
index 3f66ec294..b2776b6c8 100644
--- a/drivers/video/clgenfb.h
+++ b/drivers/video/clgenfb.h
@@ -1,175 +1,122 @@
+/*
+ * drivers/video/clgenfb.h - Cirrus Logic chipset constants
+ *
+ * Copyright 1999 Jeff Garzik <jgarzik@pobox.com>
+ *
+ * Original clgenfb author: Frank Neumann
+ *
+ * Based on retz3fb.c and clgen.c:
+ * Copyright (C) 1997 Jes Sorensen
+ * Copyright (C) 1996 Frank Neumann
+ *
+ ***************************************************************
+ *
+ * Format this code with GNU indent '-kr -i8 -pcs' options.
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive
+ * for more details.
+ *
+ */
-/* definitions for Piccolo/SD64 VGA controller chip */
-/* these definitions might most of the time also work */
-/* for other CL-GD542x/543x based boards.. */
+#ifndef __CLGENFB_H__
+#define __CLGENFB_H__
+
+/* OLD COMMENT: definitions for Piccolo/SD64 VGA controller chip */
+/* OLD COMMENT: these definitions might most of the time also work */
+/* OLD COMMENT: for other CL-GD542x/543x based boards.. */
/*** External/General Registers ***/
-#define POS102 0x102 /* POS102 register */
-#define VSSM 0x46e8 /* Adapter Sleep */
-#define VSSM2 0x3c3 /* Motherboard Sleep */
-#define MISC_W 0x3c2 /* Miscellaneous Output register, write */
-#define MISC_R 0x3cc /* Miscellaneous Output register, read */
-#define FC_W 0x3da /* Feature Control Register, write (color) */
-#define FC_R 0x3ca /* Feature Control Register, read */
-#define FEAT 0x3c2 /* Input Status Register 0 */
-#define STAT 0x3da /* Input Status Register 1, read-only */
-#define M_3C6 0x3c6 /* Pixel Mask */
-#define M_3C7_W 0x3c7 /* Pixel Address Read Mode (write) */
-#define M_3C7_R 0x3c7 /* DAC State (read-only */
-#define M_3C8 0x3c8 /* Pixel Address Write Mode */
-#define M_3C9 0x3c9 /* Pixel Data */
+#define CL_POS102 0x102 /* POS102 register */
+#define CL_VSSM 0x46e8 /* Adapter Sleep */
+#define CL_VSSM2 0x3c3 /* Motherboard Sleep */
/*** VGA Sequencer Registers ***/
-#define SEQRX 0x3c4 /* Sequencer Index */
-#define SEQR0 0x0 /* Reset */
-#define SEQR1 0x1 /* Clocking Mode */
-#define SEQR2 0x2 /* Plane Mask / Write Pixel Extension */
-#define SEQR3 0x3 /* Character Map Select */
-#define SEQR4 0x4 /* Memory Mode */
+#define CL_SEQR0 0x0 /* Reset */
/* the following are from the "extension registers" group */
-#define SEQR6 0x6 /* Unlock ALL Extensions */
-#define SEQR7 0x7 /* Extended Sequencer Mode */
-#define SEQR8 0x8 /* EEPROM Control */
-#define SEQR9 0x9 /* Scratch Pad 0 (do not access!) */
-#define SEQRA 0xa /* Scratch Pad 1 (do not access!) */
-#define SEQRB 0xb /* VCLK0 Numerator */
-#define SEQRC 0xc /* VCLK1 Numerator */
-#define SEQRD 0xd /* VCLK2 Numerator */
-#define SEQRE 0xe /* VCLK3 Numerator */
-#define SEQRF 0xf /* DRAM Control */
-#define SEQR10 0x10 /* Graphics Cursor X Position */
-#define SEQR11 0x11 /* Graphics Cursor Y Position */
-#define SEQR12 0x12 /* Graphics Cursor Attributes */
-#define SEQR13 0x13 /* Graphics Cursor Pattern Address Offset */
-#define SEQR14 0x14 /* Scratch Pad 2 (CL-GD5426/'28 Only) (do not access!) */
-#define SEQR15 0x15 /* Scratch Pad 3 (CL-GD5426/'28 Only) (do not access!) */
-#define SEQR16 0x16 /* Performance Tuning (CL-GD5424/'26/'28 Only) */
-#define SEQR17 0x17 /* Configuration ReadBack and Extended Control (CL-GF5428 Only) */
-#define SEQR18 0x18 /* Signature Generator Control (Not CL-GD5420) */
-#define SEQR19 0x19 /* Signature Generator Result Low Byte (Not CL-GD5420) */
-#define SEQR1A 0x1a /* Signature Generator Result High Byte (Not CL-GD5420) */
-#define SEQR1B 0x1b /* VCLK0 Denominator and Post-Scalar Value */
-#define SEQR1C 0x1c /* VCLK1 Denominator and Post-Scalar Value */
-#define SEQR1D 0x1d /* VCLK2 Denominator and Post-Scalar Value */
-#define SEQR1E 0x1e /* VCLK3 Denominator and Post-Scalar Value */
-#define SEQR1F 0x1f /* BIOS ROM write enable and MCLK Select */
+#define CL_SEQR6 0x6 /* Unlock ALL Extensions */
+#define CL_SEQR7 0x7 /* Extended Sequencer Mode */
+#define CL_SEQR8 0x8 /* EEPROM Control */
+#define CL_SEQR9 0x9 /* Scratch Pad 0 (do not access!) */
+#define CL_SEQRA 0xa /* Scratch Pad 1 (do not access!) */
+#define CL_SEQRB 0xb /* VCLK0 Numerator */
+#define CL_SEQRC 0xc /* VCLK1 Numerator */
+#define CL_SEQRD 0xd /* VCLK2 Numerator */
+#define CL_SEQRE 0xe /* VCLK3 Numerator */
+#define CL_SEQRF 0xf /* DRAM Control */
+#define CL_SEQR10 0x10 /* Graphics Cursor X Position */
+#define CL_SEQR11 0x11 /* Graphics Cursor Y Position */
+#define CL_SEQR12 0x12 /* Graphics Cursor Attributes */
+#define CL_SEQR13 0x13 /* Graphics Cursor Pattern Address Offset */
+#define CL_SEQR14 0x14 /* Scratch Pad 2 (CL-GD5426/'28 Only) (do not access!) */
+#define CL_SEQR15 0x15 /* Scratch Pad 3 (CL-GD5426/'28 Only) (do not access!) */
+#define CL_SEQR16 0x16 /* Performance Tuning (CL-GD5424/'26/'28 Only) */
+#define CL_SEQR17 0x17 /* Configuration ReadBack and Extended Control (CL-GF5428 Only) */
+#define CL_SEQR18 0x18 /* Signature Generator Control (Not CL-GD5420) */
+#define CL_SEQR19 0x19 /* Signature Generator Result Low Byte (Not CL-GD5420) */
+#define CL_SEQR1A 0x1a /* Signature Generator Result High Byte (Not CL-GD5420) */
+#define CL_SEQR1B 0x1b /* VCLK0 Denominator and Post-Scalar Value */
+#define CL_SEQR1C 0x1c /* VCLK1 Denominator and Post-Scalar Value */
+#define CL_SEQR1D 0x1d /* VCLK2 Denominator and Post-Scalar Value */
+#define CL_SEQR1E 0x1e /* VCLK3 Denominator and Post-Scalar Value */
+#define CL_SEQR1F 0x1f /* BIOS ROM write enable and MCLK Select */
/*** CRT Controller Registers ***/
-#define CRTX 0x3d4 /* CRTC Index */
-#define CRT0 0x0 /* Horizontal Total */
-#define CRT1 0x1 /* Horizontal Display End */
-#define CRT2 0x2 /* Horizontal Blanking Start */
-#define CRT3 0x3 /* Horizontal Blabking End */
-#define CRT4 0x4 /* Horizontal Sync Start */
-#define CRT5 0x5 /* Horizontal Sync End */
-#define CRT6 0x6 /* Vertical Total */
-#define CRT7 0x7 /* Overflow */
-#define CRT8 0x8 /* Screen A Preset Row Scan */
-#define CRT9 0x9 /* Character Cell Height */
-#define CRTA 0xa /* Text Cursor Start */
-#define CRTB 0xb /* Text Cursor End */
-#define CRTC 0xc /* Screen Start Address High */
-#define CRTD 0xd /* Screen Start Address Low */
-#define CRTE 0xe /* Text Cursor Location High */
-#define CRTF 0xf /* Text Cursor Location Low */
-#define CRT10 0x10 /* Vertical Sync Start */
-#define CRT11 0x11 /* Vertical Sync End */
-#define CRT12 0x12 /* Vertical Display End */
-#define CRT13 0x13 /* Offset */
-#define CRT14 0x14 /* Underline Row Scan */
-#define CRT15 0x15 /* Vertical Blanking Start */
-#define CRT16 0x16 /* Vertical Blanking End */
-#define CRT17 0x17 /* Mode Control */
-#define CRT18 0x18 /* Line Compare */
-#define CRT22 0x22 /* Graphics Data Latches ReadBack */
-#define CRT24 0x24 /* Attribute Controller Toggle ReadBack */
-#define CRT26 0x26 /* Attribute Controller Index ReadBack */
+#define CL_CRT22 0x22 /* Graphics Data Latches ReadBack */
+#define CL_CRT24 0x24 /* Attribute Controller Toggle ReadBack */
+#define CL_CRT26 0x26 /* Attribute Controller Index ReadBack */
/* the following are from the "extension registers" group */
-#define CRT19 0x19 /* Interlace End */
-#define CRT1A 0x1a /* Interlace Control */
-#define CRT1B 0x1b /* Extended Display Controls */
-#define CRT1C 0x1c /* Sync adjust and genlock register */
-#define CRT1D 0x1d /* Overlay Extended Control register */
-#define CRT25 0x25 /* Part Status Register */
-#define CRT27 0x27 /* ID Register */
-#define CRT51 0x51 /* P4 disable "flicker fixer" */
+#define CL_CRT19 0x19 /* Interlace End */
+#define CL_CRT1A 0x1a /* Interlace Control */
+#define CL_CRT1B 0x1b /* Extended Display Controls */
+#define CL_CRT1C 0x1c /* Sync adjust and genlock register */
+#define CL_CRT1D 0x1d /* Overlay Extended Control register */
+#define CL_CRT25 0x25 /* Part Status Register */
+#define CL_CRT27 0x27 /* ID Register */
+#define CL_CRT51 0x51 /* P4 disable "flicker fixer" */
/*** Graphics Controller Registers ***/
-#define GRX 0x3ce /* Graphics Controller Index */
-#define GR0 0x0 /* Set/Reset, Write Mode 5 Background Extension */
-#define GR1 0x1 /* Set/Reset Enable, Write Mode 4, 5 Foreground Ext. */
-#define GR2 0x2 /* Color Compare */
-#define GR3 0x3 /* Data Rotate */
-#define GR4 0x4 /* Read Map Select */
-#define GR5 0x5 /* Mode */
-#define GR6 0x6 /* Miscellaneous */
-#define GR7 0x7 /* Color Don't Care */
-#define GR8 0x8 /* Bit Mask */
/* the following are from the "extension registers" group */
-#define GR9 0x9 /* Offset Register 0 */
-#define GRA 0xa /* Offset Register 1 */
-#define GRB 0xb /* Graphics Controller Mode Extensions */
-#define GRC 0xc /* Color Key (CL-GD5424/'26/'28 Only) */
-#define GRD 0xd /* Color Key Mask (CL-GD5424/'26/'28 Only) */
-#define GRE 0xe /* Miscellaneous Control (Cl-GD5428 Only) */
-#define GRF 0xf /* Display Compression Control register */
-#define GR10 0x10 /* 16-bit Pixel BG Color High Byte (Not CL-GD5420) */
-#define GR11 0x11 /* 16-bit Pixel FG Color High Byte (Not CL-GD5420) */
-#define GR12 0x12 /* Background Color Byte 2 Register */
-#define GR13 0x13 /* Foreground Color Byte 2 Register */
-#define GR14 0x14 /* Background Color Byte 3 Register */
-#define GR15 0x15 /* Foreground Color Byte 3 Register */
+#define CL_GR9 0x9 /* Offset Register 0 */
+#define CL_GRA 0xa /* Offset Register 1 */
+#define CL_GRB 0xb /* Graphics Controller Mode Extensions */
+#define CL_GRC 0xc /* Color Key (CL-GD5424/'26/'28 Only) */
+#define CL_GRD 0xd /* Color Key Mask (CL-GD5424/'26/'28 Only) */
+#define CL_GRE 0xe /* Miscellaneous Control (Cl-GD5428 Only) */
+#define CL_GRF 0xf /* Display Compression Control register */
+#define CL_GR10 0x10 /* 16-bit Pixel BG Color High Byte (Not CL-GD5420) */
+#define CL_GR11 0x11 /* 16-bit Pixel FG Color High Byte (Not CL-GD5420) */
+#define CL_GR12 0x12 /* Background Color Byte 2 Register */
+#define CL_GR13 0x13 /* Foreground Color Byte 2 Register */
+#define CL_GR14 0x14 /* Background Color Byte 3 Register */
+#define CL_GR15 0x15 /* Foreground Color Byte 3 Register */
/* the following are CL-GD5426/'28 specific blitter registers */
-#define GR20 0x20 /* BLT Width Low */
-#define GR21 0x21 /* BLT Width High */
-#define GR22 0x22 /* BLT Height Low */
-#define GR23 0x23 /* BLT Height High */
-#define GR24 0x24 /* BLT Destination Pitch Low */
-#define GR25 0x25 /* BLT Destination Pitch High */
-#define GR26 0x26 /* BLT Source Pitch Low */
-#define GR27 0x27 /* BLT Source Pitch High */
-#define GR28 0x28 /* BLT Destination Start Low */
-#define GR29 0x29 /* BLT Destination Start Mid */
-#define GR2A 0x2a /* BLT Destination Start High */
-#define GR2C 0x2c /* BLT Source Start Low */
-#define GR2D 0x2d /* BLT Source Start Mid */
-#define GR2E 0x2e /* BLT Source Start High */
-#define GR2F 0x2f /* Picasso IV Blitter compat mode..? */
-#define GR30 0x30 /* BLT Mode */
-#define GR31 0x31 /* BLT Start/Status */
-#define GR32 0x32 /* BLT Raster Operation */
-#define GR33 0x33 /* another P4 "compat" register.. */
-#define GR34 0x34 /* Transparent Color Select Low */
-#define GR35 0x35 /* Transparent Color Select High */
-#define GR38 0x38 /* Source Transparent Color Mask Low */
-#define GR39 0x39 /* Source Transparent Color Mask High */
+#define CL_GR20 0x20 /* BLT Width Low */
+#define CL_GR21 0x21 /* BLT Width High */
+#define CL_GR22 0x22 /* BLT Height Low */
+#define CL_GR23 0x23 /* BLT Height High */
+#define CL_GR24 0x24 /* BLT Destination Pitch Low */
+#define CL_GR25 0x25 /* BLT Destination Pitch High */
+#define CL_GR26 0x26 /* BLT Source Pitch Low */
+#define CL_GR27 0x27 /* BLT Source Pitch High */
+#define CL_GR28 0x28 /* BLT Destination Start Low */
+#define CL_GR29 0x29 /* BLT Destination Start Mid */
+#define CL_GR2A 0x2a /* BLT Destination Start High */
+#define CL_GR2C 0x2c /* BLT Source Start Low */
+#define CL_GR2D 0x2d /* BLT Source Start Mid */
+#define CL_GR2E 0x2e /* BLT Source Start High */
+#define CL_GR2F 0x2f /* Picasso IV Blitter compat mode..? */
+#define CL_GR30 0x30 /* BLT Mode */
+#define CL_GR31 0x31 /* BLT Start/Status */
+#define CL_GR32 0x32 /* BLT Raster Operation */
+#define CL_GR33 0x33 /* another P4 "compat" register.. */
+#define CL_GR34 0x34 /* Transparent Color Select Low */
+#define CL_GR35 0x35 /* Transparent Color Select High */
+#define CL_GR38 0x38 /* Source Transparent Color Mask Low */
+#define CL_GR39 0x39 /* Source Transparent Color Mask High */
/*** Attribute Controller Registers ***/
-#define ARX 0x3c0 /* Attribute Controller Index */
-#define AR0 0x0 /* Attribute Controller Palette Register 0 */
-#define AR1 0x1 /* Attribute Controller Palette Register 1 */
-#define AR2 0x2 /* Attribute Controller Palette Register 2 */
-#define AR3 0x3 /* Attribute Controller Palette Register 3 */
-#define AR4 0x4 /* Attribute Controller Palette Register 4 */
-#define AR5 0x5 /* Attribute Controller Palette Register 5 */
-#define AR6 0x6 /* Attribute Controller Palette Register 6 */
-#define AR7 0x7 /* Attribute Controller Palette Register 7 */
-#define AR8 0x8 /* Attribute Controller Palette Register 8 */
-#define AR9 0x9 /* Attribute Controller Palette Register 9 */
-#define ARA 0xa /* Attribute Controller Palette Register 10 */
-#define ARB 0xb /* Attribute Controller Palette Register 11 */
-#define ARC 0xc /* Attribute Controller Palette Register 12 */
-#define ARD 0xd /* Attribute Controller Palette Register 13 */
-#define ARE 0xe /* Attribute Controller Palette Register 14 */
-#define ARF 0xf /* Attribute Controller Palette Register 15 */
-#define AR10 0x10 /* Attribute Controller Mode Register */
-#define AR11 0x11 /* Overscan (Border) Color Register */
-#define AR12 0x12 /* Color Plane Enable Register */
-#define AR13 0x13 /* Pixel Panning Register */
-#define AR14 0x14 /* Color Select Register */
-#define AR33 0x33 /* The "real" Pixel Panning register (?) */
-#define AR34 0x34 /* *TEST* */
-
-/*** Extension Registers ***/
-#define HDR 0x3c6 /* Hidden DAC Register (Not CL-GD5420) */
+#define CL_AR33 0x33 /* The "real" Pixel Panning register (?) */
+#define CL_AR34 0x34 /* TEST */
+#endif /* __CLGENFB_H__ */
diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c
index 2a783fc9b..6893afbef 100644
--- a/drivers/video/controlfb.c
+++ b/drivers/video/controlfb.c
@@ -149,11 +149,11 @@ static int default_cmode = CMODE_NVRAM;
/*
* Exported functions
*/
-void control_init(void);
+int control_init(void);
#ifdef CONFIG_FB_OF
void control_of_init(struct device_node *dp);
#endif
-void control_setup(char *options, int *ints);
+void control_setup(char *);
static int read_control_sense(struct fb_info_control *p);
static inline int control_vram_reqd(int video_mode, int color_mode);
@@ -185,13 +185,9 @@ static struct fb_ops controlfb_ops = {
/******************** The functions for controlfb_ops ********************/
-#ifndef MODULE
-__openfirmware
-#endif
-
/********** Dummies for loading control as a module **********/
-static int control_open(struct fb_info *info, int user)
+int control_open(struct fb_info *info, int user)
{
MOD_INC_USE_COUNT;
return 0;
@@ -523,7 +519,7 @@ static void set_control_clock(unsigned char *params)
}
-__initfunc(static void init_control(struct fb_info_control *p))
+static void __init init_control(struct fb_info_control *p)
{
struct fb_par_control parstruct;
struct fb_par_control *par = &parstruct;
@@ -660,7 +656,7 @@ static void control_set_hardware(struct fb_info_control *p, struct fb_par_contro
#endif /* CONFIG_FB_COMPAT_XPMAC */
}
-__initfunc(void control_init(void))
+int __init control_init(void)
{
#ifndef CONFIG_FB_OF
struct device_node *dp;
@@ -669,9 +665,10 @@ __initfunc(void control_init(void))
if (dp != 0)
control_of_init(dp);
#endif /* CONFIG_FB_OF */
+ return 0;
}
-__initfunc(void control_of_init(struct device_node *dp))
+void __init control_of_init(struct device_node *dp)
{
struct fb_info_control *p;
unsigned long addr, size;
@@ -720,9 +717,11 @@ __initfunc(void control_of_init(struct device_node *dp))
p->total_vram = (bank1 + bank2) * 0x200000;
/* If we don't have bank 1 installed, we hope we have bank 2 :-) */
p->control_use_bank2 = !bank1;
- if (p->control_use_bank2)
+ if (p->control_use_bank2) {
p->frame_buffer += 0x600000;
-
+ p->frame_buffer_phys += 0x600000;
+ }
+
init_control(p);
}
@@ -998,7 +997,7 @@ static void control_par_to_fix(struct fb_par_control *par, struct fb_fix_screeni
{
memset(fix, 0, sizeof(*fix));
strcpy(fix->id, "control");
- fix->mmio_start = (char *)p->control_regs_phys;
+ fix->mmio_start = p->control_regs_phys;
fix->mmio_len = sizeof(struct control_regs);
fix->type = FB_TYPE_PACKED_PIXELS;
@@ -1010,7 +1009,7 @@ static void control_par_to_fix(struct fb_par_control *par, struct fb_fix_screeni
fix->xpanstep = 0;
*/
- fix->smem_start = (void *)(p->frame_buffer_phys
+ fix->smem_start = (p->frame_buffer_phys
+ control_reg_init[par->vmode-1]->offset[par->cmode]);
fix->smem_len = p->total_vram - control_reg_init[par->vmode-1]->offset[par->cmode];
fix->visual = (par->cmode == CMODE_8) ?
@@ -1152,7 +1151,7 @@ static void control_init_info(struct fb_info *info, struct fb_info_control *p)
}
/* Parse user speficied options (`video=controlfb:') */
-__initfunc(void control_setup(char *options, int *ints))
+void __init control_setup(char *options)
{
char *this_opt;
diff --git a/drivers/video/creatorfb.c b/drivers/video/creatorfb.c
index 81421a7ff..e2fefe0f4 100644
--- a/drivers/video/creatorfb.c
+++ b/drivers/video/creatorfb.c
@@ -1,4 +1,4 @@
-/* $Id: creatorfb.c,v 1.27 1999/03/28 12:37:12 jj Exp $
+/* $Id: creatorfb.c,v 1.29 1999/08/10 15:56:07 davem Exp $
* creatorfb.c: Creator/Creator3D frame buffer driver
*
* Copyright (C) 1997,1998,1999 Jakub Jelinek (jj@ultra.linux.cz)
@@ -633,11 +633,17 @@ static void ffb_switch_from_graph (struct fb_info_sbusfb *fb)
fbc->fg = fb->s.ffb.fg_cache;
fbc->bg = fb->s.ffb.bg_cache;
FFBWait(fbc);
-}
+}
+
+static int __init ffb_rasterimg (struct fb_info *info, int start)
+{
+ ffb_switch_from_graph (sbusfbinfo(info));
+ return 0;
+}
static char idstring[60] __initdata = { 0 };
-__initfunc(char *creatorfb_init(struct fb_info_sbusfb *fb))
+char __init *creatorfb_init(struct fb_info_sbusfb *fb)
{
struct fb_fix_screeninfo *fix = &fb->fix;
struct fb_var_screeninfo *var = &fb->var;
@@ -647,6 +653,7 @@ __initfunc(char *creatorfb_init(struct fb_info_sbusfb *fb))
int i, afb = 0;
unsigned int btype;
char name[64];
+ struct fb_ops *fbops;
if (prom_getproperty(fb->prom_node, "reg", (void *) regs, sizeof(regs)) <= 0)
return NULL;
@@ -656,6 +663,13 @@ __initfunc(char *creatorfb_init(struct fb_info_sbusfb *fb))
return NULL;
memset(disp->dispsw_data, 0, 16 * sizeof(u32));
+ fbops = kmalloc(sizeof(*fbops), GFP_KERNEL);
+ if (!fbops) return NULL;
+
+ *fbops = *fb->info.fbops;
+ fbops->fb_rasterimg = ffb_rasterimg;
+ fb->info.fbops = fbops;
+
prom_getstring(fb->prom_node, "name", name, sizeof(name));
if (!strcmp(name, "SUNW,afb"))
afb = 1;
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index d342304a3..cedb41c2a 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -631,13 +631,15 @@ static void cyber2000fb_set_timing(struct fb_var_screeninfo *var)
cyber2000_outw(width, 0xbf218);
cyber2000_outb(b, 0xbf01c);
-{ int j;
+#if 0
+{ int j; i = 0;
printk(KERN_DEBUG);
for (j = 0; j < 19; j++) printk("%2d ", j); printk("\n"KERN_DEBUG);
for (j = 0; j < 19; j++) printk("%02X ", crtc[j]); printk("\n"KERN_DEBUG);
for (j = 0; j < 18; j++) printk("%02X ", cyber2000_res[i].crtc_regs[j]);
printk("%02X\n", cyber2000_res[i].crtc_ofl);
}
+#endif
}
static inline void
@@ -765,9 +767,9 @@ cyber2000fb_get_fix(struct fb_fix_screeninfo *fix, int con,
else
display = &global_disp;
- fix->smem_start = (char *)current_par.screen_base_p;
+ fix->smem_start = current_par.screen_base_p;
fix->smem_len = current_par.screen_size;
- fix->mmio_start = (char *)current_par.regs_base_p;
+ fix->mmio_start = current_par.regs_base_p;
fix->mmio_len = 0x000c0000;
fix->type = display->type;
fix->type_aux = display->type_aux;
@@ -1018,8 +1020,9 @@ static void cyber2000fb_blank(int blank, struct fb_info *fb_info)
}
}
-__initfunc(void cyber2000fb_setup(char *options, int *ints))
+int __init cyber2000fb_setup(char *options)
{
+ return 0;
}
static struct fb_ops cyber2000fb_ops =
@@ -1035,8 +1038,8 @@ static struct fb_ops cyber2000fb_ops =
cyber2000fb_ioctl
};
-__initfunc(static void
-cyber2000fb_init_fbinfo(void))
+static void __init
+cyber2000fb_init_fbinfo(void)
{
static int first = 1;
@@ -1138,16 +1141,28 @@ cyber2000fb_init_fbinfo(void))
/*
* Initialization
*/
-__initfunc(void cyber2000fb_init(void))
+int __init cyber2000fb_init(void)
{
struct pci_dev *dev;
u_int h_sync, v_sync;
+ u_long base_p, base_v;
dev = pci_find_device(PCI_VENDOR_ID_INTERG, 0x2000, NULL);
if (!dev)
- return;
+ return -ENXIO;
+
+ /* this should be done by PCI generic code */
+ base_p = 0x80000000 + dev->resource[0].start;
+
+ /*
+ * This should be ioremap'd, thus:
+ *
+ * base_v = ioremap(dev->resource[0].start, dev->resource[0].end - dev->resource[0].start + 1);
+ */
+ base_v = (u_long)bus_to_virt(dev->resource[0].start);
- CyberRegs = bus_to_virt(dev->base_address[0]) + 0x00800000;/*FIXME*/
+ /*FIXME*/
+ CyberRegs = base_v + 0x00800000;
cyber2000_outb(0x18, 0x46e8);
cyber2000_outb(0x01, 0x102);
@@ -1156,10 +1171,10 @@ __initfunc(void cyber2000fb_init(void))
cyber2000fb_init_fbinfo();
current_par.currcon = -1;
- current_par.screen_base_p = 0x80000000 + dev->base_address[0];
- current_par.screen_base = (u_int)bus_to_virt(dev->base_address[0]);
+ current_par.screen_base_p = base_p;
+ current_par.screen_base = base_v;
current_par.screen_size = 0x00200000;
- current_par.regs_base_p = 0x80800000 + dev->base_address[0];
+ current_par.regs_base_p = base_p + 0x00800000;
cyber2000fb_set_var(&init_var, -1, &fb_info);
@@ -1175,18 +1190,18 @@ __initfunc(void cyber2000fb_init(void))
h_sync / 1000, h_sync % 1000, v_sync);
if (register_framebuffer(&fb_info) < 0)
- return;
+ return -EINVAL;
MOD_INC_USE_COUNT; /* TODO: This driver cannot be unloaded yet */
+ return 0;
}
#ifdef MODULE
-int init_module(void)
+int __init init_module(void)
{
- cyber2000fb_init();
- return 0;
+ return cyber2000fb_init();
}
void cleanup_module(void)
diff --git a/drivers/video/cyberfb.c b/drivers/video/cyberfb.c
index 6882ebfb0..7e4aea83f 100644
--- a/drivers/video/cyberfb.c
+++ b/drivers/video/cyberfb.c
@@ -109,7 +109,10 @@ static void cv64_dump(void);
#define arraysize(x) (sizeof(x)/sizeof(*(x)))
-#define wb_64(reg,dat) (*((unsigned char volatile *)CyberRegs + reg) = dat)
+#define wb_64(regs,reg,dat) (*(((volatile unsigned char *)regs) + reg) = dat)
+#define rb_64(regs, reg) (*(((volatile unsigned char *)regs) + reg))
+
+#define ww_64(regs,reg,dat) (*((volatile unsigned short *)(regs + reg) = dat)
struct cyberfb_par {
struct fb_var_screeninfo var;
@@ -129,60 +132,32 @@ static struct fb_info fb_info;
/*
-* Switch for Chipset Independency
-*/
-
-static struct fb_hwswitch {
-
-/* Initialisation */
-
-int (*init)(void);
-
-/* Display Control */
-
-int (*encode_fix)(struct fb_fix_screeninfo *fix, struct cyberfb_par *par);
-int (*decode_var)(struct fb_var_screeninfo *var, struct cyberfb_par *par);
-int (*encode_var)(struct fb_var_screeninfo *var, struct cyberfb_par *par);
-int (*getcolreg)(u_int regno, u_int *red, u_int *green, u_int *blue,
- u_int *transp, struct fb_info *info);
-int (*setcolreg)(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *info);
-void (*blank)(int blank);
-} *fbhw;
-
-
-/*
-* Frame Buffer Name
-*/
+ * Frame Buffer Name
+ */
static char cyberfb_name[16] = "Cybervision";
/*
-* Cybervision Graphics Board
-*/
+ * CyberVision Graphics Board
+ */
static unsigned char Cyber_colour_table [256][3];
-static unsigned long CyberMem;
static unsigned long CyberSize;
-static volatile char *CyberRegs;
+static volatile unsigned char *CyberBase;
+static volatile unsigned char *CyberMem;
+static volatile unsigned char *CyberRegs;
static unsigned long CyberMem_phys;
static unsigned long CyberRegs_phys;
-/* From cvision.c for cvision_core.c */
-static unsigned long cv64_mem;
-static unsigned long cv64_fbmem;
-static volatile char *cv64_regs;
-static unsigned long cv64_size;
-#if 0
-static int cvision_custom_mode = 0;
-static int hbs, hbe, hss, hse, ht, vbs, vbe, vss, vse, vt;
-#endif
/*
-* Predefined Video Modes
-*/
+ * Predefined Video Modes
+ */
-static struct fb_videomode cyberfb_predefined[] __initdata = {
+static struct {
+ const char *name;
+ struct fb_var_screeninfo var;
+} cyberfb_predefined[] __initdata = {
{ "640x480-8", { /* Default 8 BPP mode (cyber8) */
640, 480, 640, 480, 0, 0, 8, 0,
{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
@@ -251,19 +226,20 @@ static struct fb_videomode cyberfb_predefined[] __initdata = {
static int Cyberfb_inverse = 0;
/*
-* Some default modes
-*/
+ * Some default modes
+ */
#define CYBER8_DEFMODE (0)
#define CYBER16_DEFMODE (1)
static struct fb_var_screeninfo cyberfb_default;
+static int cyberfb_usermode __initdata = 0;
/*
-* Interface used by the world
-*/
+ * Interface used by the world
+ */
-void cyberfb_setup(char *options, int *ints);
+int cyberfb_setup(char *options);
static int cyberfb_open(struct fb_info *info, int user);
static int cyberfb_release(struct fb_info *info, int user);
@@ -283,25 +259,25 @@ static int cyberfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
u_long arg, int con, struct fb_info *info);
/*
-* Interface to the low level console driver
-*/
+ * Interface to the low level console driver
+ */
-void cyberfb_init(void);
+int cyberfb_init(void);
static int Cyberfb_switch(int con, struct fb_info *info);
static int Cyberfb_updatevar(int con, struct fb_info *info);
static void Cyberfb_blank(int blank, struct fb_info *info);
/*
-* Text console acceleration
-*/
+ * Text console acceleration
+ */
#ifdef FBCON_HAS_CFB8
static struct display_switch fbcon_cyber8;
#endif
/*
-* Accelerated Functions used by the low level console driver
-*/
+ * Accelerated Functions used by the low level console driver
+ */
static void Cyber_WaitQueue(u_short fifo);
static void Cyber_WaitBlit(void);
@@ -310,11 +286,13 @@ static void Cyber_BitBLT(u_short curx, u_short cury, u_short destx,
u_short mode);
static void Cyber_RectFill(u_short x, u_short y, u_short width, u_short height,
u_short mode, u_short color);
+#if 0
static void Cyber_MoveCursor(u_short x, u_short y);
+#endif
/*
-* Hardware Specific Routines
-*/
+ * Hardware Specific Routines
+ */
static int Cyber_init(void);
static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
@@ -327,11 +305,10 @@ static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
u_int *transp, struct fb_info *info);
static int Cyber_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info);
-static void Cyber_blank(int blank);
/*
-* Internal routines
-*/
+ * Internal routines
+ */
static void cyberfb_get_par(struct cyberfb_par *par);
static void cyberfb_set_par(struct cyberfb_par *par);
@@ -342,7 +319,7 @@ static int get_video_mode(const char *name);
/* For cvision_core.c */
static unsigned short cv64_compute_clock(unsigned long);
-static int cv_has_4mb (volatile caddr_t);
+static int cv_has_4mb (volatile unsigned char *);
static void cv64_board_init (void);
static void cv64_load_video_mode (struct fb_var_screeninfo *);
@@ -351,16 +328,17 @@ static void cv64_load_video_mode (struct fb_var_screeninfo *);
/*
-* Initialization
-*
-* Set the default video mode for this chipset. If a video mode was
-* specified on the command line, it will override the default mode.
-*/
+ * Initialization
+ *
+ * Set the default video mode for this chipset. If a video mode was
+ * specified on the command line, it will override the default mode.
+ */
static int Cyber_init(void)
{
+ volatile unsigned char *regs = CyberRegs;
+ volatile unsigned long *CursorBase;
int i;
- volatile u_long *CursorBase;
DPRINTK("ENTER\n");
/* Init local cmap as greyscale levels */
@@ -371,27 +349,25 @@ static int Cyber_init(void)
}
/* Initialize the board and determine fbmem size */
- cv64_board_init ();
+ cv64_board_init();
#ifdef CYBERFBDEBUG
DPRINTK("Register state after initing board\n");
cv64_dump();
#endif
/* Clear framebuffer memory */
DPRINTK("Clear framebuffer memory\n");
- memset ((char *) cv64_fbmem, 0, cv64_size);
+ memset ((char *)CyberMem, 0, CyberSize);
/* Disable hardware cursor */
DPRINTK("Disable HW cursor\n");
- wb_64(S3_CRTC_ADR, S3_REG_LOCK2);
- wb_64(S3_CRTC_DATA, 0xa0);
- wb_64(S3_CRTC_ADR, S3_HGC_MODE);
- wb_64(S3_CRTC_DATA, 0x00);
- wb_64(S3_CRTC_ADR, S3_HWGC_DX);
- wb_64(S3_CRTC_DATA, 0x00);
- wb_64(S3_CRTC_ADR, S3_HWGC_DY);
- wb_64(S3_CRTC_DATA, 0x00);
-
- CyberSize = cv64_size;
+ wb_64(regs, S3_CRTC_ADR, S3_REG_LOCK2);
+ wb_64(regs, S3_CRTC_DATA, 0xa0);
+ wb_64(regs, S3_CRTC_ADR, S3_HGC_MODE);
+ wb_64(regs, S3_CRTC_DATA, 0x00);
+ wb_64(regs, S3_CRTC_ADR, S3_HWGC_DX);
+ wb_64(regs, S3_CRTC_DATA, 0x00);
+ wb_64(regs, S3_CRTC_ADR, S3_HWGC_DY);
+ wb_64(regs, S3_CRTC_DATA, 0x00);
/* Initialize hardware cursor */
DPRINTK("Init HW cursor\n");
@@ -420,9 +396,9 @@ static int Cyber_init(void)
/*
-* This function should fill in the `fix' structure based on the
-* values in the `par' structure.
-*/
+ * This function should fill in the `fix' structure based on the
+ * values in the `par' structure.
+ */
static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
struct cyberfb_par *par)
@@ -430,9 +406,9 @@ static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
DPRINTK("ENTER\n");
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id, cyberfb_name);
- fix->smem_start = (char*) CyberMem_phys;
+ fix->smem_start = CyberMem_phys;
fix->smem_len = CyberSize;
- fix->mmio_start = (char*) CyberRegs_phys;
+ fix->mmio_start = CyberRegs_phys;
fix->mmio_len = 0x10000;
fix->type = FB_TYPE_PACKED_PIXELS;
@@ -546,19 +522,21 @@ static int Cyber_encode_var(struct fb_var_screeninfo *var,
/*
-* Set a single color register. Return != 0 for invalid regno.
-*/
+ * Set a single color register. Return != 0 for invalid regno.
+ */
static int Cyber_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info)
{
+ volatile unsigned char *regs = CyberRegs;
+
/*DPRINTK("ENTER\n");*/
if (regno > 255) {
DPRINTK("EXIT - Register # > 255\n");
return (1);
}
- wb_64(0x3c8, (unsigned char) regno);
+ wb_64(regs, 0x3c8, (unsigned char) regno);
red >>= 10;
green >>= 10;
@@ -568,9 +546,9 @@ static int Cyber_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
Cyber_colour_table [regno][1] = green;
Cyber_colour_table [regno][2] = blue;
- wb_64(0x3c9, red);
- wb_64(0x3c9, green);
- wb_64(0x3c9, blue);
+ wb_64(regs, 0x3c9, red);
+ wb_64(regs, 0x3c9, green);
+ wb_64(regs, 0x3c9, blue);
/*DPRINTK("EXIT\n");*/
return (0);
@@ -611,29 +589,30 @@ static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
* 0 = restore fb cmap from local cmap
*/
-void Cyber_blank(int blank)
+void Cyberfb_blank(int blank, struct fb_info *info)
{
+ volatile unsigned char *regs = CyberRegs;
int i;
DPRINTK("ENTER\n");
#if 0
/* Blank by turning gfx off */
- gfx_on_off (1, cv64_regs);
+ gfx_on_off (1, regs);
#else
if (blank) {
for (i = 0; i < 256; i++) {
- wb_64(0x3c8, (unsigned char) i);
+ wb_64(regs, 0x3c8, (unsigned char) i);
/* ARB Pale red to detect this blanking method */
- wb_64(0x3c9, 48);
- wb_64(0x3c9, 0);
- wb_64(0x3c9, 0);
+ wb_64(regs, 0x3c9, 48);
+ wb_64(regs, 0x3c9, 0);
+ wb_64(regs, 0x3c9, 0);
}
} else {
for (i = 0; i < 256; i++) {
- wb_64(0x3c8, (unsigned char) i);
- wb_64(0x3c9, Cyber_colour_table[i][0]);
- wb_64(0x3c9, Cyber_colour_table[i][1]);
- wb_64(0x3c9, Cyber_colour_table[i][2]);
+ wb_64(regs, 0x3c8, (unsigned char) i);
+ wb_64(regs, 0x3c9, Cyber_colour_table[i][0]);
+ wb_64(regs, 0x3c9, Cyber_colour_table[i][1]);
+ wb_64(regs, 0x3c9, Cyber_colour_table[i][2]);
}
}
#endif
@@ -646,13 +625,12 @@ void Cyber_blank(int blank)
*/
static void Cyber_WaitQueue (u_short fifo)
{
- u_short status;
+ unsigned short status;
DPRINTK("ENTER\n");
do {
status = *((u_short volatile *)(CyberRegs + S3_GP_STAT));
- }
- while (status & fifo);
+ } while (status & fifo);
DPRINTK("EXIT\n");
}
@@ -661,13 +639,12 @@ static void Cyber_WaitQueue (u_short fifo)
*/
static void Cyber_WaitBlit (void)
{
- u_short status;
+ unsigned short status;
DPRINTK("ENTER\n");
do {
status = *((u_short volatile *)(CyberRegs + S3_GP_STAT));
- }
- while (status & S3_HDW_BUSY);
+ } while (status & S3_HDW_BUSY);
DPRINTK("EXIT\n");
}
@@ -678,6 +655,7 @@ static void Cyber_BitBLT (u_short curx, u_short cury, u_short destx,
u_short desty, u_short width, u_short height,
u_short mode)
{
+ volatile unsigned char *regs = CyberRegs;
u_short blitcmd = S3_BITBLT;
DPRINTK("ENTER\n");
@@ -699,19 +677,19 @@ static void Cyber_BitBLT (u_short curx, u_short cury, u_short destx,
Cyber_WaitQueue (0x8000);
- *((u_short volatile *)(CyberRegs + S3_PIXEL_CNTL)) = 0xa000;
- *((u_short volatile *)(CyberRegs + S3_FRGD_MIX)) = (0x0060 | mode);
+ *((u_short volatile *)(regs + S3_PIXEL_CNTL)) = 0xa000;
+ *((u_short volatile *)(regs + S3_FRGD_MIX)) = (0x0060 | mode);
- *((u_short volatile *)(CyberRegs + S3_CUR_X)) = curx;
- *((u_short volatile *)(CyberRegs + S3_CUR_Y)) = cury;
+ *((u_short volatile *)(regs + S3_CUR_X)) = curx;
+ *((u_short volatile *)(regs + S3_CUR_Y)) = cury;
- *((u_short volatile *)(CyberRegs + S3_DESTX_DIASTP)) = destx;
- *((u_short volatile *)(CyberRegs + S3_DESTY_AXSTP)) = desty;
+ *((u_short volatile *)(regs + S3_DESTX_DIASTP)) = destx;
+ *((u_short volatile *)(regs + S3_DESTY_AXSTP)) = desty;
- *((u_short volatile *)(CyberRegs + S3_MIN_AXIS_PCNT)) = height - 1;
- *((u_short volatile *)(CyberRegs + S3_MAJ_AXIS_PCNT)) = width - 1;
+ *((u_short volatile *)(regs + S3_MIN_AXIS_PCNT)) = height - 1;
+ *((u_short volatile *)(regs + S3_MAJ_AXIS_PCNT)) = width - 1;
- *((u_short volatile *)(CyberRegs + S3_CMD)) = blitcmd;
+ *((u_short volatile *)(regs + S3_CMD)) = blitcmd;
DPRINTK("EXIT\n");
}
@@ -721,56 +699,52 @@ static void Cyber_BitBLT (u_short curx, u_short cury, u_short destx,
static void Cyber_RectFill (u_short x, u_short y, u_short width,
u_short height, u_short mode, u_short color)
{
+ volatile unsigned char *regs = CyberRegs;
u_short blitcmd = S3_FILLEDRECT;
DPRINTK("ENTER\n");
Cyber_WaitQueue (0x8000);
- *((u_short volatile *)(CyberRegs + S3_PIXEL_CNTL)) = 0xa000;
- *((u_short volatile *)(CyberRegs + S3_FRGD_MIX)) = (0x0020 | mode);
+ *((u_short volatile *)(regs + S3_PIXEL_CNTL)) = 0xa000;
+ *((u_short volatile *)(regs + S3_FRGD_MIX)) = (0x0020 | mode);
- *((u_short volatile *)(CyberRegs + S3_MULT_MISC)) = 0xe000;
- *((u_short volatile *)(CyberRegs + S3_FRGD_COLOR)) = color;
+ *((u_short volatile *)(regs + S3_MULT_MISC)) = 0xe000;
+ *((u_short volatile *)(regs + S3_FRGD_COLOR)) = color;
- *((u_short volatile *)(CyberRegs + S3_CUR_X)) = x;
- *((u_short volatile *)(CyberRegs + S3_CUR_Y)) = y;
+ *((u_short volatile *)(regs + S3_CUR_X)) = x;
+ *((u_short volatile *)(regs + S3_CUR_Y)) = y;
- *((u_short volatile *)(CyberRegs + S3_MIN_AXIS_PCNT)) = height - 1;
- *((u_short volatile *)(CyberRegs + S3_MAJ_AXIS_PCNT)) = width - 1;
+ *((u_short volatile *)(regs + S3_MIN_AXIS_PCNT)) = height - 1;
+ *((u_short volatile *)(regs + S3_MAJ_AXIS_PCNT)) = width - 1;
- *((u_short volatile *)(CyberRegs + S3_CMD)) = blitcmd;
+ *((u_short volatile *)(regs + S3_CMD)) = blitcmd;
DPRINTK("EXIT\n");
}
+
+#if 0
/**************************************************************
* Move cursor to x, y
*/
static void Cyber_MoveCursor (u_short x, u_short y)
{
+ volatile unsigned char *regs = CyberRegs;
DPRINTK("ENTER\n");
- *(CyberRegs + S3_CRTC_ADR) = 0x39;
- *(CyberRegs + S3_CRTC_DATA) = 0xa0;
-
- *(CyberRegs + S3_CRTC_ADR) = S3_HWGC_ORGX_H;
- *(CyberRegs + S3_CRTC_DATA) = (char)((x & 0x0700) >> 8);
- *(CyberRegs + S3_CRTC_ADR) = S3_HWGC_ORGX_L;
- *(CyberRegs + S3_CRTC_DATA) = (char)(x & 0x00ff);
-
- *(CyberRegs + S3_CRTC_ADR) = S3_HWGC_ORGY_H;
- *(CyberRegs + S3_CRTC_DATA) = (char)((y & 0x0700) >> 8);
- *(CyberRegs + S3_CRTC_ADR) = S3_HWGC_ORGY_L;
- *(CyberRegs + S3_CRTC_DATA) = (char)(y & 0x00ff);
+ *(regs + S3_CRTC_ADR) = 0x39;
+ *(regs + S3_CRTC_DATA) = 0xa0;
+
+ *(regs + S3_CRTC_ADR) = S3_HWGC_ORGX_H;
+ *(regs + S3_CRTC_DATA) = (char)((x & 0x0700) >> 8);
+ *(regs + S3_CRTC_ADR) = S3_HWGC_ORGX_L;
+ *(regs + S3_CRTC_DATA) = (char)(x & 0x00ff);
+
+ *(regs + S3_CRTC_ADR) = S3_HWGC_ORGY_H;
+ *(regs + S3_CRTC_DATA) = (char)((y & 0x0700) >> 8);
+ *(regs + S3_CRTC_ADR) = S3_HWGC_ORGY_L;
+ *(regs + S3_CRTC_DATA) = (char)(y & 0x00ff);
DPRINTK("EXIT\n");
}
-
-
-/* -------------------- Interfaces to hardware functions -------------------- */
-
-
-static struct fb_hwswitch Cyber_switch = {
- Cyber_init, Cyber_encode_fix, Cyber_decode_var, Cyber_encode_var,
- Cyber_getcolreg, Cyber_setcolreg, Cyber_blank
-};
+#endif
/* -------------------- Generic routines ---------------------------------- */
@@ -786,7 +760,7 @@ static void cyberfb_get_par(struct cyberfb_par *par)
if (current_par_valid) {
*par = current_par;
} else {
- fbhw->decode_var(&cyberfb_default, par);
+ Cyber_decode_var(&cyberfb_default, par);
}
DPRINTK("EXIT\n");
}
@@ -819,14 +793,14 @@ static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
struct cyberfb_par par;
DPRINTK("ENTER\n");
- if ((err = fbhw->decode_var(var, &par))) {
+ if ((err = Cyber_decode_var(var, &par))) {
DPRINTK("EXIT - decode_var failed\n");
return(err);
}
activate = var->activate;
if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW && isactive)
cyberfb_set_par(&par);
- fbhw->encode_var(var, &par);
+ Cyber_encode_var(var, &par);
var->activate = activate;
cyber_set_video(var);
@@ -844,11 +818,11 @@ static void do_install_cmap(int con, struct fb_info *info)
}
if (fb_display[con].cmap.len) {
DPRINTK("Use console cmap\n");
- fb_set_cmap(&fb_display[con].cmap, 1, fbhw->setcolreg, info);
+ fb_set_cmap(&fb_display[con].cmap, 1, Cyber_setcolreg, info);
} else {
DPRINTK("Use default cmap\n");
fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
- 1, fbhw->setcolreg, info);
+ 1, Cyber_setcolreg, info);
}
DPRINTK("EXIT\n");
}
@@ -889,10 +863,10 @@ static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con,
if (con == -1) {
cyberfb_get_par(&par);
} else {
- error = fbhw->decode_var(&fb_display[con].var, &par);
+ error = Cyber_decode_var(&fb_display[con].var, &par);
}
DPRINTK("EXIT\n");
- return(error ? error : fbhw->encode_fix(fix, &par));
+ return(error ? error : Cyber_encode_fix(fix, &par));
}
@@ -909,7 +883,7 @@ static int cyberfb_get_var(struct fb_var_screeninfo *var, int con,
DPRINTK("ENTER\n");
if (con == -1) {
cyberfb_get_par(&par);
- error = fbhw->encode_var(var, &par);
+ error = Cyber_encode_var(var, &par);
disp.var = *var; /* ++Andre: don't know if this is the right place */
} else {
*var = fb_display[con].var;
@@ -934,7 +908,7 @@ static void cyberfb_set_disp(int con, struct fb_info *info)
cyberfb_get_fix(&fix, con, info);
if (con == -1)
con = 0;
- display->screen_base = phys_to_virt ((unsigned long) fix.smem_start);
+ display->screen_base = (unsigned char *)CyberMem;
display->visual = fix.visual;
display->type = fix.type;
display->type_aux = fix.type_aux;
@@ -1014,7 +988,7 @@ static int cyberfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
DPRINTK("ENTER\n");
if (con == currcon) { /* current console? */
DPRINTK("EXIT - console is current console\n");
- return(fb_get_cmap(cmap, kspc, fbhw->getcolreg, info));
+ return(fb_get_cmap(cmap, kspc, Cyber_getcolreg, info));
} else if (fb_display[con].cmap.len) { /* non default colormap? */
DPRINTK("Use console cmap\n");
fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
@@ -1048,7 +1022,7 @@ static int cyberfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
}
if (con == currcon) { /* current console? */
DPRINTK("EXIT - Current console\n");
- return(fb_set_cmap(cmap, kspc, fbhw->setcolreg, info));
+ return(fb_set_cmap(cmap, kspc, Cyber_setcolreg, info));
} else {
fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
}
@@ -1066,7 +1040,7 @@ static int cyberfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
static int cyberfb_pan_display(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
- return(-EINVAL);
+ return -EINVAL;
}
@@ -1077,7 +1051,7 @@ static int cyberfb_pan_display(struct fb_var_screeninfo *var, int con,
static int cyberfb_ioctl(struct inode *inode, struct file *file,
u_int cmd, u_long arg, int con, struct fb_info *info)
{
- return(-EINVAL);
+ return -EINVAL;
}
@@ -1088,7 +1062,7 @@ static struct fb_ops cyberfb_ops = {
};
-__initfunc(void cyberfb_setup(char *options, int *ints))
+int __init cyberfb_setup(char *options)
{
char *this_opt;
DPRINTK("ENTER\n");
@@ -1097,7 +1071,7 @@ __initfunc(void cyberfb_setup(char *options, int *ints))
if (!options || !*options) {
DPRINTK("EXIT - no options\n");
- return;
+ return 0;
}
for (this_opt = strtok(options, ","); this_opt;
@@ -1109,8 +1083,10 @@ __initfunc(void cyberfb_setup(char *options, int *ints))
strcpy(fb_info.fontname, this_opt+5);
} else if (!strcmp (this_opt, "cyber8")) {
cyberfb_default = cyberfb_predefined[CYBER8_DEFMODE].var;
+ cyberfb_usermode = 1;
} else if (!strcmp (this_opt, "cyber16")) {
cyberfb_default = cyberfb_predefined[CYBER16_DEFMODE].var;
+ cyberfb_usermode = 1;
} else get_video_mode(this_opt);
}
@@ -1119,13 +1095,14 @@ __initfunc(void cyberfb_setup(char *options, int *ints))
cyberfb_default.yres,
cyberfb_default.bits_per_pixel);
DPRINTK("EXIT\n");
+ return 0;
}
/*
* Initialization
*/
-__initfunc(void cyberfb_init(void))
+int __init cyberfb_init(void)
{
struct cyberfb_par par;
unsigned long board_addr;
@@ -1136,7 +1113,7 @@ __initfunc(void cyberfb_init(void))
if (!(CyberKey = zorro_find(ZORRO_PROD_PHASE5_CYBERVISION64, 0, 0))) {
DPRINTK("EXIT - zorro_find failed\n");
- return;
+ return -ENXIO;
}
cd = zorro_get_board (CyberKey);
@@ -1146,14 +1123,12 @@ __initfunc(void cyberfb_init(void))
DPRINTK("board_addr=%08lx\n", board_addr);
DPRINTK("board_size=%08lx\n", board_size);
- cv64_mem = ioremap(board_addr, board_size);
- cv64_regs = (volatile char *)(cv64_mem + 0x02000000);
- cv64_fbmem = cv64_mem + 0x01400000;
- DPRINTK("cv64_mem=%08lx cv64_regs=%08lx cv64_fbmem=%08lx\n",
- cv64_mem, (long unsigned int)cv64_regs, cv64_fbmem);
+ CyberBase = ioremap(board_addr, board_size);
+ CyberRegs = CyberBase + 0x02000000;
+ CyberMem = CyberBase + 0x01400000;
+ DPRINTK("CyberBase=%08lx CyberRegs=%08lx CyberMem=%08lx\n",
+ CyberBase, (long unsigned int)CyberRegs, CyberMem);
- CyberMem = cv64_fbmem;
- CyberRegs = cv64_regs;
CyberMem_phys = board_addr + 0x01400000;
CyberRegs_phys = CyberMem_phys + 0x00c00000;
DPRINTK("CyberMem=%08lx CyberRegs=%08lx\n", CyberMem,
@@ -1164,8 +1139,6 @@ __initfunc(void cyberfb_init(void))
cv64_dump();
#endif
- fbhw = &Cyber_switch;
-
strcpy(fb_info.modename, cyberfb_name);
fb_info.changevar = NULL;
fb_info.node = -1;
@@ -1175,9 +1148,14 @@ __initfunc(void cyberfb_init(void))
fb_info.updatevar = &Cyberfb_updatevar;
fb_info.blank = &Cyberfb_blank;
- fbhw->init();
- fbhw->decode_var(&cyberfb_default, &par);
- fbhw->encode_var(&cyberfb_default, &par);
+ Cyber_init();
+ /* ++Andre: set cyberfb default mode */
+ if (!cyberfb_usermode) {
+ cyberfb_default = cyberfb_predefined[CYBER8_DEFMODE].var;
+ DPRINTK("Use default cyber8 mode\n");
+ }
+ Cyber_decode_var(&cyberfb_default, &par);
+ Cyber_encode_var(&cyberfb_default, &par);
do_fb_set_var(&cyberfb_default, 1);
cyberfb_get_var(&fb_display[0].var, -1, &fb_info);
@@ -1186,7 +1164,7 @@ __initfunc(void cyberfb_init(void))
if (register_framebuffer(&fb_info) < 0) {
DPRINTK("EXIT - register_framebuffer failed\n");
- return;
+ return -EINVAL;
}
printk("fb%d: %s frame buffer device, using %ldK of video memory\n",
@@ -1195,6 +1173,7 @@ __initfunc(void cyberfb_init(void))
/* TODO: This driver cannot be unloaded yet */
MOD_INC_USE_COUNT;
DPRINTK("EXIT\n");
+ return 0;
}
@@ -1203,7 +1182,7 @@ static int Cyberfb_switch(int con, struct fb_info *info)
DPRINTK("ENTER\n");
/* Do we have to save the colormap? */
if (fb_display[currcon].cmap.len) {
- fb_get_cmap(&fb_display[currcon].cmap, 1, fbhw->getcolreg,
+ fb_get_cmap(&fb_display[currcon].cmap, 1, Cyber_getcolreg,
info);
}
@@ -1231,22 +1210,10 @@ static int Cyberfb_updatevar(int con, struct fb_info *info)
/*
- * Blank the display.
- */
-
-static void Cyberfb_blank(int blank, struct fb_info *info)
-{
- DPRINTK("Enter\n");
- fbhw->blank(blank);
- DPRINTK("Exit\n");
-}
-
-
-/*
* Get a Video Mode
*/
-__initfunc(static int get_video_mode(const char *name))
+static int __init get_video_mode(const char *name)
{
int i;
@@ -1254,13 +1221,11 @@ __initfunc(static int get_video_mode(const char *name))
for (i = 0; i < NUM_TOTAL_MODES; i++) {
if (!strcmp(name, cyberfb_predefined[i].name)) {
cyberfb_default = cyberfb_predefined[i].var;
+ cyberfb_usermode = 1;
DPRINTK("EXIT - Matched predefined mode\n");
return(i);
}
}
- /* ++Andre: set cyberfb default mode */
- cyberfb_default = cyberfb_predefined[CYBER8_DEFMODE].var;
- DPRINTK("EXIT - Use default cyber8 mode\n");
return(0);
}
@@ -1336,8 +1301,7 @@ static struct display_switch fbcon_cyber8 = {
#ifdef MODULE
int init_module(void)
{
- cyberfb_init();
- return 0;
+ return cyberfb_init();
}
void cleanup_module(void)
@@ -1454,71 +1418,38 @@ unsigned char cvconscolors[16][3] = { /* background, foreground, hilite */
};
/* -------------------- Hardware specific routines ------------------------- */
-#if 0
-/* ARB Generates 100 usec delay */
-inline void __cv_delay (unsigned long usecs)
-{
- int k;
-
- for (k = 0; k < 1000; k++) {
- asm volatile ("nop");
- }
-}
-#endif
-
-/* Wait while Graphics Engine is busy */
-inline void GfxBusyWait (volatile caddr_t board)
-{
- int test;
- DPRINTK("ENTER\n");
-
- do {
- test = vgar16 (board, ECR_GP_STAT);
- asm volatile ("nop");
- } while (test & (1 << 9));
- DPRINTK("EXIT\n");
-}
-
-/* Wait for any of the 8 Trio32 FIFOs to be free */
-inline void GfxFifoWait (volatile caddr_t board)
-{
- int test;
- DPRINTK("ENTER\n");
-
- do {
- test = vgar16 (board, ECR_GP_STAT);
- } while (test & 0x0f);
- DPRINTK("EXIT\n");
-}
/* Read Attribute Controller Register=idx */
-inline unsigned char RAttr (volatile caddr_t board, short idx)
+inline unsigned char RAttr (volatile unsigned char *regs, short idx)
{
- vgaw (board, ACT_ADDRESS_W, idx);
+ wb_64 (regs, ACT_ADDRESS_W, idx);
+ mb();
udelay(100);
- /* __cv_delay (0); */
- return (vgar (board, ACT_ADDRESS_R));
+ return (rb_64(regs, ACT_ADDRESS_R));
}
/* Read Sequencer Register=idx */
-inline unsigned char RSeq (volatile caddr_t board, short idx)
+inline unsigned char RSeq (volatile unsigned char *regs, short idx)
{
- vgaw (board, SEQ_ADDRESS, idx);
- return (vgar (board, SEQ_ADDRESS_R));
+ wb_64 (regs, SEQ_ADDRESS, idx);
+ mb();
+ return (rb_64(regs, SEQ_ADDRESS_R));
}
/* Read CRT Controller Register=idx */
-inline unsigned char RCrt (volatile caddr_t board, short idx)
+inline unsigned char RCrt (volatile unsigned char *regs, short idx)
{
- vgaw (board, CRT_ADDRESS, idx);
- return (vgar (board, CRT_ADDRESS_R));
+ wb_64 (regs, CRT_ADDRESS, idx);
+ mb();
+ return (rb_64(regs, CRT_ADDRESS_R));
}
/* Read Graphics Controller Register=idx */
-inline unsigned char RGfx (volatile caddr_t board, short idx)
+inline unsigned char RGfx (volatile unsigned char *regs, short idx)
{
- vgaw (board, GCT_ADDRESS, idx);
- return (vgar (board, GCT_ADDRESS_R));
+ wb_64 (regs, GCT_ADDRESS, idx);
+ mb();
+ return (rb_64(regs, GCT_ADDRESS_R));
}
/*
@@ -1526,13 +1457,13 @@ inline unsigned char RGfx (volatile caddr_t board, short idx)
*/
inline void cv64_write_port (unsigned short bits,
- volatile unsigned char *board)
+ volatile unsigned char *base)
{
volatile unsigned char *addr;
static unsigned char cvportbits = 0; /* Mirror port bits here */
DPRINTK("ENTER\n");
- addr = board + 0x40001;
+ addr = base + 0x40001;
if (bits & 0x8000) {
cvportbits |= bits & 0xff; /* Set bits */
DPRINTK("Set bits: %04x\n", bits);
@@ -1542,7 +1473,7 @@ inline void cv64_write_port (unsigned short bits,
cvportbits &= bits; /* Clear bits */
DPRINTK("Clear bits: %04x\n", bits);
}
-
+
*addr = cvportbits;
DPRINTK("EXIT\n");
}
@@ -1572,7 +1503,7 @@ inline void cvscreen (int toggle, volatile unsigned char *board)
/* Control screen display */
/* toggle: 0 = on, 1 = off */
/* board = registerbase */
-inline void gfx_on_off (int toggle, volatile unsigned char *board)
+inline void gfx_on_off(int toggle, volatile unsigned char *regs)
{
int r;
DPRINTK("ENTER\n");
@@ -1581,10 +1512,10 @@ inline void gfx_on_off (int toggle, volatile unsigned char *board)
toggle = toggle << 5;
DPRINTK("Turn display %s\n", (toggle ? "off" : "on"));
- r = (int) RSeq ((volatile caddr_t) board, SEQ_ID_CLOCKING_MODE);
+ r = (int) RSeq(regs, SEQ_ID_CLOCKING_MODE);
r &= 0xdf; /* Set bit 5 to 0 */
- WSeq (board, SEQ_ID_CLOCKING_MODE, r | toggle);
+ WSeq (regs, SEQ_ID_CLOCKING_MODE, r | toggle);
DPRINTK("EXIT\n");
}
@@ -1640,11 +1571,11 @@ static unsigned short cv64_compute_clock(unsigned long freq)
return (erg);
}
-static int cv_has_4mb (volatile caddr_t fb)
+static int cv_has_4mb (volatile unsigned char *fb)
{
volatile unsigned long *tr, *tw;
DPRINTK("ENTER\n");
-
+
/* write patterns in memory and test if they can be read */
tw = (volatile unsigned long *) fb;
tr = (volatile unsigned long *) (fb + 0x02000000);
@@ -1655,41 +1586,42 @@ static int cv_has_4mb (volatile caddr_t fb)
DPRINTK("EXIT - <4MB\n");
return (0);
}
-
+
/* upper memory region */
tw = (volatile unsigned long *) (fb + 0x00200000);
tr = (volatile unsigned long *) (fb + 0x02200000);
-
+
*tw = 0x87654321;
-
+
if (*tr != 0x87654321) {
DPRINTK("EXIT - <4MB\n");
return (0);
}
-
+
*tw = 0xAAAAAAAA;
-
+
if (*tr != 0xAAAAAAAA) {
DPRINTK("EXIT - <4MB\n");
return (0);
}
-
+
*tw = 0x55555555;
-
+
if (*tr != 0x55555555) {
DPRINTK("EXIT - <4MB\n");
return (0);
}
-
+
DPRINTK("EXIT\n");
return (1);
}
static void cv64_board_init (void)
{
+ volatile unsigned char *regs = CyberRegs;
int i;
- unsigned char test;
unsigned int clockpar;
+ unsigned char test;
DPRINTK("ENTER\n");
@@ -1698,259 +1630,252 @@ static void cv64_board_init (void)
*/
/* Reset board */
for (i = 0; i < 6; i++) {
- cv64_write_port (0xff, (volatile unsigned char *) cv64_mem);
+ cv64_write_port (0xff, CyberBase);
}
/* Return to operational mode */
- cv64_write_port (0x8004, (volatile unsigned char *) cv64_mem);
+ cv64_write_port (0x8004, CyberBase);
- /*
- * Generic (?) S3 chip wakeup
- */
- /* Disable I/O & memory decoders, video in setup mode */
- vgaw (cv64_regs, SREG_VIDEO_SUBS_ENABLE, 0x10);
- /* Video responds to cmds, addrs & data */
- vgaw (cv64_regs, SREG_OPTION_SELECT, 0x1);
- /* Enable I/O & memory decoders, video in operational mode */
- vgaw (cv64_regs, SREG_VIDEO_SUBS_ENABLE, 0x8);
- /* VGA color emulation, enable cpu access to display mem */
- vgaw (cv64_regs, GREG_MISC_OUTPUT_W, 0x03);
- /* Unlock S3 VGA regs */
- WCrt (cv64_regs, CRT_ID_REGISTER_LOCK_1, 0x48);
- /* Unlock system control & extension registers */
- WCrt (cv64_regs, CRT_ID_REGISTER_LOCK_2, 0xA5);
+ /*
+ * Generic (?) S3 chip wakeup
+ */
+ /* Disable I/O & memory decoders, video in setup mode */
+ wb_64 (regs, SREG_VIDEO_SUBS_ENABLE, 0x10);
+ /* Video responds to cmds, addrs & data */
+ wb_64 (regs, SREG_OPTION_SELECT, 0x1);
+ /* Enable I/O & memory decoders, video in operational mode */
+ wb_64 (regs, SREG_VIDEO_SUBS_ENABLE, 0x8);
+ /* VGA color emulation, enable cpu access to display mem */
+ wb_64 (regs, GREG_MISC_OUTPUT_W, 0x03);
+ /* Unlock S3 VGA regs */
+ WCrt (regs, CRT_ID_REGISTER_LOCK_1, 0x48);
+ /* Unlock system control & extension registers */
+ WCrt (regs, CRT_ID_REGISTER_LOCK_2, 0xA5);
/* GRF - Enable interrupts */
- /* Enable enhanced regs access, Ready cntl 0 wait states */
- test = RCrt (cv64_regs, CRT_ID_SYSTEM_CONFIG);
- test = test | 0x01; /* enable enhaced register access */
- test = test & 0xEF; /* clear bit 4, 0 wait state */
- WCrt (cv64_regs, CRT_ID_SYSTEM_CONFIG, test);
- /*
- * bit 0=1: Enable enhaced mode functions
- * bit 2=0: Enhanced mode 8+ bits/pixel
- * bit 4=1: Enable linear addressing
- * bit 5=1: Enable MMIO
- */
- vgaw (cv64_regs, ECR_ADV_FUNC_CNTL, 0x31);
- /*
- * bit 0=1: Color emulation
- * bit 1=1: Enable CPU access to display memory
- * bit 5=1: Select high 64K memory page
- */
+ /* Enable enhanced regs access, Ready cntl 0 wait states */
+ test = RCrt (regs, CRT_ID_SYSTEM_CONFIG);
+ test = test | 0x01; /* enable enhanced register access */
+ test = test & 0xEF; /* clear bit 4, 0 wait state */
+ WCrt (regs, CRT_ID_SYSTEM_CONFIG, test);
+ /*
+ * bit 0=1: Enable enhaced mode functions
+ * bit 2=0: Enhanced mode 8+ bits/pixel
+ * bit 4=1: Enable linear addressing
+ * bit 5=1: Enable MMIO
+ */
+ wb_64 (regs, ECR_ADV_FUNC_CNTL, 0x31);
+ /*
+ * bit 0=1: Color emulation
+ * bit 1=1: Enable CPU access to display memory
+ * bit 5=1: Select high 64K memory page
+ */
/* GRF - 0xE3 */
- vgaw (cv64_regs, GREG_MISC_OUTPUT_W, 0x23);
-
- /* Cpu base addr */
- WCrt (cv64_regs, CRT_ID_EXT_SYS_CNTL_4, 0x0);
-
- /* Reset. This does nothing on Trio, but standard VGA practice */
- /* WSeq (cv64_regs, SEQ_ID_RESET, 0x03); */
- /* Character clocks 8 dots wide */
- WSeq (cv64_regs, SEQ_ID_CLOCKING_MODE, 0x01);
- /* Enable cpu write to all color planes */
- WSeq (cv64_regs, SEQ_ID_MAP_MASK, 0x0F);
- /* Font table in 1st 8k of plane 2, font A=B disables swtich */
- WSeq (cv64_regs, SEQ_ID_CHAR_MAP_SELECT, 0x0);
- /* Allow mem access to 256kb */
- WSeq (cv64_regs, SEQ_ID_MEMORY_MODE, 0x2);
- /* Unlock S3 extensions to VGA Sequencer regs */
- WSeq (cv64_regs, SEQ_ID_UNLOCK_EXT, 0x6);
-
- /* Enable 4MB fast page mode */
- test = RSeq (cv64_regs, SEQ_ID_BUS_REQ_CNTL);
- test = test | 1 << 6;
- WSeq (cv64_regs, SEQ_ID_BUS_REQ_CNTL, test);
-
- /* Faster LUT write: 1 DCLK LUT write cycle, RAMDAC clk doubled */
- WSeq (cv64_regs, SEQ_ID_RAMDAC_CNTL, 0xC0);
-
- /* Clear immediate clock load bit */
- test = RSeq (cv64_regs, SEQ_ID_CLKSYN_CNTL_2);
- test = test & 0xDF;
- /* If > 55MHz, enable 2 cycle memory write */
- if (cv64_memclk >= 55000000) {
- test |= 0x80;
- }
- WSeq (cv64_regs, SEQ_ID_CLKSYN_CNTL_2, test);
-
- /* Set MCLK value */
- clockpar = cv64_compute_clock (cv64_memclk);
- test = (clockpar & 0xFF00) >> 8;
- WSeq (cv64_regs, SEQ_ID_MCLK_HI, test);
- test = clockpar & 0xFF;
- WSeq (cv64_regs, SEQ_ID_MCLK_LO, test);
-
- /* Chip rev specific: Not in my Trio manual!!! */
- if (RCrt (cv64_regs, CRT_ID_REVISION) == 0x10)
- WSeq (cv64_regs, SEQ_ID_MORE_MAGIC, test);
-
- /* We now load an 25 MHz, 31kHz, 640x480 standard VGA Mode. */
-
- /* Set DCLK value */
- WSeq (cv64_regs, SEQ_ID_DCLK_HI, 0x13);
- WSeq (cv64_regs, SEQ_ID_DCLK_LO, 0x41);
-
- /* Load DCLK (and MCLK?) immediately */
- test = RSeq (cv64_regs, SEQ_ID_CLKSYN_CNTL_2);
- test = test | 0x22;
- WSeq (cv64_regs, SEQ_ID_CLKSYN_CNTL_2, test);
-
- /* Enable loading of DCLK */
- test = vgar (cv64_regs, GREG_MISC_OUTPUT_R);
- test = test | 0x0C;
- vgaw (cv64_regs, GREG_MISC_OUTPUT_W, test);
-
- /* Turn off immediate xCLK load */
- WSeq (cv64_regs, SEQ_ID_CLKSYN_CNTL_2, 0x2);
-
- /* Horizontal character clock counts */
- /* 8 LSB of 9 bits = total line - 5 */
- WCrt (cv64_regs, CRT_ID_HOR_TOTAL, 0x5F);
- /* Active display line */
- WCrt (cv64_regs, CRT_ID_HOR_DISP_ENA_END, 0x4F);
- /* Blank assertion start */
- WCrt (cv64_regs, CRT_ID_START_HOR_BLANK, 0x50);
- /* Blank assertion end */
- WCrt (cv64_regs, CRT_ID_END_HOR_BLANK, 0x82);
- /* HSYNC assertion start */
- WCrt (cv64_regs, CRT_ID_START_HOR_RETR, 0x54);
- /* HSYNC assertion end */
- WCrt (cv64_regs, CRT_ID_END_HOR_RETR, 0x80);
- WCrt (cv64_regs, CRT_ID_VER_TOTAL, 0xBF);
- WCrt (cv64_regs, CRT_ID_OVERFLOW, 0x1F);
- WCrt (cv64_regs, CRT_ID_PRESET_ROW_SCAN, 0x0);
- WCrt (cv64_regs, CRT_ID_MAX_SCAN_LINE, 0x40);
- WCrt (cv64_regs, CRT_ID_CURSOR_START, 0x00);
- WCrt (cv64_regs, CRT_ID_CURSOR_END, 0x00);
- WCrt (cv64_regs, CRT_ID_START_ADDR_HIGH, 0x00);
- WCrt (cv64_regs, CRT_ID_START_ADDR_LOW, 0x00);
- WCrt (cv64_regs, CRT_ID_CURSOR_LOC_HIGH, 0x00);
- WCrt (cv64_regs, CRT_ID_CURSOR_LOC_LOW, 0x00);
- WCrt (cv64_regs, CRT_ID_START_VER_RETR, 0x9C);
- WCrt (cv64_regs, CRT_ID_END_VER_RETR, 0x0E);
- WCrt (cv64_regs, CRT_ID_VER_DISP_ENA_END, 0x8F);
- WCrt (cv64_regs, CRT_ID_SCREEN_OFFSET, 0x50);
- WCrt (cv64_regs, CRT_ID_UNDERLINE_LOC, 0x00);
- WCrt (cv64_regs, CRT_ID_START_VER_BLANK, 0x96);
- WCrt (cv64_regs, CRT_ID_END_VER_BLANK, 0xB9);
- WCrt (cv64_regs, CRT_ID_MODE_CONTROL, 0xE3);
- WCrt (cv64_regs, CRT_ID_LINE_COMPARE, 0xFF);
- WCrt (cv64_regs, CRT_ID_BACKWAD_COMP_3, 0x10); /* FIFO enabled */
- WCrt (cv64_regs, CRT_ID_MISC_1, 0x35);
- WCrt (cv64_regs, CRT_ID_DISPLAY_FIFO, 0x5A);
- WCrt (cv64_regs, CRT_ID_EXT_MEM_CNTL_2, 0x70);
- WCrt (cv64_regs, CRT_ID_LAW_POS_LO, 0x40);
- WCrt (cv64_regs, CRT_ID_EXT_MEM_CNTL_3, 0xFF);
-
- WGfx (cv64_regs, GCT_ID_SET_RESET, 0x0);
- WGfx (cv64_regs, GCT_ID_ENABLE_SET_RESET, 0x0);
- WGfx (cv64_regs, GCT_ID_COLOR_COMPARE, 0x0);
- WGfx (cv64_regs, GCT_ID_DATA_ROTATE, 0x0);
- WGfx (cv64_regs, GCT_ID_READ_MAP_SELECT, 0x0);
- WGfx (cv64_regs, GCT_ID_GRAPHICS_MODE, 0x40);
- WGfx (cv64_regs, GCT_ID_MISC, 0x01);
- WGfx (cv64_regs, GCT_ID_COLOR_XCARE, 0x0F);
- WGfx (cv64_regs, GCT_ID_BITMASK, 0xFF);
-
- /* Colors for text mode */
- for (i = 0; i < 0xf; i++)
- WAttr (cv64_regs, i, i);
-
- WAttr (cv64_regs, ACT_ID_ATTR_MODE_CNTL, 0x41);
- WAttr (cv64_regs, ACT_ID_OVERSCAN_COLOR, 0x01);
- WAttr (cv64_regs, ACT_ID_COLOR_PLANE_ENA, 0x0F);
- WAttr (cv64_regs, ACT_ID_HOR_PEL_PANNING, 0x0);
- WAttr (cv64_regs, ACT_ID_COLOR_SELECT, 0x0);
-
- vgaw (cv64_regs, VDAC_MASK, 0xFF);
-
- *((unsigned long *) (cv64_regs + ECR_FRGD_COLOR)) = 0xFF;
- *((unsigned long *) (cv64_regs + ECR_BKGD_COLOR)) = 0;
-
- /* Colors initially set to grayscale */
-
- vgaw (cv64_regs, VDAC_ADDRESS_W, 0);
- for (i = 255; i >= 0; i--) {
- vgaw (cv64_regs, VDAC_DATA, i);
- vgaw (cv64_regs, VDAC_DATA, i);
- vgaw (cv64_regs, VDAC_DATA, i);
- }
+ wb_64 (regs, GREG_MISC_OUTPUT_W, 0x23);
+
+ /* Cpu base addr */
+ WCrt (regs, CRT_ID_EXT_SYS_CNTL_4, 0x0);
+
+ /* Reset. This does nothing on Trio, but standard VGA practice */
+ /* WSeq (CyberRegs, SEQ_ID_RESET, 0x03); */
+ /* Character clocks 8 dots wide */
+ WSeq (regs, SEQ_ID_CLOCKING_MODE, 0x01);
+ /* Enable cpu write to all color planes */
+ WSeq (regs, SEQ_ID_MAP_MASK, 0x0F);
+ /* Font table in 1st 8k of plane 2, font A=B disables swtich */
+ WSeq (regs, SEQ_ID_CHAR_MAP_SELECT, 0x0);
+ /* Allow mem access to 256kb */
+ WSeq (regs, SEQ_ID_MEMORY_MODE, 0x2);
+ /* Unlock S3 extensions to VGA Sequencer regs */
+ WSeq (regs, SEQ_ID_UNLOCK_EXT, 0x6);
+
+ /* Enable 4MB fast page mode */
+ test = RSeq (regs, SEQ_ID_BUS_REQ_CNTL);
+ test = test | 1 << 6;
+ WSeq (regs, SEQ_ID_BUS_REQ_CNTL, test);
+
+ /* Faster LUT write: 1 DCLK LUT write cycle, RAMDAC clk doubled */
+ WSeq (regs, SEQ_ID_RAMDAC_CNTL, 0xC0);
+
+ /* Clear immediate clock load bit */
+ test = RSeq (regs, SEQ_ID_CLKSYN_CNTL_2);
+ test = test & 0xDF;
+ /* If > 55MHz, enable 2 cycle memory write */
+ if (cv64_memclk >= 55000000) {
+ test |= 0x80;
+ }
+ WSeq (regs, SEQ_ID_CLKSYN_CNTL_2, test);
+
+ /* Set MCLK value */
+ clockpar = cv64_compute_clock (cv64_memclk);
+ test = (clockpar & 0xFF00) >> 8;
+ WSeq (regs, SEQ_ID_MCLK_HI, test);
+ test = clockpar & 0xFF;
+ WSeq (regs, SEQ_ID_MCLK_LO, test);
+
+ /* Chip rev specific: Not in my Trio manual!!! */
+ if (RCrt (regs, CRT_ID_REVISION) == 0x10)
+ WSeq (regs, SEQ_ID_MORE_MAGIC, test);
+
+ /* We now load an 25 MHz, 31kHz, 640x480 standard VGA Mode. */
+
+ /* Set DCLK value */
+ WSeq (regs, SEQ_ID_DCLK_HI, 0x13);
+ WSeq (regs, SEQ_ID_DCLK_LO, 0x41);
+
+ /* Load DCLK (and MCLK?) immediately */
+ test = RSeq (regs, SEQ_ID_CLKSYN_CNTL_2);
+ test = test | 0x22;
+ WSeq (regs, SEQ_ID_CLKSYN_CNTL_2, test);
+
+ /* Enable loading of DCLK */
+ test = rb_64(regs, GREG_MISC_OUTPUT_R);
+ test = test | 0x0C;
+ wb_64 (regs, GREG_MISC_OUTPUT_W, test);
+
+ /* Turn off immediate xCLK load */
+ WSeq (regs, SEQ_ID_CLKSYN_CNTL_2, 0x2);
+
+ /* Horizontal character clock counts */
+ /* 8 LSB of 9 bits = total line - 5 */
+ WCrt (regs, CRT_ID_HOR_TOTAL, 0x5F);
+ /* Active display line */
+ WCrt (regs, CRT_ID_HOR_DISP_ENA_END, 0x4F);
+ /* Blank assertion start */
+ WCrt (regs, CRT_ID_START_HOR_BLANK, 0x50);
+ /* Blank assertion end */
+ WCrt (regs, CRT_ID_END_HOR_BLANK, 0x82);
+ /* HSYNC assertion start */
+ WCrt (regs, CRT_ID_START_HOR_RETR, 0x54);
+ /* HSYNC assertion end */
+ WCrt (regs, CRT_ID_END_HOR_RETR, 0x80);
+ WCrt (regs, CRT_ID_VER_TOTAL, 0xBF);
+ WCrt (regs, CRT_ID_OVERFLOW, 0x1F);
+ WCrt (regs, CRT_ID_PRESET_ROW_SCAN, 0x0);
+ WCrt (regs, CRT_ID_MAX_SCAN_LINE, 0x40);
+ WCrt (regs, CRT_ID_CURSOR_START, 0x00);
+ WCrt (regs, CRT_ID_CURSOR_END, 0x00);
+ WCrt (regs, CRT_ID_START_ADDR_HIGH, 0x00);
+ WCrt (regs, CRT_ID_START_ADDR_LOW, 0x00);
+ WCrt (regs, CRT_ID_CURSOR_LOC_HIGH, 0x00);
+ WCrt (regs, CRT_ID_CURSOR_LOC_LOW, 0x00);
+ WCrt (regs, CRT_ID_START_VER_RETR, 0x9C);
+ WCrt (regs, CRT_ID_END_VER_RETR, 0x0E);
+ WCrt (regs, CRT_ID_VER_DISP_ENA_END, 0x8F);
+ WCrt (regs, CRT_ID_SCREEN_OFFSET, 0x50);
+ WCrt (regs, CRT_ID_UNDERLINE_LOC, 0x00);
+ WCrt (regs, CRT_ID_START_VER_BLANK, 0x96);
+ WCrt (regs, CRT_ID_END_VER_BLANK, 0xB9);
+ WCrt (regs, CRT_ID_MODE_CONTROL, 0xE3);
+ WCrt (regs, CRT_ID_LINE_COMPARE, 0xFF);
+ WCrt (regs, CRT_ID_BACKWAD_COMP_3, 0x10); /* FIFO enabled */
+ WCrt (regs, CRT_ID_MISC_1, 0x35);
+ WCrt (regs, CRT_ID_DISPLAY_FIFO, 0x5A);
+ WCrt (regs, CRT_ID_EXT_MEM_CNTL_2, 0x70);
+ WCrt (regs, CRT_ID_LAW_POS_LO, 0x40);
+ WCrt (regs, CRT_ID_EXT_MEM_CNTL_3, 0xFF);
+
+ WGfx (regs, GCT_ID_SET_RESET, 0x0);
+ WGfx (regs, GCT_ID_ENABLE_SET_RESET, 0x0);
+ WGfx (regs, GCT_ID_COLOR_COMPARE, 0x0);
+ WGfx (regs, GCT_ID_DATA_ROTATE, 0x0);
+ WGfx (regs, GCT_ID_READ_MAP_SELECT, 0x0);
+ WGfx (regs, GCT_ID_GRAPHICS_MODE, 0x40);
+ WGfx (regs, GCT_ID_MISC, 0x01);
+ WGfx (regs, GCT_ID_COLOR_XCARE, 0x0F);
+ WGfx (regs, GCT_ID_BITMASK, 0xFF);
+
+ /* Colors for text mode */
+ for (i = 0; i < 0xf; i++)
+ WAttr (regs, i, i);
+
+ WAttr (regs, ACT_ID_ATTR_MODE_CNTL, 0x41);
+ WAttr (regs, ACT_ID_OVERSCAN_COLOR, 0x01);
+ WAttr (regs, ACT_ID_COLOR_PLANE_ENA, 0x0F);
+ WAttr (regs, ACT_ID_HOR_PEL_PANNING, 0x0);
+ WAttr (regs, ACT_ID_COLOR_SELECT, 0x0);
+
+ wb_64 (regs, VDAC_MASK, 0xFF);
+
+ *((unsigned long *) (regs + ECR_FRGD_COLOR)) = 0xFF;
+ *((unsigned long *) (regs + ECR_BKGD_COLOR)) = 0;
+
+ /* Colors initially set to grayscale */
+
+ wb_64 (regs, VDAC_ADDRESS_W, 0);
+ for (i = 255; i >= 0; i--) {
+ wb_64(regs, VDAC_DATA, i);
+ wb_64(regs, VDAC_DATA, i);
+ wb_64(regs, VDAC_DATA, i);
+ }
- /* GFx hardware cursor off */
- WCrt (cv64_regs, CRT_ID_HWGC_MODE, 0x00);
+ /* GFx hardware cursor off */
+ WCrt (regs, CRT_ID_HWGC_MODE, 0x00);
- /* Set first to 4MB, so test will work */
- WCrt (cv64_regs, CRT_ID_LAW_CNTL, 0x13);
- /* Find "correct" size of fbmem of Z3 board */
- if (cv_has_4mb ((volatile caddr_t) cv64_fbmem)) {
- cv64_size = 1024 * 1024 * 4;
- WCrt (cv64_regs, CRT_ID_LAW_CNTL, 0x13);
- DPRINTK("4MB board\n");
- } else {
- cv64_size = 1024 * 1024 * 2;
- WCrt (cv64_regs, CRT_ID_LAW_CNTL, 0x12);
- DPRINTK("2MB board\n");
- }
-
- /* Initialize graphics engine */
- Cyber_WaitBlit();
- /* GfxBusyWait (cv64_regs); */
- vgaw16 (cv64_regs, ECR_FRGD_MIX, 0x27);
- vgaw16 (cv64_regs, ECR_BKGD_MIX, 0x07);
- vgaw16 (cv64_regs, ECR_READ_REG_DATA, 0x1000);
- udelay(200);
- /* __cv_delay (200000); */
- vgaw16 (cv64_regs, ECR_READ_REG_DATA, 0x2000);
- Cyber_WaitBlit();
- /* GfxBusyWait (cv64_regs); */
- vgaw16 (cv64_regs, ECR_READ_REG_DATA, 0x3FFF);
- Cyber_WaitBlit();
- /* GfxBusyWait (cv64_regs); */
- udelay(200);
- /* __cv_delay (200000); */
- vgaw16 (cv64_regs, ECR_READ_REG_DATA, 0x4FFF);
- Cyber_WaitBlit();
- /* GfxBusyWait (cv64_regs); */
- vgaw16 (cv64_regs, ECR_BITPLANE_WRITE_MASK, ~0);
- Cyber_WaitBlit();
- /* GfxBusyWait (cv64_regs); */
- vgaw16 (cv64_regs, ECR_READ_REG_DATA, 0xE000);
- vgaw16 (cv64_regs, ECR_CURRENT_Y_POS2, 0x00);
- vgaw16 (cv64_regs, ECR_CURRENT_X_POS2, 0x00);
- vgaw16 (cv64_regs, ECR_READ_REG_DATA, 0xA000);
- vgaw16 (cv64_regs, ECR_DEST_Y__AX_STEP, 0x00);
- vgaw16 (cv64_regs, ECR_DEST_Y2__AX_STEP2, 0x00);
- vgaw16 (cv64_regs, ECR_DEST_X__DIA_STEP, 0x00);
- vgaw16 (cv64_regs, ECR_DEST_X2__DIA_STEP2, 0x00);
- vgaw16 (cv64_regs, ECR_SHORT_STROKE, 0x00);
- vgaw16 (cv64_regs, ECR_DRAW_CMD, 0x01);
-
- Cyber_WaitBlit();
- /* GfxBusyWait (cv64_regs); */
-
- vgaw16 (cv64_regs, ECR_READ_REG_DATA, 0x4FFF);
- vgaw16 (cv64_regs, ECR_BKGD_COLOR, 0x01);
- vgaw16 (cv64_regs, ECR_FRGD_COLOR, 0x00);
-
-
- /* Enable video display (set bit 5) */
+ /* Set first to 4MB, so test will work */
+ WCrt (regs, CRT_ID_LAW_CNTL, 0x13);
+ /* Find "correct" size of fbmem of Z3 board */
+ if (cv_has_4mb (CyberMem)) {
+ CyberSize = 1024 * 1024 * 4;
+ WCrt (regs, CRT_ID_LAW_CNTL, 0x13);
+ DPRINTK("4MB board\n");
+ } else {
+ CyberSize = 1024 * 1024 * 2;
+ WCrt (regs, CRT_ID_LAW_CNTL, 0x12);
+ DPRINTK("2MB board\n");
+ }
+
+ /* Initialize graphics engine */
+ Cyber_WaitBlit();
+ vgaw16 (regs, ECR_FRGD_MIX, 0x27);
+ vgaw16 (regs, ECR_BKGD_MIX, 0x07);
+ vgaw16 (regs, ECR_READ_REG_DATA, 0x1000);
+ udelay(200);
+ vgaw16 (regs, ECR_READ_REG_DATA, 0x2000);
+ Cyber_WaitBlit();
+ vgaw16 (regs, ECR_READ_REG_DATA, 0x3FFF);
+ Cyber_WaitBlit();
+ udelay(200);
+ vgaw16 (regs, ECR_READ_REG_DATA, 0x4FFF);
+ Cyber_WaitBlit();
+ vgaw16 (regs, ECR_BITPLANE_WRITE_MASK, ~0);
+ Cyber_WaitBlit();
+ vgaw16 (regs, ECR_READ_REG_DATA, 0xE000);
+ vgaw16 (regs, ECR_CURRENT_Y_POS2, 0x00);
+ vgaw16 (regs, ECR_CURRENT_X_POS2, 0x00);
+ vgaw16 (regs, ECR_READ_REG_DATA, 0xA000);
+ vgaw16 (regs, ECR_DEST_Y__AX_STEP, 0x00);
+ vgaw16 (regs, ECR_DEST_Y2__AX_STEP2, 0x00);
+ vgaw16 (regs, ECR_DEST_X__DIA_STEP, 0x00);
+ vgaw16 (regs, ECR_DEST_X2__DIA_STEP2, 0x00);
+ vgaw16 (regs, ECR_SHORT_STROKE, 0x00);
+ vgaw16 (regs, ECR_DRAW_CMD, 0x01);
+
+ Cyber_WaitBlit();
+
+ vgaw16 (regs, ECR_READ_REG_DATA, 0x4FFF);
+ vgaw16 (regs, ECR_BKGD_COLOR, 0x01);
+ vgaw16 (regs, ECR_FRGD_COLOR, 0x00);
+
+
+ /* Enable video display (set bit 5) */
/* ARB - Would also seem to write to AR13.
* May want to use parts of WAttr to set JUST bit 5
*/
- WAttr (cv64_regs, 0x33, 0);
+ WAttr (regs, 0x33, 0);
/* GRF - function code ended here */
- /* Turn gfx on again */
- gfx_on_off (0, cv64_regs);
-
- /* Pass-through */
- cvscreen (0, (volatile unsigned char *) cv64_mem);
+ /* Turn gfx on again */
+ gfx_on_off (0, regs);
+
+ /* Pass-through */
+ cvscreen (0, CyberBase);
- DPRINTK("EXIT\n");
+ DPRINTK("EXIT\n");
}
static void cv64_load_video_mode (struct fb_var_screeninfo *video_mode)
{
+ volatile unsigned char *regs = CyberRegs;
int fx, fy;
unsigned short mnr;
unsigned short HT, HDE, HBS, HBE, HSS, HSE, VDE, VBS, VBE, VSS, VSE, VT;
@@ -1977,7 +1902,7 @@ static void cv64_load_video_mode (struct fb_var_screeninfo *video_mode)
/* GRF - Disable interrupts */
- gfx_on_off (1, cv64_regs);
+ gfx_on_off (1, regs);
switch (video_mode->bits_per_pixel) {
case 15:
@@ -2049,7 +1974,7 @@ static void cv64_load_video_mode (struct fb_var_screeninfo *video_mode)
VT = yres + vfront + vsync + vback - 2;
}
- vgaw (cv64_regs, ECR_ADV_FUNC_CNTL, (TEXT ? 0x00 : 0x31));
+ wb_64 (regs, ECR_ADV_FUNC_CNTL, (TEXT ? 0x00 : 0x31));
if (TEXT)
HDE = ((video_mode->xres + fx - 1) / fx) - 1;
@@ -2058,15 +1983,15 @@ static void cv64_load_video_mode (struct fb_var_screeninfo *video_mode)
VDE = video_mode->yres - 1;
- WCrt (cv64_regs, CRT_ID_HWGC_MODE, 0x00);
- WCrt (cv64_regs, CRT_ID_EXT_DAC_CNTL, 0x00);
+ WCrt (regs, CRT_ID_HWGC_MODE, 0x00);
+ WCrt (regs, CRT_ID_EXT_DAC_CNTL, 0x00);
- WSeq (cv64_regs, SEQ_ID_MEMORY_MODE,
+ WSeq (regs, SEQ_ID_MEMORY_MODE,
(TEXT || (video_mode->bits_per_pixel == 1)) ? 0x06 : 0x0e);
- WGfx (cv64_regs, GCT_ID_READ_MAP_SELECT, 0x00);
- WSeq (cv64_regs, SEQ_ID_MAP_MASK,
+ WGfx (regs, GCT_ID_READ_MAP_SELECT, 0x00);
+ WSeq (regs, SEQ_ID_MAP_MASK,
(video_mode->bits_per_pixel == 1) ? 0x01 : 0xFF);
- WSeq (cv64_regs, SEQ_ID_CHAR_MAP_SELECT, 0x00);
+ WSeq (regs, SEQ_ID_CHAR_MAP_SELECT, 0x00);
/* cv64_compute_clock accepts arguments in Hz */
/* pixclock is in ps ... convert to Hz */
@@ -2081,11 +2006,11 @@ static void cv64_load_video_mode (struct fb_var_screeninfo *video_mode)
#endif
mnr = cv64_compute_clock (freq);
- WSeq (cv64_regs, SEQ_ID_DCLK_HI, ((mnr & 0xFF00) >> 8));
- WSeq (cv64_regs, SEQ_ID_DCLK_LO, (mnr & 0xFF));
+ WSeq (regs, SEQ_ID_DCLK_HI, ((mnr & 0xFF00) >> 8));
+ WSeq (regs, SEQ_ID_DCLK_LO, (mnr & 0xFF));
/* Load display parameters into board */
- WCrt (cv64_regs, CRT_ID_EXT_HOR_OVF,
+ WCrt (regs, CRT_ID_EXT_HOR_OVF,
((HT & 0x100) ? 0x01 : 0x00) |
((HDE & 0x100) ? 0x02 : 0x00) |
((HBS & 0x100) ? 0x04 : 0x00) |
@@ -2095,7 +2020,7 @@ static void cv64_load_video_mode (struct fb_var_screeninfo *video_mode)
(((HT-5) & 0x100) ? 0x40 : 0x00)
);
- WCrt (cv64_regs, CRT_ID_EXT_VER_OVF,
+ WCrt (regs, CRT_ID_EXT_VER_OVF,
0x40 |
((VT & 0x400) ? 0x01 : 0x00) |
((VDE & 0x400) ? 0x02 : 0x00) |
@@ -2103,18 +2028,18 @@ static void cv64_load_video_mode (struct fb_var_screeninfo *video_mode)
((VSS & 0x400) ? 0x10 : 0x00)
);
- WCrt (cv64_regs, CRT_ID_HOR_TOTAL, HT);
- WCrt (cv64_regs, CRT_ID_DISPLAY_FIFO, HT - 5);
- WCrt (cv64_regs, CRT_ID_HOR_DISP_ENA_END, ((HDE >= HBS) ? (HBS - 1) : HDE));
- WCrt (cv64_regs, CRT_ID_START_HOR_BLANK, HBS);
- WCrt (cv64_regs, CRT_ID_END_HOR_BLANK, ((HBE & 0x1F) | 0x80));
- WCrt (cv64_regs, CRT_ID_START_HOR_RETR, HSS);
- WCrt (cv64_regs, CRT_ID_END_HOR_RETR,
+ WCrt (regs, CRT_ID_HOR_TOTAL, HT);
+ WCrt (regs, CRT_ID_DISPLAY_FIFO, HT - 5);
+ WCrt (regs, CRT_ID_HOR_DISP_ENA_END, ((HDE >= HBS) ? (HBS - 1) : HDE));
+ WCrt (regs, CRT_ID_START_HOR_BLANK, HBS);
+ WCrt (regs, CRT_ID_END_HOR_BLANK, ((HBE & 0x1F) | 0x80));
+ WCrt (regs, CRT_ID_START_HOR_RETR, HSS);
+ WCrt (regs, CRT_ID_END_HOR_RETR,
(HSE & 0x1F) |
((HBE & 0x20) ? 0x80 : 0x00)
);
- WCrt (cv64_regs, CRT_ID_VER_TOTAL, VT);
- WCrt (cv64_regs, CRT_ID_OVERFLOW,
+ WCrt (regs, CRT_ID_VER_TOTAL, VT);
+ WCrt (regs, CRT_ID_OVERFLOW,
0x10 |
((VT & 0x100) ? 0x01 : 0x00) |
((VDE & 0x100) ? 0x02 : 0x00) |
@@ -2124,65 +2049,65 @@ static void cv64_load_video_mode (struct fb_var_screeninfo *video_mode)
((VDE & 0x200) ? 0x40 : 0x00) |
((VSS & 0x200) ? 0x80 : 0x00)
);
- WCrt (cv64_regs, CRT_ID_MAX_SCAN_LINE,
+ WCrt (regs, CRT_ID_MAX_SCAN_LINE,
0x40 |
(DBLSCAN ? 0x80 : 0x00) |
((VBS & 0x200) ? 0x20 : 0x00) |
(TEXT ? ((fy - 1) & 0x1F) : 0x00)
);
- WCrt (cv64_regs, CRT_ID_MODE_CONTROL, 0xE3);
+ WCrt (regs, CRT_ID_MODE_CONTROL, 0xE3);
/* Text cursor */
if (TEXT) {
#if 1
- WCrt (cv64_regs, CRT_ID_CURSOR_START, (fy & 0x1f) - 2);
- WCrt (cv64_regs, CRT_ID_CURSOR_END, (fy & 0x1F) - 1);
+ WCrt (regs, CRT_ID_CURSOR_START, (fy & 0x1f) - 2);
+ WCrt (regs, CRT_ID_CURSOR_END, (fy & 0x1F) - 1);
#else
- WCrt (cv64_regs, CRT_ID_CURSOR_START, 0x00);
- WCrt (cv64_regs, CRT_ID_CURSOR_END, fy & 0x1F);
+ WCrt (regs, CRT_ID_CURSOR_START, 0x00);
+ WCrt (regs, CRT_ID_CURSOR_END, fy & 0x1F);
#endif
- WCrt (cv64_regs, CRT_ID_UNDERLINE_LOC, (fy - 1) & 0x1F);
- WCrt (cv64_regs, CRT_ID_CURSOR_LOC_HIGH, 0x00);
- WCrt (cv64_regs, CRT_ID_CURSOR_LOC_LOW, 0x00);
+ WCrt (regs, CRT_ID_UNDERLINE_LOC, (fy - 1) & 0x1F);
+ WCrt (regs, CRT_ID_CURSOR_LOC_HIGH, 0x00);
+ WCrt (regs, CRT_ID_CURSOR_LOC_LOW, 0x00);
}
- WCrt (cv64_regs, CRT_ID_START_ADDR_HIGH, 0x00);
- WCrt (cv64_regs, CRT_ID_START_ADDR_LOW, 0x00);
- WCrt (cv64_regs, CRT_ID_START_VER_RETR, VSS);
- WCrt (cv64_regs, CRT_ID_END_VER_RETR, (VSE & 0x0F));
- WCrt (cv64_regs, CRT_ID_VER_DISP_ENA_END, VDE);
- WCrt (cv64_regs, CRT_ID_START_VER_BLANK, VBS);
- WCrt (cv64_regs, CRT_ID_END_VER_BLANK, VBE);
- WCrt (cv64_regs, CRT_ID_LINE_COMPARE, 0xFF);
- WCrt (cv64_regs, CRT_ID_LACE_RETR_START, HT / 2);
- WCrt (cv64_regs, CRT_ID_LACE_CONTROL, (LACE ? 0x20 : 0x00));
- WGfx (cv64_regs, GCT_ID_GRAPHICS_MODE,
+ WCrt (regs, CRT_ID_START_ADDR_HIGH, 0x00);
+ WCrt (regs, CRT_ID_START_ADDR_LOW, 0x00);
+ WCrt (regs, CRT_ID_START_VER_RETR, VSS);
+ WCrt (regs, CRT_ID_END_VER_RETR, (VSE & 0x0F));
+ WCrt (regs, CRT_ID_VER_DISP_ENA_END, VDE);
+ WCrt (regs, CRT_ID_START_VER_BLANK, VBS);
+ WCrt (regs, CRT_ID_END_VER_BLANK, VBE);
+ WCrt (regs, CRT_ID_LINE_COMPARE, 0xFF);
+ WCrt (regs, CRT_ID_LACE_RETR_START, HT / 2);
+ WCrt (regs, CRT_ID_LACE_CONTROL, (LACE ? 0x20 : 0x00));
+ WGfx (regs, GCT_ID_GRAPHICS_MODE,
((TEXT || (video_mode->bits_per_pixel == 1)) ? 0x00 : 0x40));
- WGfx (cv64_regs, GCT_ID_MISC, (TEXT ? 0x04 : 0x01));
- WSeq (cv64_regs, SEQ_ID_MEMORY_MODE,
+ WGfx (regs, GCT_ID_MISC, (TEXT ? 0x04 : 0x01));
+ WSeq (regs, SEQ_ID_MEMORY_MODE,
((TEXT || (video_mode->bits_per_pixel == 1)) ? 0x06 : 0x02));
- vgaw (cv64_regs, VDAC_MASK, 0xFF);
+ wb_64 (regs, VDAC_MASK, 0xFF);
/* Blank border */
- test = RCrt (cv64_regs, CRT_ID_BACKWAD_COMP_2);
- WCrt (cv64_regs, CRT_ID_BACKWAD_COMP_2, (test | 0x20));
+ test = RCrt (regs, CRT_ID_BACKWAD_COMP_2);
+ WCrt (regs, CRT_ID_BACKWAD_COMP_2, (test | 0x20));
- sr15 = RSeq (cv64_regs, SEQ_ID_CLKSYN_CNTL_2);
+ sr15 = RSeq (regs, SEQ_ID_CLKSYN_CNTL_2);
sr15 &= 0xEF;
- sr18 = RSeq (cv64_regs, SEQ_ID_RAMDAC_CNTL);
+ sr18 = RSeq (regs, SEQ_ID_RAMDAC_CNTL);
sr18 &= 0x7F;
clock_mode = 0x00;
cr50 = 0x00;
- test = RCrt (cv64_regs, CRT_ID_EXT_MISC_CNTL_2);
+ test = RCrt (regs, CRT_ID_EXT_MISC_CNTL_2);
test &= 0xD;
/* Clear roxxler byte-swapping... */
- cv64_write_port (0x0040, (volatile unsigned char *) cv64_mem);
- cv64_write_port (0x0020, (volatile unsigned char *) cv64_mem);
+ cv64_write_port (0x0040, CyberBase);
+ cv64_write_port (0x0020, CyberBase);
switch (video_mode->bits_per_pixel) {
case 1:
@@ -2201,14 +2126,14 @@ static void cv64_load_video_mode (struct fb_var_screeninfo *video_mode)
break;
case 15:
- cv64_write_port (0x8020, (volatile unsigned char *) cv64_mem);
+ cv64_write_port (0x8020, CyberBase);
clock_mode = 0x30;
HDE = video_mode->xres / 4;
cr50 |= 0x10;
break;
case 16:
- cv64_write_port (0x8020, (volatile unsigned char *) cv64_mem);
+ cv64_write_port (0x8020, CyberBase);
clock_mode = 0x50;
HDE = video_mode->xres / 4;
cr50 |= 0x10;
@@ -2216,24 +2141,24 @@ static void cv64_load_video_mode (struct fb_var_screeninfo *video_mode)
case 24:
case 32:
- cv64_write_port (0x8040, (volatile unsigned char *) cv64_mem);
+ cv64_write_port (0x8040, CyberBase);
clock_mode = 0xD0;
HDE = video_mode->xres / 2;
cr50 |= 0x30;
break;
}
-
- WCrt (cv64_regs, CRT_ID_EXT_MISC_CNTL_2, clock_mode | test);
- WSeq (cv64_regs, SEQ_ID_CLKSYN_CNTL_2, sr15);
- WSeq (cv64_regs, SEQ_ID_RAMDAC_CNTL, sr18);
- WCrt (cv64_regs, CRT_ID_SCREEN_OFFSET, HDE);
- WCrt (cv64_regs, CRT_ID_MISC_1, (TEXT ? 0x05 : 0x35));
+ WCrt (regs, CRT_ID_EXT_MISC_CNTL_2, clock_mode | test);
+ WSeq (regs, SEQ_ID_CLKSYN_CNTL_2, sr15);
+ WSeq (regs, SEQ_ID_RAMDAC_CNTL, sr18);
+ WCrt (regs, CRT_ID_SCREEN_OFFSET, HDE);
+
+ WCrt (regs, CRT_ID_MISC_1, (TEXT ? 0x05 : 0x35));
- test = RCrt (cv64_regs, CRT_ID_EXT_SYS_CNTL_2);
+ test = RCrt (regs, CRT_ID_EXT_SYS_CNTL_2);
test &= ~0x30;
test |= (HDE >> 4) & 0x30;
- WCrt (cv64_regs, CRT_ID_EXT_SYS_CNTL_2, test);
+ WCrt (regs, CRT_ID_EXT_SYS_CNTL_2, test);
/* Set up graphics engine */
switch (video_mode->xres) {
@@ -2265,17 +2190,14 @@ static void cv64_load_video_mode (struct fb_var_screeninfo *video_mode)
break;
}
- WCrt (cv64_regs, CRT_ID_EXT_SYS_CNTL_1, cr50);
+ WCrt (regs, CRT_ID_EXT_SYS_CNTL_1, cr50);
udelay(100);
- /* __cv_delay (100000); */
- WAttr (cv64_regs, ACT_ID_ATTR_MODE_CNTL, (TEXT ? 0x08 : 0x41));
+ WAttr (regs, ACT_ID_ATTR_MODE_CNTL, (TEXT ? 0x08 : 0x41));
udelay(100);
- /* __cv_delay (100000); */
- WAttr (cv64_regs, ACT_ID_COLOR_PLANE_ENA,
+ WAttr (regs, ACT_ID_COLOR_PLANE_ENA,
(video_mode->bits_per_pixel == 1) ? 0x01 : 0x0F);
udelay(100);
- /* __cv_delay (100000); */
tfillm = (96 * (cv64_memclk / 1000)) / 240000;
@@ -2304,10 +2226,9 @@ static void cv64_load_video_mode (struct fb_var_screeninfo *video_mode)
m = 0x18;
n = 0xFF;
- WCrt (cv64_regs, CRT_ID_EXT_MEM_CNTL_2, m);
- WCrt (cv64_regs, CRT_ID_EXT_MEM_CNTL_3, n);
+ WCrt (regs, CRT_ID_EXT_MEM_CNTL_2, m);
+ WCrt (regs, CRT_ID_EXT_MEM_CNTL_3, n);
udelay(10);
- /* __cv_delay (10000); */
/* Text initialization */
@@ -2317,21 +2238,21 @@ static void cv64_load_video_mode (struct fb_var_screeninfo *video_mode)
if (CONSOLE) {
int i;
- vgaw (cv64_regs, VDAC_ADDRESS_W, 0);
+ wb_64 (regs, VDAC_ADDRESS_W, 0);
for (i = 0; i < 4; i++) {
- vgaw (cv64_regs, VDAC_DATA, cvconscolors [i][0]);
- vgaw (cv64_regs, VDAC_DATA, cvconscolors [i][1]);
- vgaw (cv64_regs, VDAC_DATA, cvconscolors [i][2]);
+ wb_64 (regs, VDAC_DATA, cvconscolors [i][0]);
+ wb_64 (regs, VDAC_DATA, cvconscolors [i][1]);
+ wb_64 (regs, VDAC_DATA, cvconscolors [i][2]);
}
}
- WAttr (cv64_regs, 0x33, 0);
+ WAttr (regs, 0x33, 0);
/* Turn gfx on again */
- gfx_on_off (0, (volatile unsigned char *) cv64_regs);
+ gfx_on_off (0, (volatile unsigned char *) regs);
/* Pass-through */
- cvscreen (0, (volatile unsigned char *) cv64_mem);
+ cvscreen (0, CyberBase);
DPRINTK("EXIT\n");
}
@@ -2339,6 +2260,7 @@ DPRINTK("EXIT\n");
void cvision_bitblt (u_short sx, u_short sy, u_short dx, u_short dy,
u_short w, u_short h)
{
+ volatile unsigned char *regs = CyberRegs;
unsigned short drawdir = 0;
DPRINTK("ENTER\n");
@@ -2357,37 +2279,36 @@ void cvision_bitblt (u_short sx, u_short sy, u_short dx, u_short dy,
}
Cyber_WaitBlit();
- /* GfxBusyWait (cv64_regs); */
- vgaw16 (cv64_regs, ECR_READ_REG_DATA, 0xA000);
- vgaw16 (cv64_regs, ECR_BKGD_MIX, 0x7);
- vgaw16 (cv64_regs, ECR_FRGD_MIX, 0x67);
- vgaw16 (cv64_regs, ECR_BKGD_COLOR, 0x0);
- vgaw16 (cv64_regs, ECR_FRGD_COLOR, 0x1);
- vgaw16 (cv64_regs, ECR_BITPLANE_READ_MASK, 0x1);
- vgaw16 (cv64_regs, ECR_BITPLANE_WRITE_MASK, 0xFFF);
- vgaw16 (cv64_regs, ECR_CURRENT_Y_POS, sy);
- vgaw16 (cv64_regs, ECR_CURRENT_X_POS, sx);
- vgaw16 (cv64_regs, ECR_DEST_Y__AX_STEP, dy);
- vgaw16 (cv64_regs, ECR_DEST_X__DIA_STEP, dx);
- vgaw16 (cv64_regs, ECR_READ_REG_DATA, h - 1);
- vgaw16 (cv64_regs, ECR_MAJ_AXIS_PIX_CNT, w - 1);
- vgaw16 (cv64_regs, ECR_DRAW_CMD, 0xC051 | drawdir);
+ vgaw16 (regs, ECR_READ_REG_DATA, 0xA000);
+ vgaw16 (regs, ECR_BKGD_MIX, 0x7);
+ vgaw16 (regs, ECR_FRGD_MIX, 0x67);
+ vgaw16 (regs, ECR_BKGD_COLOR, 0x0);
+ vgaw16 (regs, ECR_FRGD_COLOR, 0x1);
+ vgaw16 (regs, ECR_BITPLANE_READ_MASK, 0x1);
+ vgaw16 (regs, ECR_BITPLANE_WRITE_MASK, 0xFFF);
+ vgaw16 (regs, ECR_CURRENT_Y_POS, sy);
+ vgaw16 (regs, ECR_CURRENT_X_POS, sx);
+ vgaw16 (regs, ECR_DEST_Y__AX_STEP, dy);
+ vgaw16 (regs, ECR_DEST_X__DIA_STEP, dx);
+ vgaw16 (regs, ECR_READ_REG_DATA, h - 1);
+ vgaw16 (regs, ECR_MAJ_AXIS_PIX_CNT, w - 1);
+ vgaw16 (regs, ECR_DRAW_CMD, 0xC051 | drawdir);
DPRINTK("EXIT\n");
}
void cvision_clear (u_short dx, u_short dy, u_short w, u_short h, u_short bg)
{
+ volatile unsigned char *regs = CyberRegs;
DPRINTK("ENTER\n");
Cyber_WaitBlit();
- /* GfxBusyWait (cv64_regs); */
- vgaw16 (cv64_regs, ECR_FRGD_MIX, 0x0027);
- vgaw16 (cv64_regs, ECR_FRGD_COLOR, bg);
- vgaw16 (cv64_regs, ECR_READ_REG_DATA, 0xA000);
- vgaw16 (cv64_regs, ECR_CURRENT_Y_POS, dy);
- vgaw16 (cv64_regs, ECR_CURRENT_X_POS, dx);
- vgaw16 (cv64_regs, ECR_READ_REG_DATA, h - 1);
- vgaw16 (cv64_regs, ECR_MAJ_AXIS_PIX_CNT, w - 1);
- vgaw16 (cv64_regs, ECR_DRAW_CMD, 0x40B1);
+ vgaw16 (regs, ECR_FRGD_MIX, 0x0027);
+ vgaw16 (regs, ECR_FRGD_COLOR, bg);
+ vgaw16 (regs, ECR_READ_REG_DATA, 0xA000);
+ vgaw16 (regs, ECR_CURRENT_Y_POS, dy);
+ vgaw16 (regs, ECR_CURRENT_X_POS, dx);
+ vgaw16 (regs, ECR_READ_REG_DATA, h - 1);
+ vgaw16 (regs, ECR_MAJ_AXIS_PIX_CNT, w - 1);
+ vgaw16 (regs, ECR_DRAW_CMD, 0x40B1);
DPRINTK("EXIT\n");
}
@@ -2397,83 +2318,84 @@ void cvision_clear (u_short dx, u_short dy, u_short w, u_short h, u_short bg)
*/
static void cv64_dump (void)
{
+ volatile unsigned char *regs = CyberRegs;
DPRINTK("ENTER\n");
/* Dump the VGA setup values */
- *(CyberRegs + S3_CRTC_ADR) = 0x00;
- DPRINTK("CR00 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x01;
- DPRINTK("CR01 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x02;
- DPRINTK("CR02 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x03;
- DPRINTK("CR03 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x04;
- DPRINTK("CR04 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x05;
- DPRINTK("CR05 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x06;
- DPRINTK("CR06 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x07;
- DPRINTK("CR07 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x08;
- DPRINTK("CR08 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x09;
- DPRINTK("CR09 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x10;
- DPRINTK("CR10 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x11;
- DPRINTK("CR11 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x12;
- DPRINTK("CR12 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x13;
- DPRINTK("CR13 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x15;
- DPRINTK("CR15 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x16;
- DPRINTK("CR16 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x36;
- DPRINTK("CR36 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x37;
- DPRINTK("CR37 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x42;
- DPRINTK("CR42 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x43;
- DPRINTK("CR43 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x50;
- DPRINTK("CR50 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x51;
- DPRINTK("CR51 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x53;
- DPRINTK("CR53 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x58;
- DPRINTK("CR58 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x59;
- DPRINTK("CR59 = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x5A;
- DPRINTK("CR5A = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x5D;
- DPRINTK("CR5D = %x\n", *(CyberRegs + S3_CRTC_DATA));
- *(CyberRegs + S3_CRTC_ADR) = 0x5E;
- DPRINTK("CR5E = %x\n", *(CyberRegs + S3_CRTC_DATA));
- DPRINTK("MISC = %x\n", *(CyberRegs + GREG_MISC_OUTPUT_R));
- *(CyberRegs + SEQ_ADDRESS) = 0x01;
- DPRINTK("SR01 = %x\n", *(CyberRegs + SEQ_ADDRESS_R));
- *(CyberRegs + SEQ_ADDRESS) = 0x02;
- DPRINTK("SR02 = %x\n", *(CyberRegs + SEQ_ADDRESS_R));
- *(CyberRegs + SEQ_ADDRESS) = 0x03;
- DPRINTK("SR03 = %x\n", *(CyberRegs + SEQ_ADDRESS_R));
- *(CyberRegs + SEQ_ADDRESS) = 0x09;
- DPRINTK("SR09 = %x\n", *(CyberRegs + SEQ_ADDRESS_R));
- *(CyberRegs + SEQ_ADDRESS) = 0x10;
- DPRINTK("SR10 = %x\n", *(CyberRegs + SEQ_ADDRESS_R));
- *(CyberRegs + SEQ_ADDRESS) = 0x11;
- DPRINTK("SR11 = %x\n", *(CyberRegs + SEQ_ADDRESS_R));
- *(CyberRegs + SEQ_ADDRESS) = 0x12;
- DPRINTK("SR12 = %x\n", *(CyberRegs + SEQ_ADDRESS_R));
- *(CyberRegs + SEQ_ADDRESS) = 0x13;
- DPRINTK("SR13 = %x\n", *(CyberRegs + SEQ_ADDRESS_R));
- *(CyberRegs + SEQ_ADDRESS) = 0x15;
- DPRINTK("SR15 = %x\n", *(CyberRegs + SEQ_ADDRESS_R));
+ *(regs + S3_CRTC_ADR) = 0x00;
+ DPRINTK("CR00 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x01;
+ DPRINTK("CR01 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x02;
+ DPRINTK("CR02 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x03;
+ DPRINTK("CR03 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x04;
+ DPRINTK("CR04 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x05;
+ DPRINTK("CR05 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x06;
+ DPRINTK("CR06 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x07;
+ DPRINTK("CR07 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x08;
+ DPRINTK("CR08 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x09;
+ DPRINTK("CR09 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x10;
+ DPRINTK("CR10 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x11;
+ DPRINTK("CR11 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x12;
+ DPRINTK("CR12 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x13;
+ DPRINTK("CR13 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x15;
+ DPRINTK("CR15 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x16;
+ DPRINTK("CR16 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x36;
+ DPRINTK("CR36 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x37;
+ DPRINTK("CR37 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x42;
+ DPRINTK("CR42 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x43;
+ DPRINTK("CR43 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x50;
+ DPRINTK("CR50 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x51;
+ DPRINTK("CR51 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x53;
+ DPRINTK("CR53 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x58;
+ DPRINTK("CR58 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x59;
+ DPRINTK("CR59 = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x5A;
+ DPRINTK("CR5A = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x5D;
+ DPRINTK("CR5D = %x\n", *(regs + S3_CRTC_DATA));
+ *(regs + S3_CRTC_ADR) = 0x5E;
+ DPRINTK("CR5E = %x\n", *(regs + S3_CRTC_DATA));
+ DPRINTK("MISC = %x\n", *(regs + GREG_MISC_OUTPUT_R));
+ *(regs + SEQ_ADDRESS) = 0x01;
+ DPRINTK("SR01 = %x\n", *(regs + SEQ_ADDRESS_R));
+ *(regs + SEQ_ADDRESS) = 0x02;
+ DPRINTK("SR02 = %x\n", *(regs + SEQ_ADDRESS_R));
+ *(regs + SEQ_ADDRESS) = 0x03;
+ DPRINTK("SR03 = %x\n", *(regs + SEQ_ADDRESS_R));
+ *(regs + SEQ_ADDRESS) = 0x09;
+ DPRINTK("SR09 = %x\n", *(regs + SEQ_ADDRESS_R));
+ *(regs + SEQ_ADDRESS) = 0x10;
+ DPRINTK("SR10 = %x\n", *(regs + SEQ_ADDRESS_R));
+ *(regs + SEQ_ADDRESS) = 0x11;
+ DPRINTK("SR11 = %x\n", *(regs + SEQ_ADDRESS_R));
+ *(regs + SEQ_ADDRESS) = 0x12;
+ DPRINTK("SR12 = %x\n", *(regs + SEQ_ADDRESS_R));
+ *(regs + SEQ_ADDRESS) = 0x13;
+ DPRINTK("SR13 = %x\n", *(regs + SEQ_ADDRESS_R));
+ *(regs + SEQ_ADDRESS) = 0x15;
+ DPRINTK("SR15 = %x\n", *(regs + SEQ_ADDRESS_R));
return;
}
diff --git a/drivers/video/cyberfb.h b/drivers/video/cyberfb.h
index bce02a462..2acff941a 100644
--- a/drivers/video/cyberfb.h
+++ b/drivers/video/cyberfb.h
@@ -128,26 +128,9 @@
#define GRFBBOPset 0xf /* 1 */
-/* Read VGA register */
-#define vgar(ba, reg) (*(((volatile caddr_t)ba)+reg))
-
-/* Write VGA register */
-#define vgaw(ba, reg, val) \
-*(((volatile caddr_t)ba)+reg) = ((val) & 0xff)
-
-/* Read 16 Bit VGA register */
-#define vgar16(ba, reg) ( *((unsigned short *) (((volatile caddr_t)ba)+reg)) )
-
/* Write 16 Bit VGA register */
#define vgaw16(ba, reg, val) \
-*((unsigned short *) (((volatile caddr_t)ba)+reg)) = val
-
-/* Read 32 Bit VGA register */
-#define vgar32(ba, reg) ( *((unsigned long *) (((volatile caddr_t)ba)+reg)) )
-
-/* Write 32 Bit VGA register */
-#define vgaw32(ba, reg, val) \
- *((unsigned long *) (((volatile caddr_t)ba)+reg)) = val
+*((unsigned short *) (((volatile unsigned char *)ba)+reg)) = val
/*
* Defines for the used register addresses (mw)
@@ -394,20 +377,20 @@
#define WGfx(ba, idx, val) \
-do { vgaw(ba, GCT_ADDRESS, idx); vgaw(ba, GCT_ADDRESS_W , val); } while (0)
+do { wb_64(ba, GCT_ADDRESS, idx); wb_64(ba, GCT_ADDRESS_W , val); } while (0)
#define WSeq(ba, idx, val) \
-do { vgaw(ba, SEQ_ADDRESS, idx); vgaw(ba, SEQ_ADDRESS_W , val); } while (0)
+do { wb_64(ba, SEQ_ADDRESS, idx); wb_64(ba, SEQ_ADDRESS_W , val); } while (0)
#define WCrt(ba, idx, val) \
-do { vgaw(ba, CRT_ADDRESS, idx); vgaw(ba, CRT_ADDRESS_W , val); } while (0)
+do { wb_64(ba, CRT_ADDRESS, idx); wb_64(ba, CRT_ADDRESS_W , val); } while (0)
#define WAttr(ba, idx, val) \
do { \
unsigned char tmp;\
- tmp = vgar(ba, ACT_ADDRESS_RESET);\
- vgaw(ba, ACT_ADDRESS_W, idx);\
- vgaw(ba, ACT_ADDRESS_W, val);\
+ tmp = rb_64(ba, ACT_ADDRESS_RESET);\
+ wb_64(ba, ACT_ADDRESS_W, idx);\
+ wb_64(ba, ACT_ADDRESS_W, val);\
} while (0)
#define SetTextPlane(ba, m) \
@@ -420,21 +403,17 @@ do { \
/* prototypes */
/* --------------------------------- */
-/* in cvision_core.c */
-inline void __cv_delay(unsigned long usecs);
-inline void GfxBusyWait(volatile caddr_t board);
-inline void GfxFifoWait(volatile caddr_t board);
-inline unsigned char RAttr(volatile caddr_t board, short idx);
-inline unsigned char RSeq(volatile caddr_t board, short idx);
-inline unsigned char RCrt(volatile caddr_t board, short idx);
-inline unsigned char RGfx(volatile caddr_t board, short idx);
+inline unsigned char RAttr(volatile unsigned char * board, short idx);
+inline unsigned char RSeq(volatile unsigned char * board, short idx);
+inline unsigned char RCrt(volatile unsigned char * board, short idx);
+inline unsigned char RGfx(volatile unsigned char * board, short idx);
inline void cv64_write_port(unsigned short bits,
volatile unsigned char *board);
inline void cvscreen(int toggle, volatile unsigned char *board);
inline void gfx_on_off(int toggle, volatile unsigned char *board);
#if 0
unsigned short cv64_compute_clock(unsigned long freq);
-int cv_has_4mb(volatile caddr_t fb);
+int cv_has_4mb(volatile unsigned char * fb);
void cv64_board_init(void);
void cv64_load_video_mode(struct fb_var_screeninfo *video_mode);
#endif
diff --git a/drivers/video/dnfb.c b/drivers/video/dnfb.c
index e0da396bf..c8a550eb8 100644
--- a/drivers/video/dnfb.c
+++ b/drivers/video/dnfb.c
@@ -169,7 +169,7 @@ static int dnfb_get_fix(struct fb_fix_screeninfo *fix, int con,
{
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id,"Apollo Mono");
- fix->smem_start=(char*)(FRAME_BUFFER_START+IO_BASE);
+ fix->smem_start=FRAME_BUFFER_START+IO_BASE;
fix->smem_len=FRAME_BUFFER_LEN;
fix->type=FB_TYPE_PACKED_PIXELS;
fix->type_aux=0;
@@ -310,7 +310,7 @@ static void dnfb_set_disp(int con, struct fb_info *info)
#endif
}
-void dnfb_init(void)
+int dnfb_init(void)
{
fb_info.changevar=NULL;
strcpy(&fb_info.modename[0],dnfb_name);
@@ -333,11 +333,14 @@ void dnfb_init(void)
dnfb_get_var(&disp[0].var, 0, &fb_info);
dnfb_set_disp(-1, &fb_info);
- if (register_framebuffer(&fb_info) < 0)
- panic("unable to register apollo frame buffer\n");
+ if (register_framebuffer(&fb_info) < 0) {
+ printk(KERN_ERR "unable to register apollo frame buffer\n");
+ return -EINVAL;
+ }
printk("fb%d: apollo frame buffer alive and kicking !\n",
GET_FB_IDX(fb_info.node));
+ return 0;
}
diff --git a/drivers/video/dummycon.c b/drivers/video/dummycon.c
index ea8743495..ecabee5e5 100644
--- a/drivers/video/dummycon.c
+++ b/drivers/video/dummycon.c
@@ -25,7 +25,7 @@
#define DUMMY_ROWS 25
#endif
-__initfunc(static const char *dummycon_startup(void))
+static const char __init *dummycon_startup(void)
{
return "dummy device";
}
diff --git a/drivers/video/fbcon-vga-planes.c b/drivers/video/fbcon-vga-planes.c
index 391ceb22e..3f500e694 100644
--- a/drivers/video/fbcon-vga-planes.c
+++ b/drivers/video/fbcon-vga-planes.c
@@ -44,7 +44,8 @@
OR. */
static inline void rmw(volatile char *p)
{
- *p |= 1;
+ readb(p);
+ writeb(1, p);
}
/* Set the Graphics Mode Register. Bits 0-1 are write mode, bit 3 is
@@ -122,8 +123,12 @@ void fbcon_vga_planes_bmove(struct display *p, int sy, int sx, int dy, int dx,
dest = p->screen_base + dx + dy * p->line_length;
src = p->screen_base + sx + sy * p->line_length;
while (height--) {
- for (x = 0; x < width; x++)
- *dest++ = *src++;
+ for (x = 0; x < width; x++) {
+ readb(src);
+ writeb(0, dest);
+ dest++;
+ src++;
+ }
src += line_ofs;
dest += line_ofs;
}
@@ -132,8 +137,12 @@ void fbcon_vga_planes_bmove(struct display *p, int sy, int sx, int dy, int dx,
dest = p->screen_base + dx + width + (dy + height - 1) * p->line_length;
src = p->screen_base + sx + width + (sy + height - 1) * p->line_length;
while (height--) {
- for (x = 0; x < width; x++)
- *--dest = *--src;
+ for (x = 0; x < width; x++) {
+ dest--;
+ src--;
+ readb(src);
+ writeb(0, dest);
+ }
src -= line_ofs;
dest -= line_ofs;
}
@@ -160,8 +169,10 @@ void fbcon_vga_planes_clear(struct vc_data *conp, struct display *p, int sy, int
where = p->screen_base + sx + sy * p->line_length;
while (height--) {
- for (x = 0; x < width; x++)
- *where++ = 0;
+ for (x = 0; x < width; x++) {
+ writeb(0, where);
+ where++;
+ }
where += line_ofs;
}
}
@@ -211,13 +222,13 @@ void fbcon_vga_planes_putc(struct vc_data *conp, struct display *p, int c, int y
selectmask();
setmask(0xff);
- *where = bg;
+ writeb(bg, where);
rmb();
- *(volatile char*)where; /* fill latches */
+ readb(where); /* fill latches */
setmode(3);
wmb();
for (y = 0; y < fontheight(p); y++, where += p->line_length)
- *where = cdat[y];
+ writeb(cdat[y], where);
wmb();
}
@@ -237,9 +248,9 @@ void fbcon_ega_planes_putcs(struct vc_data *conp, struct display *p, const unsig
setmask(0xff);
where = p->screen_base + xx + yy * p->line_length * fontheight(p);
- *where = bg;
+ writeb(bg, where);
rmb();
- *(volatile char*)where;
+ readb(where); /* fill latches */
wmb();
selectmask();
for (n = 0; n < count; n++) {
@@ -250,7 +261,7 @@ void fbcon_ega_planes_putcs(struct vc_data *conp, struct display *p, const unsig
while (cdat < end) {
outb(*cdat++, GRAPHICS_DATA_REG);
wmb();
- *where = fg;
+ writeb(fg, where);
where += p->line_length;
}
where += 1 - p->line_length * fontheight(p);
@@ -277,9 +288,9 @@ void fbcon_vga_planes_putcs(struct vc_data *conp, struct display *p, const unsig
setmask(0xff);
where = p->screen_base + xx + yy * p->line_length * fontheight(p);
- *where = bg;
+ writeb(bg, where);
rmb();
- *(volatile char*)where; /* fill latches with background */
+ readb(where); /* fill latches */
setmode(3);
wmb();
for (n = 0; n < count; n++) {
@@ -288,7 +299,7 @@ void fbcon_vga_planes_putcs(struct vc_data *conp, struct display *p, const unsig
u8 *cdat = p->fontdata + (c & p->charmask) * fontheight(p);
for (y = 0; y < fontheight(p); y++, cdat++) {
- *where = *cdat;
+ writeb (*cdat, where);
where += p->line_length;
}
where += 1 - p->line_length * fontheight(p);
diff --git a/drivers/video/fbcon.c b/drivers/video/fbcon.c
index 12ab76c65..b54d0b5a4 100644
--- a/drivers/video/fbcon.c
+++ b/drivers/video/fbcon.c
@@ -215,7 +215,7 @@ static int fbcon_show_logo(void);
#ifdef CONFIG_MAC
/*
- * On the Macintoy, there may or may not be a working VBL int. We need to prob
+ * On the Macintoy, there may or may not be a working VBL int. We need to probe
*/
static int vbl_detected = 0;
@@ -246,7 +246,7 @@ static void cursor_timer_handler(unsigned long dev_addr)
struct display_switch fbcon_dummy;
-/* NOTE: fbcon cannot be __initfunc: it may be called from take_over_console later */
+/* NOTE: fbcon cannot be __init: it may be called from take_over_console later */
static const char *fbcon_startup(void)
{
@@ -1951,7 +1951,7 @@ static inline unsigned safe_shift(unsigned d,int n)
return n<0 ? d>>-n : d<<n;
}
-__initfunc(static int fbcon_show_logo( void ))
+static int __init fbcon_show_logo( void )
{
struct display *p = &fb_display[fg_console]; /* draw to vt in foreground */
int depth = p->var.bits_per_pixel;
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 24e7ad742..a02920395 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -44,65 +44,67 @@
* Frame buffer device initialization and setup routines
*/
-extern void acornfb_init(void);
-extern void acornfb_setup(char *options, int *ints);
-extern void amifb_init(void);
-extern void amifb_setup(char *options, int *ints);
-extern void atafb_init(void);
-extern void atafb_setup(char *options, int *ints);
-extern void macfb_init(void);
-extern void macfb_setup(char *options, int *ints);
-extern void cyberfb_init(void);
-extern void cyberfb_setup(char *options, int *ints);
-extern void pm2fb_init(void);
-extern void pm2fb_setup(char *options, int *ints);
-extern void cyber2000fb_init(void);
-extern void cyber2000fb_setup(char *options, int *ints);
-extern void retz3fb_init(void);
-extern void retz3fb_setup(char *options, int *ints);
-extern void clgenfb_init(void);
-extern void clgenfb_setup(char *options, int *ints);
-extern void vfb_init(void);
-extern void vfb_setup(char *options, int *ints);
-extern void offb_init(void);
-extern void offb_setup(char *options, int *ints);
-extern void atyfb_init(void);
-extern void atyfb_setup(char *options, int *ints);
-extern void igafb_init(void);
-extern void igafb_setup(char *options, int *ints);
-extern void imsttfb_init(void);
-extern void imsttfb_setup(char *options, int *ints);
-extern void dnfb_init(void);
-extern void tgafb_init(void);
-extern void tgafb_setup(char *options, int *ints);
-extern void virgefb_init(void);
-extern void virgefb_setup(char *options, int *ints);
-extern void resolver_video_setup(char *options, int *ints);
-extern void s3triofb_init(void);
-extern void s3triofb_setup(char *options, int *ints);
-extern void vesafb_init(void);
-extern void vesafb_setup(char *options, int *ints);
-extern void vga16fb_init(void);
-extern void vga16fb_setup(char *options, int *ints);
-extern void matroxfb_init(void);
-extern void matroxfb_setup(char* options, int *ints);
-extern void hpfb_init(void);
-extern void hpfb_setup(char *options, int *ints);
-extern void sbusfb_init(void);
-extern void sbusfb_setup(char *options, int *ints);
-extern void valkyriefb_init(void);
-extern void valkyriefb_setup(char *options, int *ints);
-extern void g364fb_init(void);
-extern void fm2fb_init(void);
-extern void fm2fb_setup(char *options, int *ints);
-extern void q40fb_init(void);
-extern void sgivwfb_init(void);
-extern void sgivwfb_setup(char* options, int *ints);
+extern int acornfb_init(void);
+extern int acornfb_setup(char*);
+extern int amifb_init(void);
+extern int amifb_setup(char*);
+extern int atafb_init(void);
+extern int atafb_setup(char*);
+extern int macfb_init(void);
+extern int macfb_setup(char*);
+extern int cyberfb_init(void);
+extern int cyberfb_setup(char*);
+extern int pm2fb_init(void);
+extern int pm2fb_setup(char*);
+extern int cyber2000fb_init(void);
+extern int cyber2000fb_setup(char*);
+extern int retz3fb_init(void);
+extern int retz3fb_setup(char*);
+extern int clgenfb_init(void);
+extern int clgenfb_setup(char*);
+extern int vfb_init(void);
+extern int vfb_setup(char*);
+extern int offb_init(void);
+extern int offb_setup(char*);
+extern int atyfb_init(void);
+extern int atyfb_setup(char*);
+extern int igafb_init(void);
+extern int igafb_setup(char*);
+extern int imsttfb_init(void);
+extern int imsttfb_setup(char*);
+extern int dnfb_init(void);
+extern int tgafb_init(void);
+extern int tgafb_setup(char*);
+extern int virgefb_init(void);
+extern int virgefb_setup(char*);
+extern int resolver_video_setup(char*);
+extern int s3triofb_init(void);
+extern int s3triofb_setup(char*);
+extern int vesafb_init(void);
+extern int vesafb_setup(char*);
+extern int vga16fb_init(void);
+extern int vga16fb_setup(char*);
+extern int matroxfb_init(void);
+extern int matroxfb_setup(char*);
+extern int hpfb_init(void);
+extern int hpfb_setup(char*);
+extern int sbusfb_init(void);
+extern int sbusfb_setup(char*);
+extern int valkyriefb_init(void);
+extern int valkyriefb_setup(char*);
+extern int control_init(void);
+extern int control_setup(char*);
+extern int g364fb_init(void);
+extern int fm2fb_init(void);
+extern int fm2fb_setup(char*);
+extern int q40fb_init(void);
+extern int sgivwfb_init(void);
+extern int sgivwfb_setup(char*);
static struct {
const char *name;
- void (*init)(void);
- void (*setup)(char *options, int *ints);
+ int (*init)(void);
+ int (*setup)(char*);
} fb_drivers[] __initdata = {
#ifdef CONFIG_FB_SGIVW
{ "sgivw", sgivwfb_init, sgivwfb_setup },
@@ -176,6 +178,9 @@ static struct {
#ifdef CONFIG_FB_HP300
{ "hpfb", hpfb_init, hpfb_setup },
#endif
+#ifdef CONFIG_FB_CONTROL
+ { "controlfb", control_init, control_setup },
+#endif
#ifdef CONFIG_FB_VALKYRIE
{ "valkyriefb", valkyriefb_init, valkyriefb_setup },
#endif
@@ -197,7 +202,9 @@ static struct {
#define NUM_FB_DRIVERS (sizeof(fb_drivers)/sizeof(*fb_drivers))
-static void (*pref_init_funcs[FB_MAX])(void);
+extern const char *global_mode_option;
+
+static initcall_t pref_init_funcs[FB_MAX];
static int num_pref_init_funcs __initdata = 0;
@@ -214,7 +221,7 @@ static int first_fb_vc = 0;
static int last_fb_vc = MAX_NR_CONSOLES-1;
static int fbcon_is_default = 1;
-static int PROC_CONSOLE(struct fb_info *info)
+static int PROC_CONSOLE(const struct fb_info *info)
{
int fgc;
@@ -468,10 +475,18 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
return -ENODEV;
if (fb->fb_mmap)
return fb->fb_mmap(info, file, vma);
+
+#if defined(__sparc__)
+ /* Should never get here, all fb drivers should have their own
+ mmap routines */
+ return -EINVAL;
+#else
+ /* non-SPARC... */
+
fb->fb_get_fix(&fix, PROC_CONSOLE(info), info);
/* frame buffer memory */
- start = (unsigned long)fix.smem_start;
+ start = fix.smem_start;
len = (start & ~PAGE_MASK)+fix.smem_len;
start &= PAGE_MASK;
len = (len+~PAGE_MASK) & PAGE_MASK;
@@ -481,7 +496,7 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
fb->fb_get_var(&var, PROC_CONSOLE(info), info);
if (var.accel_flags)
return -EINVAL;
- start = (unsigned long)fix.mmio_start;
+ start = fix.mmio_start;
len = (start & ~PAGE_MASK)+fix.mmio_len;
start &= PAGE_MASK;
len = (len+~PAGE_MASK) & PAGE_MASK;
@@ -503,9 +518,6 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE|_PAGE_GUARDED;
#elif defined(__alpha__)
/* Caching is off in the I/O space quadrant by design. */
-#elif defined(__sparc__)
- /* Should never get here, all fb drivers should have their own
- mmap routines */
#elif defined(__i386__)
if (boot_cpu_data.x86 > 3)
pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
@@ -522,10 +534,12 @@ fb_mmap(struct file *file, struct vm_area_struct * vma)
#else
#warning What do we have to do here??
#endif
- if (remap_page_range(vma->vm_start, vma->vm_offset,
+ if (io_remap_page_range(vma->vm_start, vma->vm_offset,
vma->vm_end - vma->vm_start, vma->vm_page_prot))
return -EAGAIN;
return 0;
+
+#endif /* defined(__sparc__) */
}
static int
@@ -619,8 +633,8 @@ unregister_framebuffer(const struct fb_info *fb_info)
static struct proc_dir_entry *proc_fbmem;
-__initfunc(void
-fbmem_init(void))
+void __init
+fbmem_init(void)
{
int i;
@@ -679,12 +693,12 @@ int fbmon_dpms(const struct fb_info *fb_info)
* Command line options
*/
-__initfunc(void video_setup(char *options, int *ints))
+int __init video_setup(char *options)
{
int i, j;
if (!options || !*options)
- return;
+ return 0;
if (!strncmp(options, "scrollback:", 11)) {
options += 11;
@@ -695,10 +709,10 @@ __initfunc(void video_setup(char *options, int *ints))
options++;
}
if (*options != ',')
- return;
+ return 0;
options++;
} else
- return;
+ return 0;
}
if (!strncmp(options, "map:", 4)) {
@@ -709,7 +723,7 @@ __initfunc(void video_setup(char *options, int *ints))
j = 0;
con2fb_map[i] = (options[j++]-'0') % FB_MAX;
}
- return;
+ return 0;
}
if (!strncmp(options, "vc:", 3)) {
@@ -724,7 +738,7 @@ __initfunc(void video_setup(char *options, int *ints))
}
if (num_pref_init_funcs == FB_MAX)
- return;
+ return 0;
for (i = 0; i < NUM_FB_DRIVERS; i++) {
j = strlen(fb_drivers[i].name);
@@ -739,28 +753,21 @@ __initfunc(void video_setup(char *options, int *ints))
fb_drivers[i].init = NULL;
}
if (fb_drivers[i].setup)
- fb_drivers[i].setup(options+j+1, ints);
+ fb_drivers[i].setup(options+j+1);
}
- return;
+ return 0;
}
}
+
/*
- * If we get here no fb was specified and we default to pass the
- * options to the first frame buffer that has an init and a setup
- * function.
+ * If we get here no fb was specified.
+ * We consider the argument to be a global video mode option.
*/
- for (i = 0; i < NUM_FB_DRIVERS; i++) {
- if (fb_drivers[i].init && fb_drivers[i].setup) {
- pref_init_funcs[num_pref_init_funcs++] =
- fb_drivers[i].init;
- fb_drivers[i].init = NULL;
-
- fb_drivers[i].setup(options, ints);
- return;
- }
- }
+ global_mode_option = options;
+ return 0;
}
+__setup("video=", video_setup);
/*
* Visible symbols for modules
diff --git a/drivers/video/fm2fb.c b/drivers/video/fm2fb.c
index e5ab75e08..97f4e9ba8 100644
--- a/drivers/video/fm2fb.c
+++ b/drivers/video/fm2fb.c
@@ -205,7 +205,7 @@ static int fm2fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
* Interface to the low level console driver
*/
-void fm2fb_init(void);
+int fm2fb_init(void);
static int fm2fbcon_switch(int con, struct fb_info *info);
static int fm2fbcon_updatevar(int con, struct fb_info *info);
static void fm2fbcon_blank(int blank, struct fb_info *info);
@@ -374,7 +374,7 @@ static int fm2fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
* Initialisation
*/
-__initfunc(void fm2fb_init(void))
+int __init fm2fb_init(void)
{
int key, is_fm;
const struct ConfigDev *cd = NULL;
@@ -383,10 +383,10 @@ __initfunc(void fm2fb_init(void))
if (!(key = is_fm = zorro_find(ZORRO_PROD_BSC_FRAMEMASTER_II, 0, 0)) &&
!(key = zorro_find(ZORRO_PROD_HELFRICH_RAINBOW_II, 0, 0)))
- return;
+ return -ENXIO;
cd = zorro_get_board(key);
if (!(board = (u_long)cd->cd_BoardAddr))
- return;
+ return -ENXIO;
zorro_config_board(key, 0);
/* assigning memory to kernel space */
@@ -415,13 +415,13 @@ __initfunc(void fm2fb_init(void))
fb_var = fb_var_modes[fm2fb_mode];
strcpy(fb_fix.id, is_fm ? "FrameMaster II" : "Rainbow II");
- fb_fix.smem_start = (char *)fm2fb_mem_phys;
+ fb_fix.smem_start = fm2fb_mem_phys;
fb_fix.smem_len = FRAMEMASTER_REG;
fb_fix.type = FB_TYPE_PACKED_PIXELS;
fb_fix.type_aux = 0;
fb_fix.visual = FB_VISUAL_TRUECOLOR;
fb_fix.line_length = 768<<2;
- fb_fix.mmio_start = (char *)fm2fb_reg_phys;
+ fb_fix.mmio_start = fm2fb_reg_phys;
fb_fix.mmio_len = 8;
fb_fix.accel = FB_ACCEL_NONE;
@@ -460,18 +460,19 @@ __initfunc(void fm2fb_init(void))
fm2fb_set_var(&fb_var, -1, &fb_info);
if (register_framebuffer(&fb_info) < 0)
- return;
+ return -EINVAL;
printk("fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.node),
fb_fix.id);
+ return 0;
}
-__initfunc(void fm2fb_setup(char *options, int *ints))
+int __init fm2fb_setup(char *options)
{
char *this_opt;
if (!options || !*options)
- return;
+ return 0;
for (this_opt = strtok(options, ","); this_opt;
this_opt = strtok(NULL, ",")) {
@@ -480,6 +481,7 @@ __initfunc(void fm2fb_setup(char *options, int *ints))
else if (!strncmp(this_opt, "ntsc", 4))
fm2fb_mode = FM2FB_MODE_NTSC;
}
+ return 0;
}
diff --git a/drivers/video/font_6x11.c b/drivers/video/font_6x11.c
index 362529c2b..aa95f8863 100644
--- a/drivers/video/font_6x11.c
+++ b/drivers/video/font_6x11.c
@@ -1207,6 +1207,8 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = {
0x00, /* 00000000 */
/* 92 0x5c '\' */
+ 0x40, /* 0 000000 */
+ 0x40, /* 0 000000 */
0x20, /* 00 00000 */
0x20, /* 00 00000 */
0x10, /* 000 0000 */
@@ -1215,8 +1217,6 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = {
0x08, /* 0000 000 */
0x04, /* 00000 00 */
0x04, /* 00000 00 */
- 0x02, /* 000000 0 */
- 0x02, /* 000000 0 */
0x00, /* 00000000 */
/* 93 0x5d ']' */
@@ -1253,7 +1253,7 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = {
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
- 0x7e, /* 0 0 */
+ 0xfc, /* 00 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
@@ -2222,9 +2222,9 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = {
/* 170 0xaa '\252' */
0x00, /* 00000000 */
- 0x7a, /* 0 0 0 */
- 0x2e, /* 00 0 0 */
- 0x2e, /* 00 0 0 */
+ 0xf4, /* 0 00 */
+ 0x5c, /* 0 0 00 */
+ 0x5c, /* 0 0 00 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
@@ -2732,7 +2732,7 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = {
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
- 0x7e, /* 0 0 */
+ 0xfc, /* 00 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
@@ -2834,11 +2834,11 @@ static unsigned char fontdata_6x11[FONTDATAMAX] = {
/* 217 0xd9 '\331' */
0x00, /* 00000000 */
0x00, /* 00000000 */
- 0x7e, /* 0 0 */
+ 0xfc, /* 00 */
0x00, /* 00000000 */
- 0x7e, /* 0 0 */
+ 0xfc, /* 00 */
0x00, /* 00000000 */
- 0x7e, /* 0 0 */
+ 0xfc, /* 00 */
0x00, /* 00000000 */
0x00, /* 00000000 */
0x00, /* 00000000 */
diff --git a/drivers/video/g364fb.c b/drivers/video/g364fb.c
index fe57a7558..b74d12d93 100644
--- a/drivers/video/g364fb.c
+++ b/drivers/video/g364fb.c
@@ -112,7 +112,7 @@ static int g364fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
/*
* Interface to the low level console driver
*/
-void g364fb_init(void);
+int g364fb_init(void);
static int g364fbcon_switch(int con, struct fb_info *info);
static int g364fbcon_updatevar(int con, struct fb_info *info);
static void g364fbcon_blank(int blank, struct fb_info *info);
@@ -297,7 +297,7 @@ static int g364fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
/*
* Initialisation
*/
-__initfunc(void g364fb_init(void))
+int __init g364fb_init(void)
{
int i,j;
volatile unsigned int *pal_ptr = (volatile unsigned int *) CLR_PAL_REG;
@@ -345,7 +345,7 @@ __initfunc(void g364fb_init(void))
fb_var.yres = yres;
fb_fix.line_length = (xres / 8) * fb_var.bits_per_pixel;
- fb_fix.smem_start = (char *)0x40000000; /* physical address */
+ fb_fix.smem_start = 0x40000000; /* physical address */
/* get size of video memory; this is special for the JAZZ hardware */
mem = (r4030_read_reg32(JAZZ_R4030_CONFIG) >> 8) & 3;
fb_fix.smem_len = (1 << (mem*2)) * 512 * 1024;
@@ -355,7 +355,7 @@ __initfunc(void g364fb_init(void))
fb_fix.xpanstep = 0;
fb_fix.ypanstep = 1;
fb_fix.ywrapstep = 0;
- fb_fix.mmio_start = NULL;
+ fb_fix.mmio_start = 0;
fb_fix.mmio_len = 0;
fb_fix.accel = FB_ACCEL_NONE;
@@ -413,10 +413,11 @@ __initfunc(void g364fb_init(void))
g364fb_set_var(&fb_var, -1, &fb_info);
if (register_framebuffer(&fb_info) < 0)
- return;
+ return -EINVAL;
printk("fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.node),
fb_fix.id);
+ return 0;
}
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
index 11689b150..27a383ece 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/hpfb.c
@@ -192,7 +192,7 @@ static void hpfb_encode_fix(struct fb_fix_screeninfo *fix,
/*
* X works, but screen wraps ...
*/
- fix->smem_start=(char *)fb_start;
+ fix->smem_start=fb_start;
fix->smem_len=fb_size;
fix->type = FB_TYPE_PACKED_PIXELS;
fix->visual = FB_VISUAL_PSEUDOCOLOR;
@@ -301,7 +301,7 @@ static struct fb_ops hpfb_ops = {
#define TOPCAT_FBOMSB 0x5d
#define TOPCAT_FBOLSB 0x5f
-__initfunc(int hpfb_init_one(unsigned long base))
+int __init hpfb_init_one(unsigned long base)
{
unsigned long fboff;
@@ -384,7 +384,7 @@ __initfunc(int hpfb_init_one(unsigned long base))
* Initialise the framebuffer
*/
-__initfunc(unsigned long hpfb_init(unsigned long mem_start))
+int __init hpfb_init(void)
{
unsigned int sid;
@@ -421,9 +421,10 @@ __initfunc(unsigned long hpfb_init(unsigned long mem_start))
}
}
- return mem_start;
+ return 0;
}
-__initfunc(void hpfb_setup(char *options, int *ints))
+int __init hpfb_setup(char *options)
{
+ return 0;
}
diff --git a/drivers/video/igafb.c b/drivers/video/igafb.c
index dbf56108c..5ed528af2 100644
--- a/drivers/video/igafb.c
+++ b/drivers/video/igafb.c
@@ -217,7 +217,7 @@ static int igafb_get_fix(struct fb_fix_screeninfo *fix, int con,
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id, igafb_name);
- fix->smem_start = (char *)fb->frame_buffer;
+ fix->smem_start = fb->frame_buffer;
fix->smem_len = fb->total_vram;
fix->xpanstep = 0;
fix->ypanstep = 0;
@@ -559,7 +559,7 @@ static void igafb_blank(int blank, struct fb_info *info)
}
-__initfunc(static int iga_init(struct fb_info_iga *info))
+static int __init iga_init(struct fb_info_iga *info)
{
char vramsz = iga_inb(info, IGA_EXT_CNTRL, IGA_IDX_EXT_BUS_CNTL)
& MEM_SIZE_ALIAS;
@@ -624,7 +624,7 @@ __initfunc(static int iga_init(struct fb_info_iga *info))
}
-__initfunc(void igafb_init(void))
+int __init igafb_init(void)
{
struct pci_dev *pdev;
struct fb_info_iga *info;
@@ -634,7 +634,7 @@ __initfunc(void igafb_init(void))
/* Do not attach when we have a serial console. */
if (!con_is_present())
- return;
+ return -ENXIO;
pdev = pci_find_device(PCI_VENDOR_ID_INTERG,
PCI_DEVICE_ID_INTERG_1682, 0);
@@ -642,28 +642,28 @@ __initfunc(void igafb_init(void))
pdev = pci_find_device(PCI_VENDOR_ID_INTERG,
0x2000, 0);
if(pdev == NULL)
- return;
+ return -ENXIO;
iga2000 = 1;
}
info = kmalloc(sizeof(struct fb_info_iga), GFP_ATOMIC);
if (!info) {
printk("igafb_init: can't alloc fb_info_iga\n");
- return;
+ return -ENOMEM;
}
memset(info, 0, sizeof(struct fb_info_iga));
- info->frame_buffer = pdev->base_address[0];
+ info->frame_buffer = pdev->resource[0].start;
if (!info->frame_buffer) {
kfree(info);
- return;
+ return -ENXIO;
}
pcibios_read_config_dword(0, pdev->devfn,
PCI_BASE_ADDRESS_0,
(unsigned int*)&addr);
if (!addr)
- return;
+ return -ENXIO;
info->frame_buffer_phys = addr & PCI_BASE_ADDRESS_MEM_MASK;
#ifdef __sparc__
@@ -684,7 +684,7 @@ __initfunc(void igafb_init(void))
}
if (!info->io_base) {
kfree(info);
- return;
+ return -ENXIO;
}
/*
@@ -700,7 +700,7 @@ __initfunc(void igafb_init(void))
printk("igafb_init: can't alloc mmap_map\n");
/* XXX Here we left I/O allocated */
kfree(info);
- return;
+ return -ENOMEM;
}
memset(info->mmap_map, 0, 4 * sizeof(*info->mmap_map));
@@ -775,14 +775,16 @@ __initfunc(void igafb_init(void))
info->mmap_map[1].prot_mask = SRMMU_CACHE;
info->mmap_map[1].prot_flag = SRMMU_WRITE;
#endif /* __sparc__ */
+
+ return 0;
}
-__initfunc(void igafb_setup(char *options, int *ints))
+int __init igafb_setup(char *options)
{
char *this_opt;
if (!options || !*options)
- return;
+ return 0;
for (this_opt = strtok(options, ","); this_opt;
this_opt = strtok(NULL, ",")) {
@@ -798,4 +800,5 @@ __initfunc(void igafb_setup(char *options, int *ints))
fontname[i] = 0;
}
}
+ return 0;
}
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index 99ebadf4b..398e8e500 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -380,9 +380,7 @@ static char noaccel __initdata = 0;
#if defined(CONFIG_PPC)
static signed char init_vmode __initdata = -1, init_cmode __initdata = -1;
#endif
-#ifdef MODULE
static struct fb_info_imstt *fb_info_imstt_p[FB_MAX] = { 0, 0, 0, 0, 0, 0, 0, 0 };
-#endif
static struct imstt_regvals tvp_reg_init_2 = {
512,
@@ -967,8 +965,8 @@ out:
add_timer(&c->timer);
}
-__initfunc(static void
-imstt_cursor_init (struct fb_info_imstt *p))
+static void __init
+imstt_cursor_init (struct fb_info_imstt *p)
{
struct imstt_cursor *c = &p->cursor;
@@ -1728,8 +1726,8 @@ imsttfbcon_blank (int blank, struct fb_info *info)
out_le32(&p->dc_regs[STGCTL], ctrl);
}
-__initfunc(static void
-init_imstt(struct fb_info_imstt *p))
+static void __init
+init_imstt(struct fb_info_imstt *p)
{
__u32 i, tmp;
__u32 *ip, *end;
@@ -1799,10 +1797,10 @@ init_imstt(struct fb_info_imstt *p))
}
sprintf(p->fix.id, "IMS TT (%s)", p->ramdac == IBM ? "IBM" : "TVP");
- p->fix.smem_start = (__u8 *)p->frame_buffer_phys;
+ p->fix.smem_start = p->frame_buffer_phys;
p->fix.smem_len = p->total_vram;
- p->fix.mmio_start = (__u8 *)p->dc_regs_phys;
- p->fix.mmio_len = 0x40000;
+ p->fix.mmio_start = p->dc_regs_phys;
+ p->fix.mmio_len = 0x1000;
p->fix.accel = FB_ACCEL_IMS_TWINTURBO;
p->fix.type = FB_TYPE_PACKED_PIXELS;
p->fix.visual = p->disp.var.bits_per_pixel == 8 ? FB_VISUAL_PSEUDOCOLOR
@@ -1853,9 +1851,7 @@ init_imstt(struct fb_info_imstt *p))
printk("fb%u: %s frame buffer; %uMB vram; chip version %u\n",
i, p->fix.id, p->total_vram >> 20, tmp);
-#ifdef MODULE
fb_info_imstt_p[i] = p;
-#endif
#ifdef CONFIG_FB_COMPAT_XPMAC
strncpy(display_info.name, "IMS,tt128mb", sizeof(display_info.name));
display_info.fb_address = (__u32)p->frame_buffer_phys;
@@ -1868,8 +1864,8 @@ init_imstt(struct fb_info_imstt *p))
}
#if defined(CONFIG_FB_OF) && !defined(MODULE)
-__initfunc(void
-imsttfb_of_init(struct device_node *dp))
+void __init
+imsttfb_of_init(struct device_node *dp)
{
struct fb_info_imstt *p;
int i;
@@ -1912,9 +1908,10 @@ imsttfb_of_init(struct device_node *dp))
}
#endif
-__initfunc(void
-imsttfb_init(void))
+int __init
+imsttfb_init(void)
{
+ int i;
#if defined(CONFIG_FB_OF) && !defined(MODULE)
/* We don't want to be called like this. */
/* We rely on Open Firmware (offb) instead. */
@@ -1935,13 +1932,13 @@ imsttfb_init(void))
pci_write_config_word(pdev, PCI_COMMAND, cmd);
}
- addr = pdev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK;
+ addr = pdev->resource[0].start;
if (!addr)
continue;
p = kmalloc(sizeof(struct fb_info_imstt), GFP_ATOMIC);
if (!p)
- return;
+ continue;
memset(p, 0, sizeof(struct fb_info_imstt));
printk("imsttfb: device=%04x\n", pdev->device);
@@ -1966,16 +1963,21 @@ imsttfb_init(void))
init_imstt(p);
}
#endif /* CONFIG_PCI */
+ for (i = 0; i < FB_MAX; i++) {
+ if (fb_info_imstt_p[i])
+ return 0;
+ }
+ return -ENXIO;
}
#ifndef MODULE
-__initfunc(void
-imsttfb_setup(char *options, int *ints))
+int __init
+imsttfb_setup(char *options)
{
char *this_opt;
if (!options || !*options)
- return;
+ return 0;
for (this_opt = strtok(options, ","); this_opt;
this_opt = strtok(NULL, ",")) {
@@ -2020,25 +2022,16 @@ imsttfb_setup(char *options, int *ints))
}
#endif
}
+ return 0;
}
#else /* MODULE */
-int
+int __init
init_module (void)
{
- struct fb_info_imstt *p;
- __u32 i;
-
- imsttfb_init();
-
- for (i = 0; i < FB_MAX; i++) {
- p = fb_info_imstt_p[i];
- if (p)
- return 0;
- }
- return -ENXIO;
+ return imsttfb_init();
}
void
diff --git a/drivers/video/leofb.c b/drivers/video/leofb.c
index 0a273fe43..9daa66421 100644
--- a/drivers/video/leofb.c
+++ b/drivers/video/leofb.c
@@ -1,4 +1,4 @@
-/* $Id: leofb.c,v 1.6 1999/04/01 13:03:25 jj Exp $
+/* $Id: leofb.c,v 1.7 1999/08/09 11:06:52 jj Exp $
* leofb.c: Leo (ZX) 24/8bit frame buffer driver
*
* Copyright (C) 1996-1999 Jakub Jelinek (jj@ultra.linux.cz)
@@ -505,8 +505,9 @@ static void leo_switch_from_graph (struct fb_info_sbusfb *fb)
us->fontt = 0;
}
-static void __init leo_rasterimg (struct fb_info_sbusfb *fb, int start)
+static int __init leo_rasterimg (struct fb_info *info, int start)
{
+ struct fb_info_sbusfb *fb = sbusfbinfo(info);
register struct leo_lc_ss0_usr *us = fb->s.leo.lc_ss0_usr;
register struct leo_ld *ss = fb->s.leo.ld_ss0;
@@ -521,6 +522,7 @@ static void __init leo_rasterimg (struct fb_info_sbusfb *fb, int start)
ss->rop = 0x310850;
us->addrspace = 4;
}
+ return 0;
}
static char idstring[40] __initdata = { 0 };
diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c
index 0f964f60a..282c47739 100644
--- a/drivers/video/macfb.c
+++ b/drivers/video/macfb.c
@@ -157,7 +157,7 @@ static void macfb_encode_fix(struct fb_fix_screeninfo *fix,
/*
* fbmem.c accepts non page aligned mappings now!
*/
- fix->smem_start=(char *)mac_videobase;
+ fix->smem_start=mac_videobase;
fix->smem_len=mac_videosize;
fix->type = FB_TYPE_PACKED_PIXELS;
if (mac_depth == 1)
@@ -459,14 +459,14 @@ static struct fb_ops macfb_ops = {
macfb_ioctl
};
-void macfb_setup(char *options, int *ints)
+int __init macfb_setup(char *options)
{
char *this_opt;
fb_info.fontname[0] = '\0';
if (!options || !*options)
- return;
+ return 0;
for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) {
if (!*this_opt) continue;
@@ -478,6 +478,7 @@ void macfb_setup(char *options, int *ints)
printk("macfb_setup: option %s\n", this_opt);
}
}
+ return 0;
}
static int macfb_switch(int con, struct fb_info *info)
@@ -512,12 +513,12 @@ static struct nubus_device_specifier nb_video={
NULL
};
-__initfunc(void macfb_init(void))
+int __init macfb_init(void)
{
/* nubus_remap the video .. */
if (!MACH_IS_MAC)
- return;
+ return -ENXIO;
mac_xres=mac_bi_data.dimensions&0xFFFF;
mac_yres=(mac_bi_data.dimensions&0xFFFF0000)>>16;
@@ -572,11 +573,12 @@ __initfunc(void macfb_init(void))
if (register_framebuffer(&fb_info) < 0)
{
- return;
+ return -EINVAL;
}
printk("fb%d: %s frame buffer device using %ldK of video memory\n",
GET_FB_IDX(fb_info.node), fb_info.modename, mac_videosize>>10);
+ return 0;
}
#if 0
diff --git a/drivers/video/macmodes.c b/drivers/video/macmodes.c
index 0fbe917d3..e71f36e50 100644
--- a/drivers/video/macmodes.c
+++ b/drivers/video/macmodes.c
@@ -14,240 +14,151 @@
#include <video/macmodes.h>
-struct mac_mode {
- int number;
- u32 xres;
- u32 yres;
- u32 pixclock;
- u32 left_margin;
- u32 right_margin;
- u32 upper_margin;
- u32 lower_margin;
- u32 hsync_len;
- u32 vsync_len;
- u32 sync;
- u32 vmode;
-};
-
-
- /* 512x384, 60Hz, Interlaced (NTSC) */
-
-#if 0
-static const struct mac_mode mac_mode_1 = {
- VMODE_512_384_60I, 512, 384,
- pixclock, left, right, upper, lower, hslen, vslen,
- sync, FB_VMODE_INTERLACED
-};
-#endif
-
- /* 512x384, 60Hz, Non-Interlaced */
-
-#if 0
-static const struct mac_mode mac_mode_2 = {
- VMODE_512_384_60, 512, 384,
- pixclock, left, right, upper, lower, hslen, vslen,
- sync, FB_VMODE_NONINTERLACED
-};
-#endif
-
- /* 640x480, 50Hz, Interlaced (PAL) */
-
-#if 0
-static const struct mac_mode mac_mode_3 = {
- VMODE_640_480_50I, 640, 480,
- pixclock, left, right, upper, lower, hslen, vslen,
- sync, FB_VMODE_INTERLACED
-};
-#endif
-
- /* 640x480, 60Hz, Interlaced (NTSC) */
-
-#if 0
-static const struct mac_mode mac_mode_4 = {
- VMODE_640_480_60I, 640, 480,
- pixclock, left, right, upper, lower, hslen, vslen,
- sync, FB_VMODE_INTERLACED
-};
-#endif
- /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
-
-static const struct mac_mode mac_mode_5 = {
- VMODE_640_480_60, 640, 480,
- 39722, 32, 32, 33, 10, 96, 2,
- 0, FB_VMODE_NONINTERLACED
-};
-
- /* 640x480, 67Hz, Non-Interlaced (30.0 MHz dotclock) */
-
-static const struct mac_mode mac_mode_6 = {
- VMODE_640_480_67, 640, 480,
- 33334, 80, 80, 39, 3, 64, 3,
- 0, FB_VMODE_NONINTERLACED
-};
-
- /* 640x870, 75Hz (portrait), Non-Interlaced */
-
-#if 0
-static const struct mac_mode mac_mode_7 = {
- VMODE_640_870_75P, 640, 870,
- pixclock, left, right, upper, lower, hslen, vslen,
- sync, FB_VMODE_NONINTERLACED
-};
-#endif
+ /*
+ * MacOS video mode definitions
+ *
+ * Order IS important! If you change these, don't forget to update
+ * mac_modes[] below!
+ */
- /* 768x576, 50Hz (PAL full frame), Interlaced */
+#define DEFAULT_MODEDB_INDEX 0
+
+static const struct fb_videomode mac_modedb[] = {
+ {
+ /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
+ "mac5", 60, 640, 480, 39722, 32, 32, 33, 10, 96, 2,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 640x480, 67Hz, Non-Interlaced (30.0 MHz dotclock) */
+ "mac6", 67, 640, 480, 33334, 80, 80, 39, 3, 64, 3,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 800x600, 56 Hz, Non-Interlaced (36.00 MHz dotclock) */
+ "mac9", 56, 800, 600, 27778, 112, 40, 22, 1, 72, 2,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }, {
+ /* 800x600, 60 Hz, Non-Interlaced (40.00 MHz dotclock) */
+ "mac10", 60, 800, 600, 25000, 72, 56, 23, 1, 128, 4,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }, {
+ /* 800x600, 72 Hz, Non-Interlaced (50.00 MHz dotclock) */
+ "mac11", 72, 800, 600, 20000, 48, 72, 23, 37, 120, 6,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }, {
+ /* 800x600, 75 Hz, Non-Interlaced (49.50 MHz dotclock) */
+ "mac12", 75, 800, 600, 20203, 144, 32, 21, 1, 80, 3,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }, {
+ /* 832x624, 75Hz, Non-Interlaced (57.6 MHz dotclock) */
+ "mac13", 75, 832, 624, 17362, 208, 48, 39, 1, 64, 3,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1024x768, 60 Hz, Non-Interlaced (65.00 MHz dotclock) */
+ "mac14", 60, 1024, 768, 15385, 144, 40, 29, 3, 136, 6,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1024x768, 72 Hz, Non-Interlaced (75.00 MHz dotclock) */
+ "mac15", 72, 1024, 768, 13334, 128, 40, 29, 3, 136, 6,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */
+ "mac16", 75, 1024, 768, 12699, 176, 16, 28, 1, 96, 3,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */
+ "mac17", 75, 1024, 768, 12699, 160, 32, 28, 1, 96, 3,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1152x870, 75 Hz, Non-Interlaced (100.0 MHz dotclock) */
+ "mac18", 75, 1152, 870, 10000, 128, 48, 39, 3, 128, 3,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1280x960, 75 Hz, Non-Interlaced (126.00 MHz dotclock) */
+ "mac19", 75, 1280, 960, 7937, 224, 32, 36, 1, 144, 3,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1280x1024, 75 Hz, Non-Interlaced (135.00 MHz dotclock) */
+ "mac20", 75, 1280, 1024, 7408, 232, 64, 38, 1, 112, 3,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ },
#if 0
-static const struct mac_mode mac_mode_8 = {
- VMODE_768_576_50I, 768, 576,
- pixclock, left, right, upper, lower, hslen, vslen,
- sync, FB_VMODE_INTERLACED
-};
+ /* Anyone who has timings for these? */
+ {
+ /* VMODE_512_384_60I: 512x384, 60Hz, Interlaced (NTSC) */
+ "mac1", 60, 512, 384, pixclock, left, right, upper, lower, hslen, vslen,
+ sync, FB_VMODE_INTERLACED
+ }, {
+ /* VMODE_512_384_60: 512x384, 60Hz, Non-Interlaced */
+ "mac2", 60, 512, 384, pixclock, left, right, upper, lower, hslen, vslen,
+ sync, FB_VMODE_NONINTERLACED
+ }, {
+ /* VMODE_640_480_50I: 640x480, 50Hz, Interlaced (PAL) */
+ "mac3", 50, 640, 480, pixclock, left, right, upper, lower, hslen, vslen,
+ sync, FB_VMODE_INTERLACED
+ }, {
+ /* VMODE_640_480_60I: 640x480, 60Hz, Interlaced (NTSC) */
+ "mac4", 60, 640, 480, pixclock, left, right, upper, lower, hslen, vslen,
+ sync, FB_VMODE_INTERLACED
+ }, {
+ /* VMODE_640_870_75P: 640x870, 75Hz (portrait), Non-Interlaced */
+ "mac7", 75, 640, 870, pixclock, left, right, upper, lower, hslen, vslen,
+ sync, FB_VMODE_NONINTERLACED
+ }, {
+ /* VMODE_768_576_50I: 768x576, 50Hz (PAL full frame), Interlaced */
+ "mac8", 50, 768, 576, pixclock, left, right, upper, lower, hslen, vslen,
+ sync, FB_VMODE_INTERLACED
+ },
#endif
-
- /* 800x600, 56 Hz, Non-Interlaced (36.00 MHz dotclock) */
-
-static const struct mac_mode mac_mode_9 = {
- VMODE_800_600_56, 800, 600,
- 27778, 112, 40, 22, 1, 72, 2,
- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-};
-
- /* 800x600, 60 Hz, Non-Interlaced (40.00 MHz dotclock) */
-
-static const struct mac_mode mac_mode_10 = {
- VMODE_800_600_60, 800, 600,
- 25000, 72, 56, 23, 1, 128, 4,
- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-};
-
- /* 800x600, 72 Hz, Non-Interlaced (50.00 MHz dotclock) */
-
-static const struct mac_mode mac_mode_11 = {
- VMODE_800_600_72, 800, 600,
- 20000, 48, 72, 23, 37, 120, 6,
- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
};
- /* 800x600, 75 Hz, Non-Interlaced (49.50 MHz dotclock) */
-
-static const struct mac_mode mac_mode_12 = {
- VMODE_800_600_75, 800, 600,
- 20203, 144, 32, 21, 1, 80, 3,
- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-};
-
- /* 832x624, 75Hz, Non-Interlaced (57.6 MHz */
-
-static const struct mac_mode mac_mode_13 = {
- VMODE_832_624_75, 832, 624,
- 17362, 208, 48, 39, 1, 64, 3,
- 0, FB_VMODE_NONINTERLACED
-};
-
- /* 1024x768, 60 Hz, Non-Interlaced (65.00 MHz dotclock) */
-
-static const struct mac_mode mac_mode_14 = {
- VMODE_1024_768_60, 1024, 768,
- 15385, 144, 40, 29, 3, 136, 6,
- 0, FB_VMODE_NONINTERLACED
-};
-
- /* 1024x768, 72 Hz, Non-Interlaced (75.00 MHz dotclock) */
-
-static const struct mac_mode mac_mode_15 = {
- VMODE_1024_768_70, 1024, 768,
- 13334, 128, 40, 29, 3, 136, 6,
- 0, FB_VMODE_NONINTERLACED
-};
-
- /* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */
-
-static const struct mac_mode mac_mode_16 = {
- VMODE_1024_768_75V, 1024, 768,
- 12699, 176, 16, 28, 1, 96, 3,
- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-};
-
- /* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */
-
-static const struct mac_mode mac_mode_17 = {
- VMODE_1024_768_75, 1024, 768,
- 12699, 160, 32, 28, 1, 96, 3,
- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-};
-
- /* 1152x870, 75 Hz, Non-Interlaced (100.0 MHz dotclock) */
-
-static const struct mac_mode mac_mode_18 = {
- VMODE_1152_870_75, 1152, 870,
- 10000, 128, 48, 39, 3, 128, 3,
- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-};
-
- /* 1280x960, 75 Hz, Non-Interlaced (126.00 MHz dotclock) */
-
-static const struct mac_mode mac_mode_19 = {
- VMODE_1280_960_75, 1280, 960,
- 7937, 224, 32, 36, 1, 144, 3,
- 0, FB_VMODE_NONINTERLACED
-};
-
- /* 1280x1024, 75 Hz, Non-Interlaced (135.00 MHz dotclock) */
-
-static const struct mac_mode mac_mode_20 = {
- VMODE_1280_1024_75, 1280, 1024,
- 7408, 232, 64, 38, 1, 112, 3,
- FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
-};
+ /*
+ * Mapping between MacOS video mode numbers and video mode definitions
+ *
+ * These MUST be ordered in
+ * - increasing resolution
+ * - decreasing refresh rate
+ */
-static const struct mac_mode *mac_modes[20] = {
- NULL, /* 512x384, 60Hz interlaced (NTSC) */
- NULL, /* 512x384, 60Hz */
- NULL, /* 640x480, 50Hz interlaced (PAL) */
- NULL, /* 640x480, 60Hz interlaced (NTSC) */
- &mac_mode_5, /* 640x480, 60Hz (VGA) */
- &mac_mode_6, /* 640x480, 67Hz */
- NULL, /* 640x870, 75Hz (portrait) */
- NULL, /* 768x576, 50Hz (PAL full frame) */
- &mac_mode_9, /* 800x600, 56Hz */
- &mac_mode_10, /* 800x600, 60Hz */
- &mac_mode_11, /* 800x600, 72Hz */
- &mac_mode_12, /* 800x600, 75Hz */
- &mac_mode_13, /* 832x624, 75Hz */
- &mac_mode_14, /* 1024x768, 60Hz */
- &mac_mode_15, /* 1024x768, 70Hz (or 72Hz?) */
- &mac_mode_16, /* 1024x768, 75Hz (VESA) */
- &mac_mode_17, /* 1024x768, 75Hz */
- &mac_mode_18, /* 1152x870, 75Hz */
- &mac_mode_19, /* 1280x960, 75Hz */
- &mac_mode_20, /* 1280x1024, 75Hz */
+static const struct mode_map {
+ int vmode;
+ const struct fb_videomode *mode;
+} mac_modes[] = {
+ /* 640x480 */
+ { VMODE_640_480_67, &mac_modedb[1] },
+ { VMODE_640_480_60, &mac_modedb[0] },
+ /* 800x600 */
+ { VMODE_800_600_75, &mac_modedb[5] },
+ { VMODE_800_600_72, &mac_modedb[4] },
+ { VMODE_800_600_60, &mac_modedb[3] },
+ { VMODE_800_600_56, &mac_modedb[2] },
+ /* 832x624 */
+ { VMODE_832_624_75, &mac_modedb[6] },
+ /* 1024x768 */
+ { VMODE_1024_768_75, &mac_modedb[10] },
+ { VMODE_1024_768_75V, &mac_modedb[9] },
+ { VMODE_1024_768_70, &mac_modedb[8] },
+ { VMODE_1024_768_60, &mac_modedb[7] },
+ /* 1152x870 */
+ { VMODE_1152_870_75, &mac_modedb[11] },
+ /* 1280x960 */
+ { VMODE_1280_960_75, &mac_modedb[12] },
+ /* 1280x1024 */
+ { VMODE_1280_1024_75, &mac_modedb[13] },
+ { -1, NULL }
};
-static const struct mac_mode *mac_modes_inv[] = {
- &mac_mode_6, /* 640x480, 67Hz */
- &mac_mode_5, /* 640x480, 60Hz (VGA) */
- &mac_mode_12, /* 800x600, 75Hz */
- &mac_mode_11, /* 800x600, 72Hz */
- &mac_mode_10, /* 800x600, 60Hz */
- &mac_mode_9, /* 800x600, 56Hz */
- &mac_mode_13, /* 832x624, 75Hz */
- &mac_mode_17, /* 1024x768, 75Hz */
- &mac_mode_16, /* 1024x768, 75Hz (VESA) */
- &mac_mode_15, /* 1024x768, 70Hz (or 72Hz?) */
- &mac_mode_14, /* 1024x768, 60Hz */
- &mac_mode_18, /* 1152x870, 75Hz */
- &mac_mode_19, /* 1280x960, 75Hz */
- &mac_mode_20, /* 1280x1024, 75Hz */
-};
+ /*
+ * Mapping between monitor sense values and MacOS video mode numbers
+ */
-static struct mon_map {
+static const struct monitor_map {
int sense;
int vmode;
-} monitor_map[] = {
+} mac_monitors[] = {
{ 0x000, VMODE_1280_1024_75 }, /* 21" RGB */
{ 0x114, VMODE_640_870_75P }, /* Portrait Monochrome */
{ 0x221, VMODE_512_384_60 }, /* 12" RGB*/
@@ -277,11 +188,14 @@ static struct mon_map {
int mac_vmode_to_var(int vmode, int cmode, struct fb_var_screeninfo *var)
{
- const struct mac_mode *mode = NULL;
-
- if (vmode > 0 && vmode <= VMODE_MAX)
- mode = mac_modes[vmode-1];
+ const struct fb_videomode *mode = NULL;
+ const struct mode_map *map;
+ for (map = mac_modes; map->vmode != -1; map++)
+ if (map->vmode == vmode) {
+ mode = map->mode;
+ break;
+ }
if (!mode)
return -EINVAL;
@@ -348,7 +262,8 @@ int mac_vmode_to_var(int vmode, int cmode, struct fb_var_screeninfo *var)
int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
int *cmode)
{
- unsigned int i;
+ const struct fb_videomode *mode = NULL;
+ const struct mode_map *map;
if (var->bits_per_pixel <= 8)
*cmode = CMODE_8;
@@ -359,8 +274,8 @@ int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
else
return -EINVAL;
- for (i = 0; i < sizeof(mac_modes_inv)/sizeof(*mac_modes_inv); i++) {
- const struct mac_mode *mode = mac_modes_inv[i];
+ for (map = mac_modes; map->vmode != -1; map++) {
+ mode = map->mode;
if (var->xres > mode->xres || var->yres > mode->yres)
continue;
if (var->xres_virtual > mode->xres || var->yres_virtual > mode->yres)
@@ -369,7 +284,7 @@ int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
continue;
if ((var->vmode & FB_VMODE_MASK) != mode->vmode)
continue;
- *vmode = mode->number;
+ *vmode = map->vmode;
return 0;
}
return -EINVAL;
@@ -382,10 +297,32 @@ int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
int mac_map_monitor_sense(int sense)
{
- struct mon_map *map;
+ const struct monitor_map *map;
- for (map = monitor_map; map->sense >= 0; ++map)
+ for (map = mac_monitors; map->sense != -1; map++)
if (map->sense == sense)
break;
return map->vmode;
}
+
+
+ /*
+ * Find a suitable video mode
+ *
+ * If the name of the wanted mode begins with `mac', use the Mac video
+ * mode database, else fall back to the standard video mode database.
+ */
+
+int __init mac_find_mode(struct fb_var_screeninfo *var, struct fb_info *info,
+ const char *mode_option, unsigned int default_bpp)
+{
+ const struct fb_videomode *db = NULL;
+ unsigned int dbsize = 0;
+
+ if (mode_option && !strncmp(mode_option, "mac", 3)) {
+ db = mac_modedb;
+ dbsize = sizeof(mac_modedb)/sizeof(*mac_modedb);
+ }
+ return fb_find_mode(var, info, mode_option, db, dbsize,
+ &mac_modedb[DEFAULT_MODEDB_INDEX], default_bpp);
+}
diff --git a/drivers/video/matroxfb.c b/drivers/video/matroxfb.c
index eb6126965..4b0ffb0ad 100644
--- a/drivers/video/matroxfb.c
+++ b/drivers/video/matroxfb.c
@@ -1,10 +1,10 @@
/*
*
- * Hardware accelerated Matrox Millennium I, II, Mystique and G200
+ * Hardware accelerated Matrox Millennium I, II, Mystique, G100, G200 and G400
*
* (c) 1998,1999 Petr Vandrovec <vandrove@vc.cvut.cz>
*
- * Version: 1.15 1999/04/19
+ * Version: 1.19 1999/08/05
*
* MTRR stuff: 1998 Tom Rini <tmrini@ntplx.net>
*
@@ -14,8 +14,8 @@
* "Kurt Garloff" <garloff@kg1.ping.de>
* Betatesting, fixes, ideas, videomodes, videomodes timmings
*
- * "Tom Rini" <tmrini@ntplx.net>
- * MTRR stuff, betatesting, fixes, ideas
+ * "Tom Rini" <trini@disparity.net>
+ * MTRR stuff, PPC cleanups, betatesting, fixes, ideas
*
* "Bibek Sahu" <scorpio@dodds.net>
* Access device through readb|w|l and write b|w|l
@@ -60,6 +60,9 @@
* "Cort Dougan" <cort@cs.nmt.edu>
* CHRP fixes and PReP cleanup
*
+ * "Mark Vojkovich" <mvojkovi@ucsd.edu>
+ * G400 support
+ *
* (following author is not in any relation with this code, but his code
* is included in this driver)
*
@@ -87,6 +90,11 @@
/* Debug register calls, too? */
#undef MATROXFB_DEBUG_REG
+/* Log reentrancy attempts - you must have printstate() patch applied */
+#undef MATROXFB_DEBUG_REENTER
+/* you must define DEBUG_REENTER to get debugged CONSOLEBH... */
+#undef MATROXFB_DEBUG_CONSOLEBH
+
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -103,9 +111,9 @@
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/pci.h>
+#include <linux/spinlock.h>
#include <asm/io.h>
-#include <asm/spinlock.h>
#include <asm/unaligned.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
@@ -127,12 +135,15 @@
#include <video/macmodes.h>
#endif
+/* always compile support for 32MB... It cost almost nothing */
+#define CONFIG_FB_MATROX_32MB
+
#define FBCON_HAS_VGATEXT
#ifdef MATROXFB_DEBUG
#define DEBUG
-#define DBG(x) printk("matroxfb: %s\n", (x));
+#define DBG(x) printk(KERN_DEBUG "matroxfb: %s\n", (x));
#ifdef MATROXFB_DEBUG_HEAVY
#define DBG_HEAVY(x) DBG(x)
@@ -217,6 +228,9 @@
#ifndef PCI_DEVICE_ID_MATROX_G100_AGP
#define PCI_DEVICE_ID_MATROX_G100_AGP 0x1001
#endif
+#ifndef PCI_DEVICE_ID_MATROX_G400_AGP
+#define PCI_DEVICE_ID_MATROX_G400_AGP 0x0525
+#endif
#ifndef PCI_SS_ID_MATROX_PRODUCTIVA_G100_AGP
#define PCI_SS_ID_MATROX_GENERIC 0xFF00
@@ -422,7 +436,7 @@ struct matrox_hw_state {
unsigned char MiscOutReg;
unsigned char DACpal[768];
unsigned char CRTC[25];
- unsigned char CRTCEXT[6];
+ unsigned char CRTCEXT[9];
unsigned char SEQ[5];
/* unused for MGA mode, but who knows... */
unsigned char GCTL[9];
@@ -453,7 +467,8 @@ static inline struct matrox_fb_info* mxinfo(const struct display* p) {
}
#define PMXINFO(p) mxinfo(p),
-#define MINFO_FROM_DISP(x) struct matrox_fb_info* minfo = mxinfo(x)
+#define MINFO_FROM(x) struct matrox_fb_info* minfo = x
+#define MINFO_FROM_DISP(x) MINFO_FROM(mxinfo(x))
#else
@@ -476,6 +491,7 @@ static inline struct matrox_fb_info* mxinfo(const struct display* p) {
#endif
#define PMXINFO(p)
+#define MINFO_FROM(x)
#define MINFO_FROM_DISP(x)
#endif
@@ -563,6 +579,9 @@ struct matrox_fb_info {
int hwcursor;
int blink;
int sgram;
+#ifdef CONFIG_FB_MATROX_32MB
+ int support32MB;
+#endif
int accelerator;
int text_type_aux;
@@ -609,6 +628,8 @@ struct matrox_fb_info {
#if defined(CONFIG_FB_OF)
unsigned char nvram_read_byte(int);
int matrox_of_init(struct device_node *dp);
+static int default_vmode = VMODE_NVRAM;
+static int default_cmode = CMODE_NVRAM;
#endif
#define curr_ydstorg(x) ACCESS_FBINFO2(x, curr.ydstorg.pixels)
@@ -678,6 +699,8 @@ int matrox_of_init(struct device_node *dp);
#define M_RESET 0x1E40
+#define M_AGP2PLL 0x1E4C
+
#define M_OPMODE 0x1E54
#define M_OPMODE_DMA_GEN_WRITE 0x00
#define M_OPMODE_DMA_BLIT 0x04
@@ -713,6 +736,9 @@ int matrox_of_init(struct device_node *dp);
#define M_EXTVGA_INDEX 0x1FDE
#define M_EXTVGA_DATA 0x1FDF
+/* G200 only */
+#define M_SRCORG 0x2CB4
+
#define M_RAMDAC_BASE 0x3C00
/* fortunately, same on TVP3026 and MGA1064 */
@@ -723,6 +749,9 @@ int matrox_of_init(struct device_node *dp);
#define M_X_INDEX 0x00
#define M_X_DATAREG 0x0A
+#define DAC_XGENIOCTRL 0x2A
+#define DAC_XGENIODATA 0x2B
+
#ifdef CONFIG_FB_MATROX_MILLENIUM
#define TVP3026_INDEX 0x00
#define TVP3026_PALWRADD 0x00
@@ -1054,6 +1083,48 @@ int matrox_of_init(struct device_node *dp);
#define isMilleniumII(x) (0)
#endif
+#ifdef MATROXFB_DEBUG_REENTER
+static atomic_t guard_counter = ATOMIC_INIT(1);
+static atomic_t guard_printing = ATOMIC_INIT(1);
+static void guard_start(void) {
+ if (atomic_dec_and_test(&guard_counter)) { /* first level */
+ if (!(bh_mask & (1 << CONSOLE_BH))) /* and CONSOLE_BH disabled */
+ return; /* is OK */
+ /* otherwise it is first level with CONSOLE_BH enabled -
+ - if we are __sti or SMP, reentering from console_bh possible */
+ atomic_dec(&guard_printing); /* disable reentrancy warning */
+ printk(KERN_DEBUG "matroxfb entered without CONSOLE_BH disabled\n");
+#ifdef printstate
+ printstate();
+#endif
+ atomic_inc(&guard_printing);
+ return;
+ }
+ /* real reentering... You should be already warned by code above */
+ if (atomic_dec_and_test(&guard_printing)) {
+#ifdef printstate
+ printstate();
+#endif
+ }
+ atomic_inc(&guard_printing);
+}
+
+static inline void guard_end(void) {
+ atomic_inc(&guard_counter);
+}
+
+#define CRITBEGIN guard_start();
+#define CRITEND guard_end();
+
+#else
+
+#define CRITBEGIN
+#define CRITEND
+
+#endif
+
+#define mga_ydstlen(y,l) mga_outl(M_YDSTLEN | M_EXEC, ((y) << 16) | (l))
+
static void matrox_cfbX_init(WPMINFO struct display* p) {
u_int32_t maccess;
u_int32_t mpitch;
@@ -1101,7 +1172,7 @@ static void matrox_cfbX_init(WPMINFO struct display* p) {
mga_outl(M_OPMODE, mopmode);
mga_outl(M_CXBNDRY, 0xFFFF0000);
mga_outl(M_YTOP, 0);
- mga_outl(M_YBOT, 0x007FFFFF);
+ mga_outl(M_YBOT, 0x01FFFFFF);
mga_outl(M_MACCESS, maccess);
ACCESS_FBINFO(accel.m_dwg_rect) = M_DWG_TRAP | M_DWG_SOLID | M_DWG_ARZERO | M_DWG_SGNZERO | M_DWG_SHIFTZERO;
if (isMilleniumII(MINFO)) ACCESS_FBINFO(accel.m_dwg_rect) |= M_DWG_TRANSC;
@@ -1113,7 +1184,9 @@ static void matrox_cfbX_bmove(struct display* p, int sy, int sx, int dy, int dx,
MINFO_FROM_DISP(p);
DBG("matrox_cfbX_bmove")
-
+
+ CRITBEGIN
+
sx *= fontwidth(p);
dx *= fontwidth(p);
width *= fontwidth(p);
@@ -1142,8 +1215,10 @@ static void matrox_cfbX_bmove(struct display* p, int sy, int sx, int dy, int dx,
mga_outl(M_AR0, end);
mga_outl(M_AR3, start);
mga_outl(M_FXBNDRY, ((dx+width)<<16) | dx);
- mga_outl(M_YDSTLEN | M_EXEC, ((dy)<<16) | height);
+ mga_ydstlen(dy, height);
WaitTillIdle();
+
+ CRITEND
}
#ifdef FBCON_HAS_CFB4
@@ -1154,7 +1229,9 @@ static void matrox_cfb4_bmove(struct display* p, int sy, int sx, int dy, int dx,
also odd, that means that we cannot use acceleration */
DBG("matrox_cfb4_bmove")
-
+
+ CRITBEGIN
+
if ((sx | dx | width) & fontwidth(p) & 1) {
fbcon_cfb4_bmove(p, sy, sx, dy, dx, height, width);
return;
@@ -1194,6 +1271,8 @@ static void matrox_cfb4_bmove(struct display* p, int sy, int sx, int dy, int dx,
mga_outl(M_YDST, dy*pixx >> 5);
mga_outl(M_LEN | M_EXEC, height);
WaitTillIdle();
+
+ CRITEND
}
#endif
@@ -1201,13 +1280,17 @@ static void matroxfb_accel_clear(CPMINFO u_int32_t color, int sy, int sx, int he
int width) {
DBG("matroxfb_accel_clear")
-
- mga_fifo(4);
+
+ CRITBEGIN
+
+ mga_fifo(5);
mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_REPLACE);
mga_outl(M_FCOL, color);
mga_outl(M_FXBNDRY, ((sx + width) << 16) | sx);
- mga_outl(M_YDSTLEN | M_EXEC, (sy << 16) | height);
+ mga_ydstlen(sy, height);
WaitTillIdle();
+
+ CRITEND
}
static void matrox_cfbX_clear(u_int32_t color, struct display* p, int sy, int sx, int height, int width) {
@@ -1225,7 +1308,9 @@ static void matrox_cfb4_clear(struct vc_data* conp, struct display* p, int sy, i
MINFO_FROM_DISP(p);
DBG("matrox_cfb4_clear")
-
+
+ CRITBEGIN
+
whattodo = 0;
bgx = attr_bgcol_ec(p, conp);
bgx |= bgx << 4;
@@ -1277,6 +1362,8 @@ static void matrox_cfb4_clear(struct vc_data* conp, struct display* p, int sy, i
}
}
}
+
+ CRITEND
}
#endif
@@ -1323,7 +1410,10 @@ static void matrox_cfbX_fastputc(u_int32_t fgx, u_int32_t bgx, struct display* p
charcell = fontwidth(p) * fontheight(p);
yy *= fontheight(p);
xx *= fontwidth(p);
- mga_fifo(7);
+
+ CRITBEGIN
+
+ mga_fifo(8);
mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);
mga_outl(M_FCOL, fgx);
@@ -1332,8 +1422,10 @@ static void matrox_cfbX_fastputc(u_int32_t fgx, u_int32_t bgx, struct display* p
ar3 = ACCESS_FBINFO(fastfont.mgabase) + (c & p->charmask) * charcell;
mga_outl(M_AR3, ar3);
mga_outl(M_AR0, (ar3 + charcell - 1) & 0x0003FFFF);
- mga_outl(M_YDSTLEN | M_EXEC, (yy << 16) | fontheight(p));
+ mga_ydstlen(yy, fontheight(p));
WaitTillIdle();
+
+ CRITEND
}
static void matrox_cfbX_putc(u_int32_t fgx, u_int32_t bgx, struct display* p, int c, int yy, int xx) {
@@ -1345,6 +1437,9 @@ static void matrox_cfbX_putc(u_int32_t fgx, u_int32_t bgx, struct display* p, in
yy *= fontheight(p);
xx *= fontwidth(p);
+
+ CRITBEGIN
+
#ifdef __BIG_ENDIAN
WaitTillIdle();
mga_outl(M_OPMODE, M_OPMODE_8BPP);
@@ -1367,7 +1462,7 @@ static void matrox_cfbX_putc(u_int32_t fgx, u_int32_t bgx, struct display* p, in
mga_outl(M_BCOL, bgx);
mga_outl(M_AR3, 0);
mga_outl(M_AR0, fontheight(p)*fontwidth(p)-1);
- mga_outl(M_YDSTLEN | M_EXEC, (yy<<16) | fontheight(p));
+ mga_ydstlen(yy, fontheight(p));
mga_memcpy_toio(ACCESS_FBINFO(mmio.vbase), 0, p->fontdata+(c&p->charmask)*charcell, charcell);
} else {
u8* chardata = p->fontdata+(c&p->charmask)*fontheight(p)*step;
@@ -1379,7 +1474,7 @@ static void matrox_cfbX_putc(u_int32_t fgx, u_int32_t bgx, struct display* p, in
mga_outl(M_AR5, 0);
mga_outl(M_AR3, 0);
mga_outl(M_AR0, ar0);
- mga_outl(M_YDSTLEN | M_EXEC, (yy << 16) | fontheight(p));
+ mga_ydstlen(yy, fontheight(p));
switch (step) {
case 1:
@@ -1410,6 +1505,7 @@ static void matrox_cfbX_putc(u_int32_t fgx, u_int32_t bgx, struct display* p, in
#ifdef __BIG_ENDIAN
mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));
#endif
+ CRITEND
}
#ifdef FBCON_HAS_CFB8
@@ -1464,6 +1560,9 @@ static void matrox_cfbX_fastputcs(u_int32_t fgx, u_int32_t bgx, struct display*
yy *= fontheight(p);
xx *= fontwidth(p);
charcell = fontwidth(p) * fontheight(p);
+
+ CRITBEGIN
+
mga_fifo(3);
mga_outl(M_DWGCTL, M_DWG_BITBLT | M_DWG_SGNZERO | M_DWG_SHIFTZERO | M_DWG_BMONOWF | M_DWG_LINEAR | M_DWG_REPLACE);
mga_outl(M_FCOL, fgx);
@@ -1475,10 +1574,12 @@ static void matrox_cfbX_fastputcs(u_int32_t fgx, u_int32_t bgx, struct display*
mga_outl(M_FXBNDRY, ((xx + fontwidth(p) - 1) << 16) | xx);
mga_outl(M_AR3, ar3);
mga_outl(M_AR0, (ar3 + charcell - 1) & 0x0003FFFF);
- mga_outl(M_YDSTLEN | M_EXEC, (yy << 16) | fontheight(p));
+ mga_ydstlen(yy, fontheight(p));
xx += fontwidth(p);
}
WaitTillIdle();
+
+ CRITEND
}
static void matrox_cfbX_putcs(u_int32_t fgx, u_int32_t bgx, struct display* p, const unsigned short* s, int count, int yy, int xx) {
@@ -1504,7 +1605,7 @@ static void matrox_cfbX_putcs(u_int32_t fgx, u_int32_t bgx, struct display* p, c
step = 4;
charcell = fontheight(p)*step;
xlen = (charcell + 3) & ~3;
- ydstlen = (yy<<16) | fontheight(p);
+ ydstlen = (yy << 16) | fontheight(p);
if (fontwidth(p) == step << 3) {
ar0 = fontheight(p)*fontwidth(p) - 1;
easy = 1;
@@ -1512,6 +1613,9 @@ static void matrox_cfbX_putcs(u_int32_t fgx, u_int32_t bgx, struct display* p, c
ar0 = fontwidth(p) - 1;
easy = 0;
}
+
+ CRITBEGIN
+
#ifdef __BIG_ENDIAN
WaitTillIdle();
mga_outl(M_OPMODE, M_OPMODE_8BPP);
@@ -1529,7 +1633,7 @@ static void matrox_cfbX_putcs(u_int32_t fgx, u_int32_t bgx, struct display* p, c
while (count--) {
u_int8_t* chardata = p->fontdata + (scr_readw(s++) & p->charmask)*charcell;
- mga_fifo(5);
+ mga_fifo(6);
mga_writel(mmio, M_FXBNDRY, fxbndry);
mga_writel(mmio, M_AR0, ar0);
mga_writel(mmio, M_AR3, 0);
@@ -1573,6 +1677,7 @@ static void matrox_cfbX_putcs(u_int32_t fgx, u_int32_t bgx, struct display* p, c
#ifdef __BIG_ENDIAN
mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));
#endif
+ CRITEND
}
#ifdef FBCON_HAS_CFB8
@@ -1635,6 +1740,8 @@ static void matrox_cfb4_revc(struct display* p, int xx, int yy) {
xx |= (xx + fontwidth(p)) << 16;
xx >>= 1;
+ CRITBEGIN
+
mga_fifo(5);
mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_XOR);
mga_outl(M_FCOL, 0xFFFFFFFF);
@@ -1642,6 +1749,8 @@ static void matrox_cfb4_revc(struct display* p, int xx, int yy) {
mga_outl(M_YDST, yy * p->var.xres_virtual >> 6);
mga_outl(M_LEN | M_EXEC, fontheight(p));
WaitTillIdle();
+
+ CRITEND
}
#endif
@@ -1654,12 +1763,16 @@ static void matrox_cfb8_revc(struct display* p, int xx, int yy) {
yy *= fontheight(p);
xx *= fontwidth(p);
+ CRITBEGIN
+
mga_fifo(4);
mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_XOR);
mga_outl(M_FCOL, 0x0F0F0F0F);
mga_outl(M_FXBNDRY, ((xx + fontwidth(p)) << 16) | xx);
- mga_outl(M_YDSTLEN | M_EXEC, (yy << 16) | fontheight(p));
+ mga_ydstlen(yy, fontheight(p));
WaitTillIdle();
+
+ CRITEND
}
#endif
@@ -1671,12 +1784,16 @@ static void matrox_cfbX_revc(struct display* p, int xx, int yy) {
yy *= fontheight(p);
xx *= fontwidth(p);
+ CRITBEGIN
+
mga_fifo(4);
mga_outl(M_DWGCTL, ACCESS_FBINFO(accel.m_dwg_rect) | M_DWG_XOR);
mga_outl(M_FCOL, 0xFFFFFFFF);
mga_outl(M_FXBNDRY, ((xx + fontwidth(p)) << 16) | xx);
- mga_outl(M_YDSTLEN | M_EXEC, (yy << 16) | fontheight(p));
+ mga_ydstlen(yy, fontheight(p));
WaitTillIdle();
+
+ CRITEND
}
static void matrox_cfbX_clear_margins(struct vc_data* conp, struct display* p, int bottom_only) {
@@ -1840,6 +1957,9 @@ static void matroxfb_ti3026_cursor(struct display* p, int mode, int x, int y) {
DBG("matroxfb_ti3026_cursor")
+ if (ACCESS_FBINFO(currcon_display) != p)
+ return;
+
if (mode == CM_ERASE) {
if (ACCESS_FBINFO(cursor.state) != CM_ERASE) {
spin_lock_irqsave(&ACCESS_FBINFO(lock.DAC), flags);
@@ -1914,6 +2034,9 @@ static void matroxfb_DAC1064_createcursor(WPMINFO struct display* p) {
xline = (~0) << (32 - ACCESS_FBINFO(cursor.w));
cursorbase = ACCESS_FBINFO(video.vbase);
h = ACCESS_FBINFO(features.DAC1064.cursorimage);
+
+ CRITBEGIN
+
#ifdef __BIG_ENDIAN
WaitTillIdle();
mga_outl(M_OPMODE, M_OPMODE_32BPP);
@@ -1944,12 +2067,17 @@ static void matroxfb_DAC1064_createcursor(WPMINFO struct display* p) {
#ifdef __BIG_ENDIAN
mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));
#endif
+
+ CRITEND
}
static void matroxfb_DAC1064_cursor(struct display* p, int mode, int x, int y) {
unsigned long flags;
MINFO_FROM_DISP(p);
+ if (ACCESS_FBINFO(currcon_display) != p)
+ return;
+
if (mode == CM_ERASE) {
if (ACCESS_FBINFO(cursor.state) != CM_ERASE) {
spin_lock_irqsave(&ACCESS_FBINFO(lock.DAC), flags);
@@ -2010,6 +2138,9 @@ static int matroxfb_fastfont_tryset(WPMINFO struct display* p) {
fsize = (p->userfont?FNTCHARCNT(p->fontdata):256) * fontheight(p);
if (((fsize * width + 31) / 32) * 4 > ACCESS_FBINFO(fastfont.size))
return 0;
+
+ CRITBEGIN
+
mga_outl(M_OPMODE, M_OPMODE_8BPP);
if (width <= 8) {
if (width == 8)
@@ -2100,6 +2231,9 @@ static int matroxfb_fastfont_tryset(WPMINFO struct display* p) {
}
}
mga_outl(M_OPMODE, ACCESS_FBINFO(accel.m_opmode));
+
+ CRITEND
+
return 1;
}
@@ -2117,6 +2251,8 @@ static void matrox_text_bmove(struct display* p, int sy, int sx, int dy, int dx,
unsigned int step;
MINFO_FROM_DISP(p);
+ CRITBEGIN
+
step = ACCESS_FBINFO(devflags.textstep);
srcoff = (sy * p->next_line) + (sx * step);
dstoff = (dy * p->next_line) + (dx * step);
@@ -2144,6 +2280,7 @@ static void matrox_text_bmove(struct display* p, int sy, int sx, int dy, int dx,
height--;
}
}
+ CRITEND
}
static void matrox_text_clear(struct vc_data* conp, struct display* p, int sy, int sx,
@@ -2156,6 +2293,9 @@ static void matrox_text_clear(struct vc_data* conp, struct display* p, int sy, i
step = ACCESS_FBINFO(devflags.textstep);
offs = sy * p->next_line + sx * step;
val = ntohs((attr_bgcol(p, conp->vc_video_erase_char) << 4) | attr_fgcol(p, conp->vc_video_erase_char) | (' ' << 8));
+
+ CRITBEGIN
+
while (height > 0) {
int i;
for (i = width; i > 0; offs += step, i--)
@@ -2163,6 +2303,7 @@ static void matrox_text_clear(struct vc_data* conp, struct display* p, int sy, i
offs += p->next_line - width * step;
height--;
}
+ CRITEND
}
static void matrox_text_putc(struct vc_data* conp, struct display* p, int c, int yy, int xx) {
@@ -2175,7 +2316,12 @@ static void matrox_text_putc(struct vc_data* conp, struct display* p, int c, int
offs = yy * p->next_line + xx * step;
chr = attr_fgcol(p,c) | (attr_bgcol(p,c) << 4) | ((c & p->charmask) << 8);
if (chr & 0x10000) chr |= 0x08;
+
+ CRITBEGIN
+
mga_writew(ACCESS_FBINFO(video.vbase), offs, ntohs(chr));
+
+ CRITEND
}
static void matrox_text_putcs(struct vc_data* conp, struct display* p, const unsigned short* s,
@@ -2188,12 +2334,17 @@ static void matrox_text_putcs(struct vc_data* conp, struct display* p, const uns
step = ACCESS_FBINFO(devflags.textstep);
offs = yy * p->next_line + xx * step;
attr = attr_fgcol(p, scr_readw(s)) | (attr_bgcol(p, scr_readw(s)) << 4);
+
+ CRITBEGIN
+
while (count-- > 0) {
unsigned int chr = ((scr_readw(s++)) & p->charmask) << 8;
if (chr & 0x10000) chr ^= 0x10008;
mga_writew(ACCESS_FBINFO(video.vbase), offs, ntohs(attr|chr));
offs += step;
}
+
+ CRITEND
}
static void matrox_text_revc(struct display* p, int xx, int yy) {
@@ -2203,7 +2354,12 @@ static void matrox_text_revc(struct display* p, int xx, int yy) {
step = ACCESS_FBINFO(devflags.textstep);
offs = yy * p->next_line + xx * step + 1;
+
+ CRITBEGIN
+
mga_writeb(ACCESS_FBINFO(video.vbase), offs, mga_readb(ACCESS_FBINFO(video.vbase), offs) ^ 0x77);
+
+ CRITEND
}
static int matrox_text_loadfont(WPMINFO struct display* p) {
@@ -2221,6 +2377,9 @@ static int matrox_text_loadfont(WPMINFO struct display* p) {
dst = ACCESS_FBINFO(video.vbase);
i = 2;
font = (u_int8_t*)p->fontdata;
+
+ CRITBEGIN
+
mga_setr(M_SEQ_INDEX, 0x02, 0x04);
while (fsize--) {
int l;
@@ -2233,6 +2392,9 @@ static int matrox_text_loadfont(WPMINFO struct display* p) {
i += (32 - fontheight(p)) * ACCESS_FBINFO(devflags.vgastep);
}
mga_setr(M_SEQ_INDEX, 0x02, 0x03);
+
+ CRITEND
+
return 1;
}
@@ -2242,17 +2404,31 @@ static void matrox_text_createcursor(WPMINFO struct display* p) {
return;
matroxfb_createcursorshape(PMINFO p, 0);
+
+ CRITBEGIN
+
mga_setr(M_CRTC_INDEX, 0x0A, ACCESS_FBINFO(cursor.u));
mga_setr(M_CRTC_INDEX, 0x0B, ACCESS_FBINFO(cursor.d) - 1);
+
+ CRITEND
}
static void matrox_text_cursor(struct display* p, int mode, int x, int y) {
unsigned int pos;
MINFO_FROM_DISP(p);
+ if (ACCESS_FBINFO(currcon_display) != p)
+ return;
+
if (mode == CM_ERASE) {
if (ACCESS_FBINFO(cursor.state) != CM_ERASE) {
+
+ CRITBEGIN
+
mga_setr(M_CRTC_INDEX, 0x0A, 0x20);
+
+ CRITEND
+
ACCESS_FBINFO(cursor.state) = CM_ERASE;
}
return;
@@ -2264,10 +2440,16 @@ static void matrox_text_cursor(struct display* p, int mode, int x, int y) {
ACCESS_FBINFO(cursor.x) = x;
ACCESS_FBINFO(cursor.y) = y;
pos = p->next_line / ACCESS_FBINFO(devflags.textstep) * y + x;
+
+ CRITBEGIN
+
mga_setr(M_CRTC_INDEX, 0x0F, pos);
mga_setr(M_CRTC_INDEX, 0x0E, pos >> 8);
mga_setr(M_CRTC_INDEX, 0x0A, ACCESS_FBINFO(cursor.u));
+
+ CRITEND
+
ACCESS_FBINFO(cursor.state) = CM_DRAW;
}
@@ -2498,7 +2680,7 @@ static void initMatrox(WPMINFO struct display* p) {
/* --------------------------------------------------------------------- */
static struct fb_var_screeninfo vesafb_defined __initdata = {
- 0,0,0,0, /* W,H, W, H (virtual) load xres,xres_virtual*/
+ 640,480,640,480,/* W,H, W, H (virtual) load xres,xres_virtual*/
0,0, /* virtual -> visible no offset */
8, /* depth -> load bits_per_pixel */
0, /* greyscale ? */
@@ -2510,8 +2692,8 @@ static struct fb_var_screeninfo vesafb_defined __initdata = {
FB_ACTIVATE_NOW,
-1,-1,
FB_ACCELF_TEXT, /* accel flags */
- 0L,0L,0L,0L,0L,
- 0L,0L,0, /* No sync info */
+ 39721L,48L,16L,33L,10L,
+ 96L,2L,~0, /* No sync info */
FB_VMODE_NONINTERLACED,
{0,0,0,0,0,0}
};
@@ -2523,6 +2705,9 @@ static struct fb_var_screeninfo vesafb_defined __initdata = {
static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) {
unsigned int pos;
unsigned short p0, p1, p2;
+#ifdef CONFIG_FB_MATROX_32MB
+ unsigned int p3;
+#endif
struct display *disp;
DBG("matrox_pan_var")
@@ -2536,10 +2721,22 @@ static void matrox_pan_var(WPMINFO struct fb_var_screeninfo *var) {
}
p0 = ACCESS_FBINFO(currenthw)->CRTC[0x0D] = pos & 0xFF;
p1 = ACCESS_FBINFO(currenthw)->CRTC[0x0C] = (pos & 0xFF00) >> 8;
- p2 = ACCESS_FBINFO(currenthw)->CRTCEXT[0] = (ACCESS_FBINFO(currenthw)->CRTCEXT[0] & 0xF0) | ((pos >> 16) & 0x0F);
+ p2 = ACCESS_FBINFO(currenthw)->CRTCEXT[0] = (ACCESS_FBINFO(currenthw)->CRTCEXT[0] & 0xB0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40);
+#ifdef CONFIG_FB_MATROX_32MB
+ p3 = ACCESS_FBINFO(currenthw)->CRTCEXT[8] = pos >> 21;
+#endif
+
+ CRITBEGIN
+
mga_setr(M_CRTC_INDEX, 0x0D, p0);
mga_setr(M_CRTC_INDEX, 0x0C, p1);
+#ifdef CONFIG_FB_MATROX_32MB
+ if (ACCESS_FBINFO(devflags.support32MB))
+ mga_setr(M_EXTVGA_INDEX, 0x08, p3);
+#endif
mga_setr(M_EXTVGA_INDEX, 0x00, p2);
+
+ CRITEND
}
/*
@@ -2627,13 +2824,16 @@ static int matroxfb_test_and_set_rounding(CPMINFO int xres, int bpp) {
case 0: return xres;
case 4: rounding = 128;
break;
- case 8: rounding = 64;
+ case 8: rounding = 64; /* doc says 64; 32 is OK for G400 */
break;
case 16: rounding = 32;
break;
- case 24: rounding = 64;
+ case 24: rounding = 64; /* doc says 64; 32 is OK for G400 */
break;
default: rounding = 16;
+ /* on G400, 16 really does not work */
+ if (ACCESS_FBINFO(devflags.accelerator) == FB_ACCEL_MATROX_MGAG400)
+ rounding = 32;
break;
}
if (isInterleave(MINFO)) {
@@ -3140,7 +3340,7 @@ static void DAC1064_setpclk(CPMINFO struct matrox_hw_state* hw, unsigned long fo
hw->DACclk[2] = p;
}
-__initfunc(static void DAC1064_setmclk(CPMINFO struct matrox_hw_state* hw, int oscinfo, unsigned long fmem)) {
+static void __init DAC1064_setmclk(CPMINFO struct matrox_hw_state* hw, int oscinfo, unsigned long fmem){
u_int32_t mx;
DBG("DAC1064_setmclk")
@@ -3288,6 +3488,8 @@ static int DAC1064_init_2(CPMINFO struct matrox_hw_state* hw, struct my_timming*
static void DAC1064_restore_1(CPMINFO const struct matrox_hw_state* hw, const struct matrox_hw_state* oldhw) {
DBG("DAC1064_restore_1")
+
+ CRITBEGIN
outDAC1064(PMINFO DAC1064_XSYSPLLM, hw->DACclk[3]);
outDAC1064(PMINFO DAC1064_XSYSPLLN, hw->DACclk[4]);
@@ -3298,6 +3500,8 @@ static void DAC1064_restore_1(CPMINFO const struct matrox_hw_state* hw, const st
for (i = 0; i < sizeof(MGA1064_DAC_regs); i++)
outDAC1064(PMINFO MGA1064_DAC_regs[i], hw->DACreg[i]);
}
+
+ CRITEND
}
static void DAC1064_restore_2(WPMINFO const struct matrox_hw_state* hw, const struct matrox_hw_state* oldhw, struct display* p) {
@@ -3305,6 +3509,8 @@ static void DAC1064_restore_2(WPMINFO const struct matrox_hw_state* hw, const st
unsigned int tmout;
DBG("DAC1064_restore_2")
+
+ CRITBEGIN
for (i = 0; i < 3; i++)
outDAC1064(PMINFO M1064_XPIXPLLCM + i, hw->DACclk[i]);
@@ -3313,6 +3519,9 @@ static void DAC1064_restore_2(WPMINFO const struct matrox_hw_state* hw, const st
break;
udelay(10);
};
+
+ CRITEND
+
if (!tmout)
printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
@@ -3585,7 +3794,9 @@ static int matroxfb_decode_var(CPMINFO struct display* p, struct fb_var_screenin
var->pixclock = 15000; /* limit for "normal" gclk & mclk */
#endif
}
-
+ /* YDSTLEN contains only signed 16bit value */
+ if (var->yres_virtual > 32767)
+ var->yres_virtual = 32767;
if (var->yres_virtual < var->yres)
var->yres = var->yres_virtual;
if (var->xres_virtual < var->xres)
@@ -3684,7 +3895,7 @@ static int matroxfb_decode_var(CPMINFO struct display* p, struct fb_var_screenin
}
#ifdef CONFIG_FB_MATROX_MILLENIUM
-__initfunc(static void ti3026_setMCLK(CPMINFO struct matrox_hw_state* hw, int fout)) {
+static void __init ti3026_setMCLK(CPMINFO struct matrox_hw_state* hw, int fout){
unsigned int f_pll;
unsigned int pclk_m, pclk_n, pclk_p;
unsigned int mclk_m, mclk_n, mclk_p;
@@ -3783,7 +3994,7 @@ __initfunc(static void ti3026_setMCLK(CPMINFO struct matrox_hw_state* hw, int fo
printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
}
-__initfunc(static void ti3026_ramdac_init(WPMINFO struct matrox_hw_state* hw)) {
+static void __init ti3026_ramdac_init(WPMINFO struct matrox_hw_state* hw){
DBG("ti3026_ramdac_init")
@@ -3800,7 +4011,7 @@ __initfunc(static void ti3026_ramdac_init(WPMINFO struct matrox_hw_state* hw)) {
}
#endif
-__initfunc(static void matroxfb_fastfont_init(struct matrox_fb_info* minfo)) {
+static void matroxfb_fastfont_init(struct matrox_fb_info* minfo){
unsigned int size;
size = ACCESS_FBINFO(fastfont.size);
@@ -3824,7 +4035,7 @@ __initfunc(static void matroxfb_fastfont_init(struct matrox_fb_info* minfo)) {
}
#ifdef CONFIG_FB_MATROX_MYSTIQUE
-__initfunc(static void MGA1064_ramdac_init(WPMINFO struct matrox_hw_state* hw)) {
+static void __init MGA1064_ramdac_init(WPMINFO struct matrox_hw_state* hw){
DBG("MGA1064_ramdac_init");
@@ -3841,7 +4052,7 @@ __initfunc(static void MGA1064_ramdac_init(WPMINFO struct matrox_hw_state* hw))
DAC1064_setmclk(PMINFO hw, DAC1064_OPT_MDIV2 | DAC1064_OPT_GDIV3 | DAC1064_OPT_SCLK_PLL, 133333);
}
-__initfunc(static int MGA1064_preinit(WPMINFO struct matrox_hw_state* hw)) {
+static int __init MGA1064_preinit(WPMINFO struct matrox_hw_state* hw){
static const int vxres_mystique[] = { 512, 640, 768, 800, 832, 960,
1024, 1152, 1280, 1600, 1664, 1920,
2048, 0};
@@ -3873,7 +4084,7 @@ __initfunc(static int MGA1064_preinit(WPMINFO struct matrox_hw_state* hw)) {
return 0;
}
-__initfunc(static void MGA1064_reset(WPMINFO struct matrox_hw_state* hw)) {
+static void __init MGA1064_reset(WPMINFO struct matrox_hw_state* hw){
DBG("MGA1064_reset");
@@ -3893,7 +4104,7 @@ static int x7AF4 = 0x10; /* flags, maybe 0x10 = SDRAM, 0x00 = SGRAM??? */
static int def50 = 0; /* reg50, & 0x0F, & 0x3000 (only 0x0000, 0x1000, 0x2000 (0x3000 disallowed and treated as 0) */
#endif
-__initfunc(static void MGAG100_progPixClock(CPMINFO int flags, int m, int n, int p)) {
+static void __init MGAG100_progPixClock(CPMINFO int flags, int m, int n, int p){
int reg;
int selClk;
int clk;
@@ -3937,7 +4148,7 @@ __initfunc(static void MGAG100_progPixClock(CPMINFO int flags, int m, int n, int
outDAC1064(PMINFO M1064_XPIXCLKCTRL, inDAC1064(PMINFO M1064_XPIXCLKCTRL) & ~M1064_XPIXCLKCTRL_DIS);
}
-__initfunc(static void MGAG100_setPixClock(CPMINFO int flags, int freq)) {
+static void __init MGAG100_setPixClock(CPMINFO int flags, int freq){
unsigned int m, n, p;
DBG("MGAG100_setPixClock")
@@ -3946,7 +4157,7 @@ __initfunc(static void MGAG100_setPixClock(CPMINFO int flags, int freq)) {
MGAG100_progPixClock(PMINFO flags, m, n, p);
}
-__initfunc(static int MGAG100_preinit(WPMINFO struct matrox_hw_state* hw)) {
+static int __init MGAG100_preinit(WPMINFO struct matrox_hw_state* hw){
static const int vxres_g100[] = { 512, 640, 768, 800, 832, 960,
1024, 1152, 1280, 1600, 1664, 1920,
2048, 0};
@@ -4036,7 +4247,7 @@ __initfunc(static int MGAG100_preinit(WPMINFO struct matrox_hw_state* hw)) {
return 0;
}
-__initfunc(static void MGAG100_reset(WPMINFO struct matrox_hw_state* hw)) {
+static void __init MGAG100_reset(WPMINFO struct matrox_hw_state* hw){
u_int8_t b;
DBG("MGAG100_reset")
@@ -4104,6 +4315,8 @@ static void vgaHWrestore(CPMINFO struct matrox_hw_state* hw, struct matrox_hw_st
dprintk("%02X:", hw->ATTR[i]);
dprintk("\n");
+ CRITBEGIN
+
mga_inb(M_ATTR_RESET);
mga_outb(M_ATTR_INDEX, 0);
mga_outb(M_MISC_REG, hw->MiscOutReg);
@@ -4125,6 +4338,8 @@ static void vgaHWrestore(CPMINFO struct matrox_hw_state* hw, struct matrox_hw_st
mga_outb(M_DAC_VAL, hw->DACpal[i]);
mga_inb(M_ATTR_RESET);
mga_outb(M_ATTR_INDEX, 0x20);
+
+ CRITEND
}
static int matrox_setcolreg(unsigned regno, unsigned red, unsigned green,
@@ -4227,10 +4442,15 @@ static void MGA1064_restore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw
int i;
DBG("MGA1064_restore")
+
+ CRITBEGIN
pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
mga_outb(M_IEN, 0x00);
mga_outb(M_CACHEFLUSH, 0x00);
+
+ CRITEND
+
DAC1064_restore_1(PMINFO hw, oldhw);
vgaHWrestore(PMINFO hw, oldhw);
for (i = 0; i < 6; i++)
@@ -4244,10 +4464,18 @@ static void MGAG100_restore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw
int i;
DBG("MGAG100_restore")
-
+
+ CRITBEGIN
+
pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
+ CRITEND
+
DAC1064_restore_1(PMINFO hw, oldhw);
vgaHWrestore(PMINFO hw, oldhw);
+#ifdef CONFIG_FB_MATROX_32MB
+ if (ACCESS_FBINFO(devflags.support32MB))
+ mga_setr(M_EXTVGA_INDEX, 8, hw->CRTCEXT[8]);
+#endif
for (i = 0; i < 6; i++)
mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
DAC1064_restore_2(PMINFO hw, oldhw, p);
@@ -4265,9 +4493,16 @@ static void Ti3026_restore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_
dprintk("%02X:", hw->CRTCEXT[i]);
dprintk("\n");
+ CRITBEGIN
+
pci_write_config_dword(ACCESS_FBINFO(pcidev), PCI_OPTION_REG, hw->MXoptionReg);
+ CRITEND
+
vgaHWrestore(PMINFO hw, oldhw);
+
+ CRITBEGIN
+
for (i = 0; i < 6; i++)
mga_setr(M_EXTVGA_INDEX, i, hw->CRTCEXT[i]);
@@ -4285,11 +4520,13 @@ static void Ti3026_restore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_
oldhw->DACclk[2] = inTi3026(PMINFO TVP3026_XPIXPLLDATA);
oldhw->DACclk[5] = inTi3026(PMINFO TVP3026_XLOOPPLLDATA);
}
+ CRITEND
if (!oldhw || memcmp(hw->DACclk, oldhw->DACclk, 6)) {
/* agrhh... setting up PLL is very slow on Millenium... */
/* Mystique PLL is locked in few ms, but Millenium PLL lock takes about 0.15 s... */
/* Maybe even we should call schedule() ? */
+ CRITBEGIN
outTi3026(PMINFO TVP3026_XCLKCTRL, hw->DACreg[POS3026_XCLKCTRL]);
outTi3026(PMINFO TVP3026_XPLLADDR, 0x2A);
outTi3026(PMINFO TVP3026_XLOOPPLLDATA, 0);
@@ -4307,24 +4544,31 @@ static void Ti3026_restore(WPMINFO struct matrox_hw_state* hw, struct matrox_hw_
break;
udelay(10);
}
+
+ CRITEND
+
if (!tmout)
printk(KERN_ERR "matroxfb: Pixel PLL not locked after 5 secs\n");
else
dprintk(KERN_INFO "PixelPLL: %d\n", 500000-tmout);
+ CRITBEGIN
}
outTi3026(PMINFO TVP3026_XMEMPLLCTRL, hw->DACreg[POS3026_XMEMPLLCTRL]);
outTi3026(PMINFO TVP3026_XPLLADDR, 0x00);
for (i = 3; i < 6; i++)
outTi3026(PMINFO TVP3026_XLOOPPLLDATA, hw->DACclk[i]);
+ CRITEND
if ((hw->MiscOutReg & 0x08) && ((hw->DACclk[5] & 0x80) == 0x80)) {
int tmout;
+ CRITBEGIN
outTi3026(PMINFO TVP3026_XPLLADDR, 0x3F);
for (tmout = 500000; tmout; --tmout) {
if (inTi3026(PMINFO TVP3026_XLOOPPLLDATA) & 0x40)
break;
udelay(10);
}
+ CRITEND
if (!tmout)
printk(KERN_ERR "matroxfb: Loop PLL not locked after 5 secs\n");
else
@@ -4378,8 +4622,8 @@ static int matroxfb_get_fix(struct fb_fix_screeninfo *fix, int con,
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id,"MATROX");
- fix->smem_start = (void*)ACCESS_FBINFO(video.base) + ACCESS_FBINFO(curr.ydstorg.bytes);
- fix->smem_len = ACCESS_FBINFO(video.len) - ACCESS_FBINFO(curr.ydstorg.bytes);
+ fix->smem_start = ACCESS_FBINFO(video.base) + ACCESS_FBINFO(curr.ydstorg.bytes);
+ fix->smem_len = ACCESS_FBINFO(video.len_usable) - ACCESS_FBINFO(curr.ydstorg.bytes);
fix->type = p->type;
fix->type_aux = p->type_aux;
fix->visual = p->visual;
@@ -4387,7 +4631,7 @@ static int matroxfb_get_fix(struct fb_fix_screeninfo *fix, int con,
fix->ypanstep = 1;
fix->ywrapstep = 0;
fix->line_length = p->line_length;
- fix->mmio_start = (void*)ACCESS_FBINFO(mmio.base);
+ fix->mmio_start = ACCESS_FBINFO(mmio.base);
fix->mmio_len = ACCESS_FBINFO(mmio.len);
fix->accel = ACCESS_FBINFO(devflags.accelerator);
return 0;
@@ -4531,7 +4775,8 @@ static int matroxfb_set_var(struct fb_var_screeninfo *var, int con,
hw->CRTC[0x0D] = pos & 0xFF;
hw->CRTC[0x0C] = (pos & 0xFF00) >> 8;
- hw->CRTCEXT[0] = (hw->CRTCEXT[0] & 0xF0) | ((pos >> 16) & 0x0F);
+ hw->CRTCEXT[0] = (hw->CRTCEXT[0] & 0xF0) | ((pos >> 16) & 0x0F) | ((pos >> 14) & 0x40);
+ hw->CRTCEXT[8] = pos >> 21;
ACCESS_FBINFO(hw_switch->restore(PMINFO hw, ohw, display));
ACCESS_FBINFO(cursor.redraw) = 1;
ACCESS_FBINFO(currenthw) = hw;
@@ -4717,10 +4962,16 @@ static void matroxfb_blank(int blank, struct fb_info *info)
case 4: seq = 0x20; crtc = 0x30; break;
default: seq = 0x00; crtc = 0x00; break;
}
+
+ CRITBEGIN
+
mga_outb(M_SEQ_INDEX, 1);
mga_outb(M_SEQ_DATA, (mga_inb(M_SEQ_DATA) & ~0x20) | seq);
mga_outb(M_EXTVGA_INDEX, 1);
mga_outb(M_EXTVGA_DATA, (mga_inb(M_EXTVGA_DATA) & ~0x30) | crtc);
+
+ CRITEND
+
#undef minfo
}
@@ -4739,7 +4990,8 @@ static void matroxfb_blank(int blank, struct fb_info *info)
#define RS1056x344 12 /* 132 x 43 text */
#define RS1056x400 13 /* 132 x 50 text */
#define RS1056x480 14 /* 132 x 60 text */
-/* 0F-FF */
+#define RSNoxNo 15
+/* 10-FF */
static struct { int xres, yres, left, right, upper, lower, hslen, vslen, vfreq; } timmings[] __initdata = {
{ 640, 400, 48, 16, 39, 8, 96, 2, 70 },
{ 640, 480, 48, 16, 33, 10, 96, 2, 60 },
@@ -4754,7 +5006,8 @@ static struct { int xres, yres, left, right, upper, lower, hslen, vslen, vfreq;
{ 640, 350, 48, 16, 39, 8, 96, 2, 70 },
{ 1056, 344, 96, 24, 59, 44, 160, 2, 70 },
{ 1056, 400, 96, 24, 39, 8, 160, 2, 70 },
- { 1056, 480, 96, 24, 36, 12, 160, 3, 60 }
+ { 1056, 480, 96, 24, 36, 12, 160, 3, 60 },
+ { 0, 0, ~0, ~0, ~0, ~0, 0, 0, 0 }
};
#define RSDepth(X) (((X) >> 8) & 0x0F)
@@ -4775,13 +5028,14 @@ static struct { struct fb_bitfield red, green, blue, transp; int bits_per_pixel;
{ { 0, 8, 0}, { 0, 8, 0}, { 0, 8, 0}, { 0, 0, 0}, 4 },
{ { 16, 8, 0}, { 8, 8, 0}, { 0, 8, 0}, { 0, 0, 0}, 24 },
{ { 0, 6, 0}, { 0, 6, 0}, { 0, 6, 0}, { 0, 0, 0}, 0 }, /* textmode with (default) VGA8x16 */
- { { 0, 6, 0}, { 0, 6, 0}, { 0, 6, 0}, { 0, 0, 0}, 0 } /* textmode hardwired to VGA8x8 */
+ { { 0, 6, 0}, { 0, 6, 0}, { 0, 6, 0}, { 0, 0, 0}, 0 }, /* textmode hardwired to VGA8x8 */
};
#define RSCreate(X,Y) ((X) | ((Y) << 8))
static struct { unsigned int vesa; unsigned int info; } *RSptr, vesamap[] __initdata = {
/* default must be first */
#ifdef FBCON_HAS_CFB8
+ { ~0, RSCreate(RSNoxNo, RS8bpp ) },
{ 0x101, RSCreate(RS640x480, RS8bpp ) },
{ 0x100, RSCreate(RS640x400, RS8bpp ) },
{ 0x180, RSCreate(RS768x576, RS8bpp ) },
@@ -4793,14 +5047,8 @@ static struct { unsigned int vesa; unsigned int info; } *RSptr, vesamap[] __init
{ 0x198, RSCreate(RS1408x1056, RS8bpp ) },
{ 0x11C, RSCreate(RS1600x1200, RS8bpp ) },
#endif
-#ifdef FBCON_HAS_CFB4
- { 0x010, RSCreate(RS640x350, RS4bpp ) },
- { 0x012, RSCreate(RS640x480, RS4bpp ) },
- { 0x102, RSCreate(RS800x600, RS4bpp ) },
- { 0x104, RSCreate(RS1024x768, RS4bpp ) },
- { 0x106, RSCreate(RS1280x1024, RS4bpp ) },
-#endif
#ifdef FBCON_HAS_CFB16
+ { ~0, RSCreate(RSNoxNo, RS15bpp) },
{ 0x110, RSCreate(RS640x480, RS15bpp) },
{ 0x181, RSCreate(RS768x576, RS15bpp) },
{ 0x113, RSCreate(RS800x600, RS15bpp) },
@@ -4821,6 +5069,7 @@ static struct { unsigned int vesa; unsigned int info; } *RSptr, vesamap[] __init
{ 0x11E, RSCreate(RS1600x1200, RS16bpp) },
#endif
#ifdef FBCON_HAS_CFB24
+ { ~0, RSCreate(RSNoxNo, RS24bpp) },
{ 0x1B2, RSCreate(RS640x480, RS24bpp) },
{ 0x184, RSCreate(RS768x576, RS24bpp) },
{ 0x1B5, RSCreate(RS800x600, RS24bpp) },
@@ -4832,6 +5081,7 @@ static struct { unsigned int vesa; unsigned int info; } *RSptr, vesamap[] __init
{ 0x1BF, RSCreate(RS1600x1200, RS24bpp) },
#endif
#ifdef FBCON_HAS_CFB32
+ { ~0, RSCreate(RSNoxNo, RS32bpp) },
{ 0x112, RSCreate(RS640x480, RS32bpp) },
{ 0x183, RSCreate(RS768x576, RS32bpp) },
{ 0x115, RSCreate(RS800x600, RS32bpp) },
@@ -4843,6 +5093,7 @@ static struct { unsigned int vesa; unsigned int info; } *RSptr, vesamap[] __init
{ 0x11F, RSCreate(RS1600x1200, RS32bpp) },
#endif
#ifdef FBCON_HAS_VGATEXT
+ { ~0, RSCreate(RSNoxNo, RSText) },
{ 0x002, RSCreate(RS640x400, RSText) }, /* 80x25 */
{ 0x003, RSCreate(RS640x400, RSText) }, /* 80x25 */
{ 0x007, RSCreate(RS640x400, RSText) }, /* 80x25 */
@@ -4853,6 +5104,14 @@ static struct { unsigned int vesa; unsigned int info; } *RSptr, vesamap[] __init
{ 0x10B, RSCreate(RS1056x400, RSText8) }, /* 132x50 */
{ 0x10C, RSCreate(RS1056x480, RSText8) }, /* 132x60 */
#endif
+#ifdef FBCON_HAS_CFB4
+ { ~0, RSCreate(RSNoxNo, RS4bpp ) },
+ { 0x010, RSCreate(RS640x350, RS4bpp ) },
+ { 0x012, RSCreate(RS640x480, RS4bpp ) },
+ { 0x102, RSCreate(RS800x600, RS4bpp ) },
+ { 0x104, RSCreate(RS1024x768, RS4bpp ) },
+ { 0x106, RSCreate(RS1280x1024, RS4bpp ) },
+#endif
{ 0, 0 }};
/* initialized by setup, see explanation at end of file (search for MODULE_PARM_DESC) */
@@ -4871,19 +5130,21 @@ static int inverse = 0; /* "matrox:inverse" */
static int hwcursor = 1; /* "matrox:nohwcursor" */
static int blink = 1; /* "matrox:noblink" */
static int sgram = 0; /* "matrox:sgram" */
+#ifdef CONFIG_MTRR
static int mtrr = 1; /* "matrox:nomtrr" */
+#endif
static int grayscale = 0; /* "matrox:grayscale" */
static unsigned int fastfont = 0; /* "matrox:fastfont:xxxxx" */
static int dev = -1; /* "matrox:dev:xxxxx" */
-static unsigned int vesa = 0x101; /* "matrox:vesa:xxxxx" */
+static unsigned int vesa = ~0; /* "matrox:vesa:xxxxx" */
static int depth = -1; /* "matrox:depth:xxxxx" */
static unsigned int xres = 0; /* "matrox:xres:xxxxx" */
static unsigned int yres = 0; /* "matrox:yres:xxxxx" */
-static unsigned int upper = 0; /* "matrox:upper:xxxxx" */
-static unsigned int lower = 0; /* "matrox:lower:xxxxx" */
+static unsigned int upper = ~0; /* "matrox:upper:xxxxx" */
+static unsigned int lower = ~0; /* "matrox:lower:xxxxx" */
static unsigned int vslen = 0; /* "matrox:vslen:xxxxx" */
-static unsigned int left = 0; /* "matrox:left:xxxxx" */
-static unsigned int right = 0; /* "matrox:right:xxxxx" */
+static unsigned int left = ~0; /* "matrox:left:xxxxx" */
+static unsigned int right = ~0; /* "matrox:right:xxxxx" */
static unsigned int hslen = 0; /* "matrox:hslen:xxxxx" */
static unsigned int pixclock = 0; /* "matrox:pixclock:xxxxx" */
static int sync = -1; /* "matrox:sync:xxxxx" */
@@ -4893,7 +5154,11 @@ static unsigned int maxclk = 0; /* "matrox:maxclk:xxxxM" */
static char fontname[64]; /* "matrox:font:xxxxx" */
#ifndef MODULE
-__initfunc(void matroxfb_setup(char *options, int *ints)) {
+static char videomode[64]; /* "matrox:mode:xxxxx" or "matrox:xxxxx" */
+#endif
+
+#ifndef MODULE
+int __init matroxfb_setup(char *options) {
char *this_opt;
DBG("matroxfb_setup")
@@ -4901,7 +5166,7 @@ __initfunc(void matroxfb_setup(char *options, int *ints)) {
fontname[0] = '\0';
if (!options || !*options)
- return;
+ return 0;
for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) {
if (!*this_opt) continue;
@@ -4945,7 +5210,7 @@ __initfunc(void matroxfb_setup(char *options, int *ints)) {
else if (!strncmp(this_opt, "vesa:", 5))
vesa = simple_strtoul(this_opt+5, NULL, 0);
else if (!strncmp(this_opt, "font:", 5))
- strcpy(fontname, this_opt+5);
+ strncpy(fontname, this_opt+5, sizeof(fontname)-1);
else if (!strncmp(this_opt, "maxclk:", 7))
maxclk = simple_strtoul(this_opt+7, NULL, 0);
else if (!strncmp(this_opt, "fh:", 3))
@@ -4954,6 +5219,31 @@ __initfunc(void matroxfb_setup(char *options, int *ints)) {
fv = simple_strtoul(this_opt+3, NULL, 0);
else if (!strncmp(this_opt, "mem:", 4))
mem = simple_strtoul(this_opt+4, NULL, 0);
+ else if (!strncmp(this_opt, "mode:", 5))
+ strncpy(videomode, this_opt+5, sizeof(videomode)-1);
+#ifdef CONFIG_FB_OF
+ else if (!strncmp(this_opt, "vmode:", 6)) {
+ unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
+ if (vmode > 0 && vmode <= VMODE_MAX)
+ default_vmode = vmode;
+ } else if (!strncmp(this_opt, "cmode:", 6)) {
+ unsigned int cmode = simple_strtoul(this_opt+6, NULL, 0);
+ switch (cmode) {
+ case 0:
+ case 8:
+ default_cmode = CMODE_8;
+ break;
+ case 15:
+ case 16:
+ default_cmode = CMODE_16;
+ break;
+ case 24:
+ case 32:
+ default_cmode = CMODE_32;
+ break;
+ }
+ }
+#endif
else if (!strncmp(this_opt, "fastfont:", 9))
fastfont = simple_strtoul(this_opt+9, NULL, 0);
else if (!strcmp(this_opt, "nofastfont")) /* fastfont:N and nofastfont (nofastfont = fastfont:0) */
@@ -4987,8 +5277,10 @@ __initfunc(void matroxfb_setup(char *options, int *ints)) {
nobios = !value;
else if (!strcmp(this_opt, "init"))
noinit = !value;
+#ifdef CONFIG_MTRR
else if (!strcmp(this_opt, "mtrr"))
mtrr = value;
+#endif
else if (!strcmp(this_opt, "inv24"))
inv24 = value;
else if (!strcmp(this_opt, "cross4MB"))
@@ -5000,19 +5292,20 @@ __initfunc(void matroxfb_setup(char *options, int *ints)) {
else if (!strcmp(this_opt, "grayscale"))
grayscale = value;
else {
- printk(KERN_ERR "matroxfb: unknown parameter %s%s\n", value?"":"no", this_opt);
+ strncpy(videomode, this_opt, sizeof(videomode)-1);
}
}
}
+ return 0;
}
-#endif
+#endif /* !MODULE */
-__initfunc(static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int* realOffset, unsigned int *realSize)) {
+static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned int* realOffset, unsigned int *realSize){
vaddr_t vm;
unsigned int offs;
unsigned int offs2;
unsigned char store;
- unsigned char bytes[16];
+ unsigned char bytes[32];
unsigned char* tmp;
unsigned long cbase;
unsigned long mbase;
@@ -5025,7 +5318,7 @@ __initfunc(static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned
maxSize &= ~0x1FFFFF; /* must be X*2MB (really it must be 2 or X*4MB) */
/* at least 2MB */
if (maxSize < 0x0200000) return 0;
- if (maxSize > 0x1000000) maxSize = 0x1000000;
+ if (maxSize > 0x2000000) maxSize = 0x2000000;
mga_outb(M_EXTVGA_INDEX, 0x03);
mga_outb(M_EXTVGA_DATA, mga_inb(M_EXTVGA_DATA) | 0x80);
@@ -5080,7 +5373,7 @@ __initfunc(static int matroxfb_getmemory(WPMINFO unsigned int maxSize, unsigned
}
#ifdef CONFIG_FB_MATROX_MILLENIUM
-__initfunc(static int Ti3026_preinit(WPMINFO struct matrox_hw_state* hw)) {
+static int __init Ti3026_preinit(WPMINFO struct matrox_hw_state* hw){
static const int vxres_mill2[] = { 512, 640, 768, 800, 832, 960,
1024, 1152, 1280, 1600, 1664, 1920,
2048, 0};
@@ -5133,7 +5426,7 @@ __initfunc(static int Ti3026_preinit(WPMINFO struct matrox_hw_state* hw)) {
return 0;
}
-__initfunc(static void Ti3026_reset(WPMINFO struct matrox_hw_state* hw)) {
+static void __init Ti3026_reset(WPMINFO struct matrox_hw_state* hw){
DBG("Ti3026_reset")
@@ -5163,20 +5456,28 @@ static struct matrox_switch matrox_G100 = {
struct video_board {
int maxvram;
+ int maxdisplayable;
int accelID;
struct matrox_switch* lowlevel;
};
#ifdef CONFIG_FB_MATROX_MILLENIUM
-static struct video_board vbMillenium __initdata = {0x0800000, FB_ACCEL_MATROX_MGA2064W, &matrox_millenium};
-static struct video_board vbMillenium2 __initdata = {0x1000000, FB_ACCEL_MATROX_MGA2164W, &matrox_millenium};
-static struct video_board vbMillenium2A __initdata = {0x1000000, FB_ACCEL_MATROX_MGA2164W_AGP, &matrox_millenium};
+static struct video_board vbMillenium __initdata = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGA2064W, &matrox_millenium};
+static struct video_board vbMillenium2 __initdata = {0x1000000, 0x0800000, FB_ACCEL_MATROX_MGA2164W, &matrox_millenium};
+static struct video_board vbMillenium2A __initdata = {0x1000000, 0x0800000, FB_ACCEL_MATROX_MGA2164W_AGP, &matrox_millenium};
#endif /* CONFIG_FB_MATROX_MILLENIUM */
#ifdef CONFIG_FB_MATROX_MYSTIQUE
-static struct video_board vbMystique __initdata = {0x0800000, FB_ACCEL_MATROX_MGA1064SG, &matrox_mystique};
+static struct video_board vbMystique __initdata = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGA1064SG, &matrox_mystique};
#endif /* CONFIG_FB_MATROX_MYSTIQUE */
#ifdef CONFIG_FB_MATROX_G100
-static struct video_board vbG100 __initdata = {0x0800000, FB_ACCEL_MATROX_MGAG100, &matrox_G100};
-static struct video_board vbG200 __initdata = {0x1000000, FB_ACCEL_MATROX_MGAG200, &matrox_G100};
+static struct video_board vbG100 __initdata = {0x0800000, 0x0800000, FB_ACCEL_MATROX_MGAG100, &matrox_G100};
+static struct video_board vbG200 __initdata = {0x1000000, 0x1000000, FB_ACCEL_MATROX_MGAG200, &matrox_G100};
+#ifdef CONFIG_FB_MATROX_32MB
+/* from doc it looks like that accelerator can draw only to low 16MB :-( Direct accesses & displaying are OK for
+ whole 32MB */
+static struct video_board vbG400 __initdata = {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG400, &matrox_G100};
+#else
+static struct video_board vbG400 __initdata = {0x2000000, 0x1000000, FB_ACCEL_MATROX_MGAG400, &matrox_G100};
+#endif
#endif
#define DEVF_VIDEO64BIT 0x01
@@ -5185,6 +5486,15 @@ static struct video_board vbG200 __initdata = {0x1000000, FB_ACCEL_MATROX_MGAG2
#define DEVF_MILLENIUM2 0x08
#define DEVF_CROSS4MB 0x10
#define DEVF_TEXT4B 0x20
+#define DEVF_DDC_8_2 0x40
+#define DEVF_DMA 0x80
+#define DEVF_SUPPORT32MB 0x100
+#define DEVF_ANY_VXRES 0x200
+
+#define DEVF_G100 (DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB | DEVF_DDC_8_2) /* no doc, no vxres... */
+#define DEVF_G200 (DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB | DEVF_DDC_8_2 | DEVF_ANY_VXRES)
+#define DEVF_G400 (DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB | DEVF_DDC_8_2 | DEVF_ANY_VXRES | DEVF_SUPPORT32MB)
+
static struct board {
unsigned short vendor, device, rev, svid, sid;
unsigned int flags;
@@ -5229,88 +5539,94 @@ static struct board {
#ifdef CONFIG_FB_MATROX_G100
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100, 0xFF,
PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MGA_G100_PCI,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G100,
230000,
&vbG100,
"MGA-G100 (PCI)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100, 0xFF,
0, 0,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G100,
230000,
&vbG100,
"unknown G100 (PCI)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 0xFF,
PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_GENERIC,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G100,
230000,
&vbG100,
"MGA-G100 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 0xFF,
PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MGA_G100_AGP,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G100,
230000,
&vbG100,
"MGA-G100 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 0xFF,
PCI_SS_VENDOR_ID_SIEMENS_NIXDORF, PCI_SS_ID_SIEMENS_MGA_G100_AGP,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G100,
230000,
&vbG100,
"MGA-G100 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 0xFF,
PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_PRODUCTIVA_G100_AGP,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G100,
230000,
&vbG100,
"Productiva G100 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G100_AGP, 0xFF,
0, 0,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G100,
230000,
&vbG100,
"unknown G100 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_PCI, 0xFF,
0, 0,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G200,
250000,
&vbG200,
"unknown G200 (PCI)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF,
PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_GENERIC,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G200,
220000,
&vbG200,
"MGA-G200 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF,
PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MYSTIQUE_G200_AGP,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G200,
230000,
&vbG200,
"Mystique G200 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF,
PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MILLENIUM_G200_AGP,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G200,
250000,
&vbG200,
"Millennium G200 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF,
PCI_SS_VENDOR_ID_MATROX, PCI_SS_ID_MATROX_MARVEL_G200_AGP,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G200,
230000,
&vbG200,
"Marvel G200 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF,
PCI_SS_VENDOR_ID_SIEMENS_NIXDORF, PCI_SS_ID_SIEMENS_MGA_G200_AGP,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G200,
230000,
&vbG200,
"MGA-G200 (AGP)"},
{PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G200_AGP, 0xFF,
0, 0,
- DEVF_VIDEO64BIT | DEVF_SWAPS | DEVF_CROSS4MB,
+ DEVF_G200,
230000,
&vbG200,
"unknown G200 (AGP)"},
+ {PCI_VENDOR_ID_MATROX, PCI_DEVICE_ID_MATROX_G400_AGP, 0xFF,
+ 0, 0,
+ DEVF_G400,
+ 360000,
+ &vbG400,
+ "unknown G400 (AGP)"},
#endif
{0, 0, 0xFF,
0, 0,
@@ -5319,7 +5635,17 @@ static struct board {
NULL,
NULL}};
-__initfunc(static int initMatrox2(WPMINFO struct display* d, struct board* b)) {
+#ifndef MODULE
+ /* it cannot be static const struct due to __initdata
+ marker */
+ static struct fb_videomode defaultmode __initdata = {
+ /* 640x480 @ 60Hz, 31.5 kHz */
+ NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
+ 0, FB_VMODE_NONINTERLACED
+ };
+#endif /* !MODULE */
+
+static int __init initMatrox2(WPMINFO struct display* d, struct board* b){
unsigned long ctrlptr_phys = 0;
unsigned long video_base_phys = 0;
unsigned int memsize;
@@ -5348,17 +5674,21 @@ __initfunc(static int initMatrox2(WPMINFO struct display* d, struct board* b)) {
ACCESS_FBINFO(devflags.vgastepdisp) = 64;
ACCESS_FBINFO(devflags.text_type_aux) = FB_AUX_TEXT_MGA_STEP8;
}
+#ifdef CONFIG_FB_MATROX_32MB
+ ACCESS_FBINFO(devflags.support32MB) = b->flags & DEVF_SUPPORT32MB;
+#endif
+ ACCESS_FBINFO(devflags.precise_width) = !(b->flags & DEVF_ANY_VXRES);
ACCESS_FBINFO(devflags.textstep) = ACCESS_FBINFO(devflags.vgastep) * ACCESS_FBINFO(devflags.textmode);
ACCESS_FBINFO(devflags.textvram) = 65536 / ACCESS_FBINFO(devflags.textmode);
if (ACCESS_FBINFO(capable.cross4MB) < 0)
ACCESS_FBINFO(capable.cross4MB) = b->flags & DEVF_CROSS4MB;
if (b->flags & DEVF_SWAPS) {
- ctrlptr_phys = ACCESS_FBINFO(pcidev)->base_address[1] & ~0x3FFF;
- video_base_phys = ACCESS_FBINFO(pcidev)->base_address[0] & ~0x7FFFFF; /* aligned at 8MB (or 16 for Mill 2) */
+ ctrlptr_phys = ACCESS_FBINFO(pcidev)->resource[1].start;
+ video_base_phys = ACCESS_FBINFO(pcidev)->resource[0].start;
} else {
- ctrlptr_phys = ACCESS_FBINFO(pcidev)->base_address[0] & ~0x3FFF;
- video_base_phys = ACCESS_FBINFO(pcidev)->base_address[1] & ~0x7FFFFF; /* aligned at 8MB */
+ ctrlptr_phys = ACCESS_FBINFO(pcidev)->resource[0].start;
+ video_base_phys = ACCESS_FBINFO(pcidev)->resource[1].start;
}
if (!ctrlptr_phys) {
printk(KERN_ERR "matroxfb: control registers are not available, matroxfb disabled\n");
@@ -5472,8 +5802,8 @@ __initfunc(static int initMatrox2(WPMINFO struct display* d, struct board* b)) {
return -ENOMEM;
}
ACCESS_FBINFO(video.len_usable) = ACCESS_FBINFO(video.len);
- if (ACCESS_FBINFO(video.len_usable) > 0x08000000)
- ACCESS_FBINFO(video.len_usable) = 0x08000000;
+ if (ACCESS_FBINFO(video.len_usable) > b->base->maxdisplayable)
+ ACCESS_FBINFO(video.len_usable) = b->base->maxdisplayable;
#ifdef CONFIG_MTRR
if (mtrr) {
ACCESS_FBINFO(mtrr.vram) = mtrr_add(video_base_phys, ACCESS_FBINFO(video.len), MTRR_TYPE_WRCOMB, 1);
@@ -5482,11 +5812,16 @@ __initfunc(static int initMatrox2(WPMINFO struct display* d, struct board* b)) {
}
#endif /* CONFIG_MTRR */
+ if (!ACCESS_FBINFO(devflags.novga))
+ request_region(0x3C0, 32, "matrox");
+ ACCESS_FBINFO(hw_switch->reset(PMINFO hw));
+
/* validate params, autodetect k, M */
if (fh < 1000) fh *= 1000; /* 1kHz minimum */
if (maxclk < 1000) maxclk *= 1000; /* kHz -> Hz, MHz -> kHz */
if (maxclk < 1000000) maxclk *= 1000; /* kHz -> Hz, 1MHz minimum */
- vesa &= 0x1DFF; /* mask out clearscreen, acceleration and so on */
+ if (vesa != ~0)
+ vesa &= 0x1DFF; /* mask out clearscreen, acceleration and so on */
ACCESS_FBINFO(fbcon.monspecs.hfmin) = 0;
ACCESS_FBINFO(fbcon.monspecs.hfmax) = fh;
@@ -5504,19 +5839,19 @@ __initfunc(static int initMatrox2(WPMINFO struct display* d, struct board* b)) {
}
{
int res = RSResolution(RSptr->info)-1;
- if (!left)
+ if (left == ~0)
left = timmings[res].left;
if (!xres)
xres = timmings[res].xres;
- if (!right)
+ if (right == ~0)
right = timmings[res].right;
if (!hslen)
hslen = timmings[res].hslen;
- if (!upper)
+ if (upper == ~0)
upper = timmings[res].upper;
if (!yres)
yres = timmings[res].yres;
- if (!lower)
+ if (lower == ~0)
lower = timmings[res].lower;
if (!vslen)
vslen = timmings[res].vslen;
@@ -5525,38 +5860,6 @@ __initfunc(static int initMatrox2(WPMINFO struct display* d, struct board* b)) {
if (depth == -1)
depth = RSDepth(RSptr->info);
}
- if (sync == -1) {
- sync = 0;
- if (yres < 400)
- sync |= FB_SYNC_HOR_HIGH_ACT;
- else if (yres < 480)
- sync |= FB_SYNC_VERT_HIGH_ACT;
- }
- if (xres < 320)
- xres = 320;
- if (xres > 2048)
- xres = 2048;
- if (yres < 200)
- yres = 200;
- if (yres > 2048)
- yres = 2048;
- {
- unsigned int tmp;
-
- if (fv) {
- tmp = fv * (upper + yres + lower + vslen);
- if ((tmp < fh) || (fh == 0)) fh = tmp;
- }
- if (fh) {
- tmp = fh * (left + xres + right + hslen);
- if ((tmp < maxclk) || (maxclk == 0)) maxclk = tmp;
- }
- maxclk = (maxclk + 499) / 500;
- if (maxclk) {
- tmp = (2000000000 + maxclk) / maxclk;
- if (tmp > pixclock) pixclock = tmp;
- }
- }
if ((depth == RSText8) && (!*ACCESS_FBINFO(fbcon.fontname))) {
strcpy(ACCESS_FBINFO(fbcon.fontname), "VGA8x8");
}
@@ -5564,27 +5867,8 @@ __initfunc(static int initMatrox2(WPMINFO struct display* d, struct board* b)) {
vesafb_defined.green = colors[depth-1].green;
vesafb_defined.blue = colors[depth-1].blue;
vesafb_defined.bits_per_pixel = colors[depth-1].bits_per_pixel;
- if (pixclock < 2000) /* > 500MHz */
- pixclock = 4000; /* 250MHz */
- if (pixclock > 1000000)
- pixclock = 1000000; /* 1MHz */
- vesafb_defined.xres = xres;
- vesafb_defined.yres = yres;
- vesafb_defined.xoffset = 0;
- vesafb_defined.yoffset = 0;
vesafb_defined.grayscale = grayscale;
- vesafb_defined.pixclock = pixclock;
- vesafb_defined.left_margin = left;
- vesafb_defined.right_margin = right;
- vesafb_defined.hsync_len = hslen;
- vesafb_defined.upper_margin = upper;
- vesafb_defined.lower_margin = lower;
- vesafb_defined.vsync_len = vslen;
- vesafb_defined.sync = sync;
vesafb_defined.vmode = 0;
-
- if (!ACCESS_FBINFO(devflags.novga))
- request_region(0x3C0, 32, "matrox");
if (noaccel)
vesafb_defined.accel_flags &= ~FB_ACCELF_TEXT;
@@ -5597,8 +5881,72 @@ __initfunc(static int initMatrox2(WPMINFO struct display* d, struct board* b)) {
ACCESS_FBINFO(fbcon.updatevar) = &matroxfb_updatevar;
ACCESS_FBINFO(fbcon.blank) = &matroxfb_blank;
ACCESS_FBINFO(fbcon.flags) = FBINFO_FLAG_DEFAULT;
- ACCESS_FBINFO(hw_switch->reset(PMINFO hw));
ACCESS_FBINFO(video.len_usable) &= PAGE_MASK;
+
+#ifndef MODULE
+ /* mode database is marked __init ... */
+ {
+ fb_find_mode(&vesafb_defined, &ACCESS_FBINFO(fbcon), videomode[0]?videomode:NULL,
+ NULL, 0, &defaultmode, vesafb_defined.bits_per_pixel);
+ }
+#endif /* !MODULE */
+
+ /* mode modifiers */
+ if (hslen)
+ vesafb_defined.hsync_len = hslen;
+ if (vslen)
+ vesafb_defined.vsync_len = vslen;
+ if (left != ~0)
+ vesafb_defined.left_margin = left;
+ if (right != ~0)
+ vesafb_defined.right_margin = right;
+ if (upper != ~0)
+ vesafb_defined.upper_margin = upper;
+ if (lower != ~0)
+ vesafb_defined.lower_margin = lower;
+ if (xres)
+ vesafb_defined.xres = xres;
+ if (yres)
+ vesafb_defined.yres = yres;
+ if (sync != -1)
+ vesafb_defined.sync = sync;
+ else if (vesafb_defined.sync == ~0) {
+ vesafb_defined.sync = 0;
+ if (yres < 400)
+ vesafb_defined.sync |= FB_SYNC_HOR_HIGH_ACT;
+ else if (yres < 480)
+ vesafb_defined.sync |= FB_SYNC_VERT_HIGH_ACT;
+ }
+
+ /* fv, fh, maxclk limits was specified */
+ {
+ unsigned int tmp;
+
+ if (fv) {
+ tmp = fv * (vesafb_defined.upper_margin + vesafb_defined.yres
+ + vesafb_defined.lower_margin + vesafb_defined.vsync_len);
+ if ((tmp < fh) || (fh == 0)) fh = tmp;
+ }
+ if (fh) {
+ tmp = fh * (vesafb_defined.left_margin + vesafb_defined.xres
+ + vesafb_defined.right_margin + vesafb_defined.hsync_len);
+ if ((tmp < maxclk) || (maxclk == 0)) maxclk = tmp;
+ }
+ maxclk = (maxclk + 499) / 500;
+ if (maxclk) {
+ tmp = (2000000000 + maxclk) / maxclk;
+ if (tmp > pixclock) pixclock = tmp;
+ }
+ }
+ if (pixclock) {
+ if (pixclock < 2000) /* > 500MHz */
+ pixclock = 4000; /* 250MHz */
+ if (pixclock > 1000000)
+ pixclock = 1000000; /* 1MHz */
+ vesafb_defined.pixclock = pixclock;
+ }
+
+ /* FIXME: Where to move this?! */
#if defined(CONFIG_FB_OF)
#if defined(CONFIG_FB_COMPAT_XPMAC)
strcpy(ACCESS_FBINFO(matrox_name), "MTRX,"); /* OpenFirmware naming convension */
@@ -5608,30 +5956,30 @@ __initfunc(static int initMatrox2(WPMINFO struct display* d, struct board* b)) {
#endif
if ((xres <= 640) && (yres <= 480)) {
struct fb_var_screeninfo var;
- int default_vmode = nvram_read_byte(NV_VMODE);
- int default_cmode = nvram_read_byte(NV_CMODE);
-
- if ((default_vmode <= 0) || (default_vmode > VMODE_MAX))
+ if (default_vmode == VMODE_NVRAM) {
+ default_vmode = nvram_read_byte(NV_VMODE);
+ if (default_vmode <= 0 || default_vmode > VMODE_MAX)
+ default_vmode = VMODE_CHOOSE;
+ }
+ if (default_vmode <= 0 || default_vmode > VMODE_MAX)
default_vmode = VMODE_640_480_60;
- if ((default_cmode < CMODE_8) || (default_cmode > CMODE_32))
+ if (default_cmode == CMODE_NVRAM)
+ default_cmode = nvram_read_byte(NV_CMODE);
+ if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
default_cmode = CMODE_8;
if (!mac_vmode_to_var(default_vmode, default_cmode, &var)) {
var.accel_flags = vesafb_defined.accel_flags;
var.xoffset = var.yoffset = 0;
vesafb_defined = var; /* Note: mac_vmode_to_var() doesnot set all parameters */
- }
+ }
}
#endif
- {
- int pixel_size = vesafb_defined.bits_per_pixel;
-
- vesafb_defined.xres_virtual = matroxfb_pitch_adjust(PMINFO vesafb_defined.xres, pixel_size);
- if (nopan) {
- vesafb_defined.yres_virtual = vesafb_defined.yres;
- } else {
- vesafb_defined.yres_virtual = 65536; /* large enough to be INF, but small enough
- to yres_virtual * xres_virtual < 2^32 */
- }
+ vesafb_defined.xres_virtual = vesafb_defined.xres;
+ if (nopan) {
+ vesafb_defined.yres_virtual = vesafb_defined.yres;
+ } else {
+ vesafb_defined.yres_virtual = 65536; /* large enough to be INF, but small enough
+ to yres_virtual * xres_virtual < 2^32 */
}
if (matroxfb_set_var(&vesafb_defined, -2, &ACCESS_FBINFO(fbcon))) {
printk(KERN_ERR "matroxfb: cannot set required parameters\n");
@@ -5647,8 +5995,9 @@ __initfunc(static int initMatrox2(WPMINFO struct display* d, struct board* b)) {
/* We do not have to set currcon to 0... register_framebuffer do it for us on first console
* and we do not want currcon == 0 for subsequent framebuffers */
- if (register_framebuffer(&ACCESS_FBINFO(fbcon)) < 0)
+ if (register_framebuffer(&ACCESS_FBINFO(fbcon)) < 0) {
return -EINVAL;
+ }
printk("fb%d: %s frame buffer device\n",
GET_FB_IDX(ACCESS_FBINFO(fbcon.node)), ACCESS_FBINFO(fbcon.modename));
if (ACCESS_FBINFO(currcon) < 0) {
@@ -5663,7 +6012,7 @@ __initfunc(static int initMatrox2(WPMINFO struct display* d, struct board* b)) {
static struct matrox_fb_info* fb_list = NULL;
-__initfunc(static int matrox_init(void)) {
+static int __init matrox_init(void){
struct pci_dev* pdev = NULL;
DBG("matrox_init")
@@ -5756,7 +6105,7 @@ leave:;
#ifndef MODULE
static int __init initialized = 0;
-__initfunc(void matroxfb_init(void))
+int __init matroxfb_init(void)
{
DBG("matroxfb_init")
@@ -5764,10 +6113,12 @@ __initfunc(void matroxfb_init(void))
initialized = 1;
matrox_init();
}
+ if (!fb_list) return -ENXIO;
+ return 0;
}
#if defined(CONFIG_FB_OF)
-__initfunc(int matrox_of_init(struct device_node *dp)) {
+int __init matrox_of_init(struct device_node *dp){
DBG("matrox_of_init");
if (!initialized) {
@@ -5781,8 +6132,8 @@ __initfunc(int matrox_of_init(struct device_node *dp)) {
#else
-MODULE_AUTHOR("(c) 1998 Petr Vandrovec <vandrove@vc.cvut.cz>");
-MODULE_DESCRIPTION("Accelerated FBDev driver for Matrox Millennium/Mystique/G100/G200");
+MODULE_AUTHOR("(c) 1998,1999 Petr Vandrovec <vandrove@vc.cvut.cz>");
+MODULE_DESCRIPTION("Accelerated FBDev driver for Matrox Millennium/Mystique/G100/G200/G400");
MODULE_PARM(mem, "i");
MODULE_PARM_DESC(mem, "Size of available memory in MB, KB or B (2,4,8,12,16MB, default=autodetect)");
MODULE_PARM(disabled, "i");
@@ -5802,7 +6153,7 @@ MODULE_PARM_DESC(noinit, "Disables W/SG/SD-RAM and bus interface initialization
MODULE_PARM(mtrr, "i");
MODULE_PARM_DESC(mtrr, "This speeds up video memory accesses (0=disabled or 1) (default=1)");
MODULE_PARM(sgram, "i");
-MODULE_PARM_DESC(sgram, "Indicates that G200 has SGRAM memory (0=SDRAM, 1=SGRAM) (default=0)");
+MODULE_PARM_DESC(sgram, "Indicates that G200/G400 has SGRAM memory (0=SDRAM, 1=SGRAM) (default=0)");
MODULE_PARM(inv24, "i");
MODULE_PARM_DESC(inv24, "Inverts clock polarity for 24bpp and loop frequency > 100MHz (default=do not invert polarity)");
MODULE_PARM(inverse, "i");
@@ -5855,14 +6206,20 @@ MODULE_PARM(grayscale, "i");
MODULE_PARM_DESC(grayscale, "Sets display into grayscale. Works perfectly with paletized videomode (4, 8bpp), some limitations apply to 16, 24 and 32bpp videomodes (default=nograyscale)");
MODULE_PARM(cross4MB, "i");
MODULE_PARM_DESC(cross4MB, "Specifies that 4MB boundary can be in middle of line. (default=autodetected)");
+#ifdef CONFIG_FB_OF
+MODULE_PARM(vmode, "i");
+MODULE_PARM_DESC(vmode, "Specify the vmode mode number that should be used (640x480 default)");
+MODULE_PARM(cmode, "i");
+MODULE_PARM_DESC(cmode, "Specify the video depth that should be used (8bit default)");
+#endif
-__initfunc(int init_module(void)) {
+int __init init_module(void){
DBG("init_module")
#ifdef DEBUG
if( disabled )
- return 0;
+ return -ENXIO;
#endif /* DEBUG */
if (depth == 0)
diff --git a/drivers/video/mdacon.c b/drivers/video/mdacon.c
index ae32da083..0c45722fe 100644
--- a/drivers/video/mdacon.c
+++ b/drivers/video/mdacon.c
@@ -182,7 +182,7 @@ static inline void mda_set_cursor_size(int from, int to)
#ifndef MODULE
-__initfunc(void mdacon_setup(char *str, int *ints))
+void __init mdacon_setup(char *str, int *ints)
{
/* command line format: mdacon=<first>,<last> */
@@ -201,7 +201,7 @@ __initfunc(void mdacon_setup(char *str, int *ints))
#ifdef MODULE
static int mda_detect(void)
#else
-__initfunc(static int mda_detect(void))
+static int __init mda_detect(void)
#endif
{
int count=0;
@@ -283,7 +283,7 @@ __initfunc(static int mda_detect(void))
#ifdef MODULE
static void mda_initialize(void)
#else
-__initfunc(static void mda_initialize(void))
+static void __init mda_initialize(void)
#endif
{
write_mda_b(97, 0x00); /* horizontal total */
@@ -312,7 +312,7 @@ __initfunc(static void mda_initialize(void))
#ifdef MODULE
static const char *mdacon_startup(void)
#else
-__initfunc(static const char *mdacon_startup(void))
+static const char __init *mdacon_startup(void)
#endif
{
mda_num_columns = 80;
@@ -591,7 +591,7 @@ struct consw mda_con = {
#ifdef MODULE
void mda_console_init(void)
#else
-__initfunc(void mda_console_init(void))
+void __init mda_console_init(void)
#endif
{
if (mda_first_vc > mda_last_vc)
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
new file mode 100644
index 000000000..af58b457a
--- /dev/null
+++ b/drivers/video/modedb.c
@@ -0,0 +1,410 @@
+/*
+ * linux/drivers/video/modedb.c -- Standard video mode database management
+ *
+ * Copyright (C) 1999 Geert Uytterhoeven
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+
+#include <linux/tty.h>
+#include <linux/fb.h>
+#include <linux/console_struct.h>
+#include <linux/sched.h>
+
+
+#define DEBUG
+
+#define name_matches(v, s, l) \
+ ((v).name && !strncmp((s), (v).name, (l)) && strlen((v).name) == (l))
+#define res_matches(v, x, y) \
+ ((v).xres == (x) && (v).yres == (y))
+
+#ifdef DEBUG
+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
+#else
+#define DPRINTK(fmt, args...)
+#endif
+
+
+const char *global_mode_option = NULL;
+
+
+ /*
+ * Standard video mode definitions (taken from XFree86)
+ */
+
+#define DEFAULT_MODEDB_INDEX 0
+
+static const struct fb_videomode modedb[] __initdata = {
+ {
+ /* 640x400 @ 70 Hz, 31.5 kHz hsync */
+ NULL, 70, 640, 400, 39721, 40, 24, 39, 9, 96, 2,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 640x480 @ 60 Hz, 31.5 kHz hsync */
+ NULL, 60, 640, 480, 39721, 40, 24, 32, 11, 96, 2,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 800x600 @ 56 Hz, 35.15 kHz hsync */
+ NULL, 56, 800, 600, 27777, 128, 24, 22, 1, 72, 2,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1024x768 @ 87 Hz interlaced, 35.5 kHz hsync */
+ NULL, 87, 1024, 768, 22271, 56, 24, 33, 8, 160, 8,
+ 0, FB_VMODE_INTERLACED
+ }, {
+ /* 640x400 @ 85 Hz, 37.86 kHz hsync */
+ NULL, 85, 640, 400, 31746, 96, 32, 41, 1, 64, 3,
+ FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }, {
+ /* 640x480 @ 72 Hz, 36.5 kHz hsync */
+ NULL, 72, 640, 480, 31746, 144, 40, 30, 8, 40, 3,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 640x480 @ 75 Hz, 37.50 kHz hsync */
+ NULL, 75, 640, 480, 31746, 120, 16, 16, 1, 64, 3,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 800x600 @ 60 Hz, 37.8 kHz hsync */
+ NULL, 60, 800, 600, 25000, 88, 40, 23, 1, 128, 4,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }, {
+ /* 640x480 @ 85 Hz, 43.27 kHz hsync */
+ NULL, 85, 640, 480, 27777, 80, 56, 25, 1, 56, 3,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
+ NULL, 69, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
+ 0, FB_VMODE_INTERLACED
+ }, {
+ /* 800x600 @ 72 Hz, 48.0 kHz hsync */
+ NULL, 72, 800, 600, 20000, 64, 56, 23, 37, 120, 6,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1024x768 @ 60 Hz, 48.4 kHz hsync */
+ NULL, 60, 1024, 768, 15384, 168, 8, 29, 3, 144, 6,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 640x480 @ 100 Hz, 53.01 kHz hsync */
+ NULL, 100, 640, 480, 21834, 96, 32, 36, 8, 96, 6,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1152x864 @ 60 Hz, 53.5 kHz hsync */
+ NULL, 60, 1152, 864, 11123, 208, 64, 16, 4, 256, 8,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 800x600 @ 85 Hz, 55.84 kHz hsync */
+ NULL, 85, 800, 600, 16460, 160, 64, 36, 16, 64, 5,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1024x768 @ 70 Hz, 56.5 kHz hsync */
+ NULL, 70, 1024, 768, 13333, 144, 24, 29, 3, 136, 6,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1280x1024 @ 87 Hz interlaced, 51 kHz hsync */
+ NULL, 87, 1280, 1024, 12500, 56, 16, 128, 1, 216, 12,
+ 0, FB_VMODE_INTERLACED
+ }, {
+ /* 800x600 @ 100 Hz, 64.02 kHz hsync */
+ NULL, 100, 800, 600, 14357, 160, 64, 30, 4, 64, 6,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1024x768 @ 76 Hz, 62.5 kHz hsync */
+ NULL, 76, 1024, 768, 11764, 208, 8, 36, 16, 120, 3,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1152x864 @ 70 Hz, 62.4 kHz hsync */
+ NULL, 70, 1152, 864, 10869, 106, 56, 20, 1, 160, 10,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1280x1024 @ 61 Hz, 64.2 kHz hsync */
+ NULL, 61, 1280, 1024, 9090, 200, 48, 26, 1, 184, 3,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1024x768 @ 85 Hz, 70.24 kHz hsync */
+ NULL, 85, 1024, 768, 10111, 192, 32, 34, 14, 160, 6,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1152x864 @ 78 Hz, 70.8 kHz hsync */
+ NULL, 78, 1152, 864, 9090, 228, 88, 32, 0, 84, 12,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1280x1024 @ 70 Hz, 74.59 kHz hsync */
+ NULL, 70, 1280, 1024, 7905, 224, 32, 28, 8, 160, 8,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1600x1200 @ 60Hz, 75.00 kHz hsync */
+ NULL, 60, 1600, 1200, 6172, 304, 64, 46, 1, 192, 3,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1152x864 @ 84 Hz, 76.0 kHz hsync */
+ NULL, 84, 1152, 864, 7407, 184, 312, 32, 0, 128, 12,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1280x1024 @ 74 Hz, 78.85 kHz hsync */
+ NULL, 74, 1280, 1024, 7407, 256, 32, 34, 3, 144, 3,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1024x768 @ 100Hz, 80.21 kHz hsync */
+ NULL, 100, 1024, 768, 8658, 192, 32, 21, 3, 192, 10,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1280x1024 @ 76 Hz, 81.13 kHz hsync */
+ NULL, 76, 1280, 1024, 7407, 248, 32, 34, 3, 104, 3,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1600x1200 @ 70 Hz, 87.50 kHz hsync */
+ NULL, 70, 1600, 1200, 5291, 304, 64, 46, 1, 192, 3,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1152x864 @ 100 Hz, 89.62 kHz hsync */
+ NULL, 100, 1152, 864, 7264, 224, 32, 17, 2, 128, 19,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1280x1024 @ 85 Hz, 91.15 kHz hsync */
+ NULL, 85, 1280, 1024, 6349, 224, 64, 44, 1, 160, 3,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1600x1200 @ 75 Hz, 93.75 kHz hsync */
+ NULL, 75, 1600, 1200, 4938, 304, 64, 46, 1, 192, 3,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1600x1200 @ 85 Hz, 105.77 kHz hsync */
+ NULL, 85, 1600, 1200, 4545, 272, 16, 37, 4, 192, 3,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1280x1024 @ 100 Hz, 107.16 kHz hsync */
+ NULL, 100, 1280, 1024, 5502, 256, 32, 26, 7, 128, 15,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1800x1440 @ 64Hz, 96.15 kHz hsync */
+ NULL, 64, 1800, 1440, 4347, 304, 96, 46, 1, 192, 3,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }, {
+ /* 1800x1440 @ 70Hz, 104.52 kHz hsync */
+ NULL, 70, 1800, 1440, 4000, 304, 96, 46, 1, 192, 3,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+ }, {
+ /* 512x384 @ 78 Hz, 31.50 kHz hsync */
+ NULL, 78, 512, 384, 49603, 48, 16, 16, 1, 64, 3,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 512x384 @ 85 Hz, 34.38 kHz hsync */
+ NULL, 85, 512, 384, 45454, 48, 16, 16, 1, 64, 3,
+ 0, FB_VMODE_NONINTERLACED
+ }, {
+ /* 320x200 @ 70 Hz, 31.5 kHz hsync, 8:5 aspect ratio */
+ NULL, 70, 320, 200, 79440, 16, 16, 20, 4, 48, 1,
+ 0, FB_VMODE_DOUBLE
+ }, {
+ /* 320x240 @ 60 Hz, 31.5 kHz hsync, 4:3 aspect ratio */
+ NULL, 60, 320, 240, 79440, 16, 16, 16, 5, 48, 1,
+ 0, FB_VMODE_DOUBLE
+ }, {
+ /* 320x240 @ 72 Hz, 36.5 kHz hsync */
+ NULL, 72, 320, 240, 63492, 16, 16, 16, 4, 48, 2,
+ 0, FB_VMODE_DOUBLE
+ }, {
+ /* 400x300 @ 56 Hz, 35.2 kHz hsync, 4:3 aspect ratio */
+ NULL, 56, 400, 300, 55555, 64, 16, 10, 1, 32, 1,
+ 0, FB_VMODE_DOUBLE
+ }, {
+ /* 400x300 @ 60 Hz, 37.8 kHz hsync */
+ NULL, 60, 400, 300, 50000, 48, 16, 11, 1, 64, 2,
+ 0, FB_VMODE_DOUBLE
+ }, {
+ /* 400x300 @ 72 Hz, 48.0 kHz hsync */
+ NULL, 72, 400, 300, 40000, 32, 24, 11, 19, 64, 3,
+ 0, FB_VMODE_DOUBLE
+ }, {
+ /* 480x300 @ 56 Hz, 35.2 kHz hsync, 8:5 aspect ratio */
+ NULL, 56, 480, 300, 46176, 80, 16, 10, 1, 40, 1,
+ 0, FB_VMODE_DOUBLE
+ }, {
+ /* 480x300 @ 60 Hz, 37.8 kHz hsync */
+ NULL, 60, 480, 300, 41858, 56, 16, 11, 1, 80, 2,
+ 0, FB_VMODE_DOUBLE
+ }, {
+ /* 480x300 @ 63 Hz, 39.6 kHz hsync */
+ NULL, 63, 480, 300, 40000, 56, 16, 11, 1, 80, 2,
+ 0, FB_VMODE_DOUBLE
+ }, {
+ /* 480x300 @ 72 Hz, 48.0 kHz hsync */
+ NULL, 72, 480, 300, 33386, 40, 24, 11, 19, 80, 3,
+ 0, FB_VMODE_DOUBLE
+ },
+};
+
+
+static int __init my_atoi(const char *name)
+{
+ int val = 0;
+
+ for (;; name++) {
+ switch (*name) {
+ case '0'...'9':
+ val = 10*val+(*name-'0');
+ break;
+ default:
+ return val;
+ }
+ }
+}
+
+static int __init PROC_CONSOLE(const struct fb_info *info)
+{
+ int fgc;
+
+ if (info->display_fg != NULL)
+ fgc = info->display_fg->vc_num;
+ else
+ return -1;
+
+ if (!current->tty)
+ return fgc;
+
+ if (current->tty->driver.type != TTY_DRIVER_TYPE_CONSOLE)
+ /* XXX Should report error here? */
+ return fgc;
+
+ if (MINOR(current->tty->device) < 1)
+ return fgc;
+
+ return MINOR(current->tty->device) - 1;
+}
+
+static int __init try_mode(struct fb_var_screeninfo *var, struct fb_info *info,
+ const struct fb_videomode *mode, unsigned int bpp)
+{
+ int err;
+
+ DPRINTK("Trying mode %s %dx%d-%d@%d\n", mode->name ? mode->name : "noname",
+ mode->xres, mode->yres, bpp, mode->refresh);
+ var->xres = mode->xres;
+ var->yres = mode->yres;
+ var->xres_virtual = mode->xres;
+ var->yres_virtual = mode->yres;
+ var->xoffset = 0;
+ var->yoffset = 0;
+ var->bits_per_pixel = bpp;
+ var->activate |= FB_ACTIVATE_TEST;
+ var->pixclock = mode->pixclock;
+ var->left_margin = mode->left_margin;
+ var->right_margin = mode->right_margin;
+ var->upper_margin = mode->upper_margin;
+ var->lower_margin = mode->lower_margin;
+ var->hsync_len = mode->hsync_len;
+ var->vsync_len = mode->vsync_len;
+ var->sync = mode->sync;
+ var->vmode = mode->vmode;
+ err = info->fbops->fb_set_var(var, PROC_CONSOLE(info), info);
+ var->activate &= ~FB_ACTIVATE_TEST;
+ return !err;
+}
+
+
+ /*
+ *
+ * Find a suitable video mode
+ *
+ * Valid mode specifiers (mode_option):
+ *
+ * <xres>x<yres>[-<bpp>][@<refresh>]
+ * <name>[-<bpp>][@<refresh>]
+ *
+ * with <xres>, <yres>, <bpp> and <refresh> decimal numbers and <name> a
+ * string
+ *
+ * The passed struct fb_var_screeninfo is _not_ cleared! This allows you
+ * to supply values for e.g. the grayscale and accel_flags fields.
+ */
+
+int __init fb_find_mode(struct fb_var_screeninfo *var,
+ struct fb_info *info, const char *mode_option,
+ const struct fb_videomode *db, unsigned int dbsize,
+ const struct fb_videomode *default_mode,
+ unsigned int default_bpp)
+{
+ int i, j;
+
+ /* Set up defaults */
+ if (!db) {
+ db = modedb;
+ dbsize = sizeof(modedb)/sizeof(*modedb);
+ }
+ if (!default_mode)
+ default_mode = &modedb[DEFAULT_MODEDB_INDEX];
+ if (!default_bpp)
+ default_bpp = 8;
+
+ /* Did the user specify a video mode? */
+ if (mode_option || (mode_option = global_mode_option)) {
+ const char *name = mode_option;
+ unsigned int namelen = strlen(name);
+ int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
+ unsigned int xres = 0, yres = 0, bpp = default_bpp, refresh = 0;
+ int yres_specified = 0;
+
+ for (i = namelen-1; i >= 0; i--) {
+ switch (name[i]) {
+ case '@':
+ namelen = i;
+ if (!refresh_specified && !bpp_specified &&
+ !yres_specified) {
+ refresh = my_atoi(&name[i+1]);
+ refresh_specified = 1;
+ } else
+ goto done;
+ break;
+ case '-':
+ namelen = i;
+ if (!bpp_specified && !yres_specified) {
+ bpp = my_atoi(&name[i+1]);
+ bpp_specified = 1;
+ } else
+ goto done;
+ break;
+ case 'x':
+ if (!yres_specified) {
+ yres = my_atoi(&name[i+1]);
+ yres_specified = 1;
+ } else
+ goto done;
+ break;
+ case '0'...'9':
+ break;
+ default:
+ goto done;
+ }
+ }
+ if (i < 0 && yres_specified) {
+ xres = my_atoi(name);
+ res_specified = 1;
+ }
+done:
+ for (i = refresh_specified; i >= 0; i--) {
+ DPRINTK("Trying specified video mode%s\n",
+ i ? "" : " (ignoring refresh rate)");
+ for (j = 0; j < dbsize; j++)
+ if ((name_matches(db[j], name, namelen) ||
+ (res_specified && res_matches(db[j], xres, yres))) &&
+ (!i || db[j].refresh == refresh) &&
+ try_mode(var, info, &db[j], bpp))
+ return 2-i;
+ }
+ }
+
+ DPRINTK("Trying default video mode\n");
+ if (try_mode(var, info, default_mode, default_bpp))
+ return 3;
+
+ DPRINTK("Trying all modes\n");
+ for (i = 0; i < dbsize; i++)
+ if (try_mode(var, info, &db[i], default_bpp))
+ return 4;
+
+ DPRINTK("No valid mode found\n");
+ return 0;
+}
diff --git a/drivers/video/newport_con.c b/drivers/video/newport_con.c
index f47cb6c1c..3d461df5d 100644
--- a/drivers/video/newport_con.c
+++ b/drivers/video/newport_con.c
@@ -272,7 +272,7 @@ static void newport_get_revisions(void)
#ifdef MODULE
static const char *newport_startup(void)
#else
-__initfunc(static const char *newport_startup(void))
+static const char * __init newport_startup(void)
#endif
{
struct newport_regs *p;
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index a769e9454..068282244 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -72,8 +72,8 @@ static int ofonly = 0;
* Interface used by the world
*/
-void offb_init(void);
-void offb_setup(char *options, int *ints);
+int offb_init(void);
+int offb_setup(char*);
static int offb_open(struct fb_info *info, int user);
static int offb_release(struct fb_info *info, int user);
@@ -314,13 +314,16 @@ extern void valkyrie_of_init(struct device_node *dp);
#ifdef CONFIG_FB_PLATINUM
extern void platinum_of_init(struct device_node *dp);
#endif /* CONFIG_FB_PLATINUM */
+#ifdef CONFIG_FB_CLGEN
+extern void clgen_of_init(struct device_node *dp);
+#endif /* CONFIG_FB_CLGEN */
/*
* Initialisation
*/
-__initfunc(void offb_init(void))
+int __init offb_init(void)
{
struct device_node *dp;
unsigned int dpy;
@@ -389,9 +392,10 @@ __initfunc(void offb_init(void))
offb_init_driver(dp);
}
}
+ return 0;
}
-__initfunc(static int offb_init_driver(struct device_node *dp))
+static int __init offb_init_driver(struct device_node *dp)
{
#ifdef CONFIG_FB_ATY
if (!strncmp(dp->name, "ATY", 3)) {
@@ -441,10 +445,17 @@ __initfunc(static int offb_init_driver(struct device_node *dp))
return 1;
}
#endif /* CONFIG_FB_PLATINUM */
+#ifdef CONFIG_FB_CLGEN
+ if ((!strncmp(dp->name, "MacPicasso",10) ||
+ (!strncmp(dp->name, "54m30",5)) {
+ clgen_of_init(dp);
+ return 1;
+ }
+#endif /* CONFIG_FB_CLGEN */
return 0;
}
-__initfunc(static void offb_init_nodriver(struct device_node *dp))
+static void __init offb_init_nodriver(struct device_node *dp)
{
int *pp, i;
unsigned int len;
@@ -473,7 +484,7 @@ __initfunc(static void offb_init_nodriver(struct device_node *dp))
if (dp->addrs[i].size >= len)
break;
if (i >= dp->n_addrs) {
- printk("no framebuffer address found for %s\n", dp->full_name);
+ printk(KERN_ERR "no framebuffer address found for %s\n", dp->full_name);
return;
}
@@ -488,9 +499,9 @@ __initfunc(static void offb_init_nodriver(struct device_node *dp))
}
-__initfunc(static void offb_init_fb(const char *name, const char *full_name,
+static void offb_init_fb(const char *name, const char *full_name,
int width, int height, int depth,
- int pitch, unsigned long address))
+ int pitch, unsigned long address)
{
int i;
struct fb_fix_screeninfo *fix;
@@ -501,7 +512,7 @@ __initfunc(static void offb_init_fb(const char *name, const char *full_name,
printk(KERN_INFO "Using unsupported %dx%d %s at %lx, depth=%d, pitch=%d\n",
width, height, name, address, depth, pitch);
if (depth != 8 && depth != 16 && depth != 32) {
- printk("%s: can't use depth = %d\n", full_name, depth);
+ printk(KERN_ERR "%s: can't use depth = %d\n", full_name, depth);
return;
}
@@ -522,7 +533,7 @@ __initfunc(static void offb_init_fb(const char *name, const char *full_name,
var->yres = var->yres_virtual = height;
fix->line_length = pitch;
- fix->smem_start = (char *)address;
+ fix->smem_start = address;
fix->smem_len = pitch * height;
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
@@ -674,7 +685,7 @@ __initfunc(static void offb_init_fb(const char *name, const char *full_name,
return;
}
- printk("fb%d: Open Firmware frame buffer device on %s\n",
+ printk(KERN_INFO "fb%d: Open Firmware frame buffer device on %s\n",
GET_FB_IDX(info->info.node), full_name);
#ifdef CONFIG_FB_COMPAT_XPMAC
@@ -706,13 +717,14 @@ __initfunc(static void offb_init_fb(const char *name, const char *full_name,
* Setup: parse used options
*/
-void offb_setup(char *options, int *ints)
+int offb_setup(char *options)
{
if (!options || !*options)
- return;
+ return 0;
if (!strcmp(options, "ofonly"))
ofonly = 1;
+ return 0;
}
diff --git a/drivers/video/p9100.h b/drivers/video/p9100.h
new file mode 100644
index 000000000..152b41769
--- /dev/null
+++ b/drivers/video/p9100.h
@@ -0,0 +1,87 @@
+/*
+ * Register information for the Weitek P9100 as found
+ * on the Tadpole Sparcbook 3 laptops.
+ *
+ * From the technical specification document provided by Tadpole.
+ *
+ * Derrick J Brashear (shadow@dementia.org)
+ */
+
+#ifndef _P9100_H_
+#define _P9100_H_
+
+/* P9100 control registers */
+#define P9100_SYSCTL_OFF 0x0
+#define P9100_VIDEOCTL_OFF 0x100
+#define P9100_VRAMCTL_OFF 0x180
+#define P9100_RAMDAC_OFF 0x200
+#define P9100_VIDEOCOPROC_OFF 0x400
+
+/* P9100 command registers */
+#define P9100_CMD_OFF 0x0
+
+/* P9100 framebuffer memory */
+#define P9100_FB_OFF 0x0
+
+
+/* 3 bits: 2=8bpp 3=16bpp 5=32bpp 7=24bpp */
+#define SYS_CONFIG_PIXELSIZE_SHIFT 26
+
+#define SCREENPAINT_TIMECTL1_ENABLE_VIDEO 0x20 /* 0 = off, 1 = on */
+
+struct p9100_ctrl {
+ /* Registers for the system control */
+ __volatile__ __u32 sys_base;
+ __volatile__ __u32 sys_config;
+ __volatile__ __u32 sys_intr;
+ __volatile__ __u32 sys_int_ena;
+ __volatile__ __u32 sys_alt_rd;
+ __volatile__ __u32 sys_alt_wr;
+ __volatile__ __u32 sys_xxx[58];
+ /* Registers for the video control */
+ __volatile__ __u32 vid_base;
+ __volatile__ __u32 vid_hcnt;
+ __volatile__ __u32 vid_htotal;
+ __volatile__ __u32 vid_hsync_rise;
+ __volatile__ __u32 vid_hblank_rise;
+ __volatile__ __u32 vid_hblank_fall;
+ __volatile__ __u32 vid_hcnt_preload;
+ __volatile__ __u32 vid_vcnt;
+ __volatile__ __u32 vid_vlen;
+ __volatile__ __u32 vid_vsync_rise;
+ __volatile__ __u32 vid_vblank_rise;
+ __volatile__ __u32 vid_vblank_fall;
+ __volatile__ __u32 vid_vcnt_preload;
+ __volatile__ __u32 vid_screenpaint_addr;
+ __volatile__ __u32 vid_screenpaint_timectl1;
+ __volatile__ __u32 vid_screenpaint_qsfcnt;
+ __volatile__ __u32 vid_screenpaint_timectl2;
+ __volatile__ __u32 vid_xxx[15];
+ /* Registers for the video control */
+ __volatile__ __u32 vram_base;
+ __volatile__ __u32 vram_memcfg;
+ __volatile__ __u32 vram_refresh_pd;
+ __volatile__ __u32 vram_refresh_cnt;
+ __volatile__ __u32 vram_raslo_max;
+ __volatile__ __u32 vram_raslo_cur;
+ __volatile__ __u32 pwrup_cfg;
+ __volatile__ __u32 vram_xxx[25];
+ /* Registers for IBM RGB528 Palette */
+ __volatile__ __u32 ramdac_cmap_wridx;
+ __volatile__ __u32 ramdac_palette_data;
+ __volatile__ __u32 ramdac_pixel_mask;
+ __volatile__ __u32 ramdac_palette_rdaddr;
+ __volatile__ __u32 ramdac_idx_lo;
+ __volatile__ __u32 ramdac_idx_hi;
+ __volatile__ __u32 ramdac_idx_data;
+ __volatile__ __u32 ramdac_idx_ctl;
+ __volatile__ __u32 ramdac_xxx[1784];
+};
+
+struct p9100_cmd_parameng {
+ __volatile__ __u32 parameng_status;
+ __volatile__ __u32 parameng_bltcmd;
+ __volatile__ __u32 parameng_quadcmd;
+};
+
+#endif /* _P9100_H_ */
diff --git a/drivers/video/p9100fb.c b/drivers/video/p9100fb.c
new file mode 100644
index 000000000..cbecb5e4f
--- /dev/null
+++ b/drivers/video/p9100fb.c
@@ -0,0 +1,178 @@
+/* $id: p9100fb.c,v 1.4 1999/08/18 10:55:01 shadow Exp $
+ * p9100fb.c: P9100 frame buffer driver
+ *
+ * Copyright 1999 Derrick J Brashear (shadow@dementia.org)
+ */
+
+#include <linux/module.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/selection.h>
+
+#include <video/sbusfb.h>
+#include <asm/io.h>
+
+#include <video/fbcon-cfb8.h>
+
+#include "p9100.h"
+
+static struct sbus_mmap_map p9100_mmap_map[] = {
+#if 0 /* For now, play we're a dumb color fb */
+ { P9100_CTL_OFF, 0x38000000, 0x2000 },
+ { P9100_CMD_OFF, 0x38002000, 0x2000 },
+ { P9100_FB_OFF, 0x38800000, 0x200000 },
+ { CG3_MMAP_OFFSET, 0x38800000, SBUS_MMAP_FBSIZE(1) },
+#else
+ { CG3_MMAP_OFFSET, 0x0, SBUS_MMAP_FBSIZE(1) },
+#endif
+ { 0, 0, 0 }
+};
+
+#define _READCTL(member, out) \
+{ \
+ struct p9100_ctrl *actual; \
+ actual = (struct p9100_ctrl *)fb->s.p9100.ctrl; \
+ out = actual-> ## member ; \
+}
+
+#define READCTL(member, out) \
+{ \
+ struct p9100_ctrl *enab, *actual; \
+ actual = (struct p9100_ctrl *)fb->s.p9100.ctrl; \
+ enab = (struct p9100_ctrl *)fb->s.p9100.fbmem; \
+ out = enab-> ## member ; \
+ out = actual-> ## member ; \
+}
+
+#define WRITECTL(member, val) \
+{ \
+ u32 __writetmp; \
+ struct p9100_ctrl *enab, *actual; \
+ actual = (struct p9100_ctrl *)fb->s.p9100.ctrl; \
+ enab = (struct p9100_ctrl *)fb->s.p9100.fbmem; \
+ __writetmp = enab-> ## member ; \
+ actual-> ## member = val; \
+}
+
+static void p9100_loadcmap (struct fb_info_sbusfb *fb, struct display *p, int index, int count)
+{
+ int i;
+ u32 tmp;
+
+ _READCTL(pwrup_cfg, tmp);
+ WRITECTL(ramdac_cmap_wridx, (index << 16));
+
+ for (i = index; count--; i++){
+ _READCTL(pwrup_cfg, tmp);
+ WRITECTL(ramdac_palette_data, (fb->color_map CM(i,0) << 16));
+ _READCTL(pwrup_cfg, tmp);
+ WRITECTL(ramdac_palette_data, (fb->color_map CM(i,1) << 16));
+ _READCTL(pwrup_cfg, tmp);
+ WRITECTL(ramdac_palette_data, (fb->color_map CM(i,2) << 16));
+ }
+}
+
+static void p9100_blank (struct fb_info_sbusfb *fb)
+{
+ u32 val;
+ READCTL(vid_screenpaint_timectl1, val);
+ val &= ~ SCREENPAINT_TIMECTL1_ENABLE_VIDEO;
+ WRITECTL(vid_screenpaint_timectl1, val);
+}
+
+static void p9100_unblank (struct fb_info_sbusfb *fb)
+{
+ u32 val;
+ READCTL(vid_screenpaint_timectl1, val);
+ val |= SCREENPAINT_TIMECTL1_ENABLE_VIDEO;
+ WRITECTL(vid_screenpaint_timectl1, val);
+}
+
+static void p9100_margins (struct fb_info_sbusfb *fb, struct display *p, int x_margin, int y_margin)
+{
+ p->screen_base += (y_margin - fb->y_margin) * p->line_length +
+ (x_margin - fb->x_margin);
+}
+
+static char idstring[60] __initdata = { 0 };
+
+char * __init p9100fb_init(struct fb_info_sbusfb *fb)
+{
+ struct fb_fix_screeninfo *fix = &fb->fix;
+ struct display *disp = &fb->disp;
+ struct fbtype *type = &fb->type;
+ unsigned long phys = fb->sbdp->reg_addrs[2].phys_addr;
+ int tmp;
+
+#ifndef FBCON_HAS_CFB8
+ return NULL;
+#endif
+
+ /* Control regs: fb->sbdp->reg_addrs[0].phys_addr
+ * Command regs: fb->sbdp->reg_addrs[1].phys_addr
+ * Frame buffer: fb->sbdp->reg_addrs[2].phys_addr
+ */
+
+ if (!fb->s.p9100.ctrl) {
+ fb->s.p9100.ctrl = (struct p9100_ctrl *)
+ sparc_alloc_io(fb->sbdp->reg_addrs[0].phys_addr, 0,
+ fb->sbdp->reg_addrs[1].reg_size, "p9100_ctrl", fb->iospace, 0);
+ }
+
+ strcpy(fb->info.modename, "p9100");
+ strcpy(fix->id, "p9100");
+ fix->accel = FB_ACCEL_SUN_CGTHREE;
+ fix->line_length = fb->var.xres_virtual;
+
+ disp->scrollmode = SCROLL_YREDRAW;
+ if (!disp->screen_base)
+ disp->screen_base =
+ (char *)sparc_alloc_io(phys, 0, type->fb_size, "p9100_ram",
+ fb->iospace, 0);
+ fb->s.p9100.fbmem = disp->screen_base;
+ disp->screen_base += fix->line_length * fb->y_margin + fb->x_margin;
+
+ READCTL(sys_config, tmp);
+ switch ((tmp >> SYS_CONFIG_PIXELSIZE_SHIFT) & 7) {
+ case 7:
+ type->fb_depth = 24;
+ break;
+ case 5:
+ type->fb_depth = 32;
+ break;
+ case 3:
+ type->fb_depth = 16;
+ break;
+ case 2:
+ type->fb_depth = 8;
+ break;
+ default:
+ printk("p9100: screen depth unknown: 0x%x", tmp);
+ return NULL;
+ }
+
+ fb->dispsw = fbcon_cfb8;
+
+ fb->margins = p9100_margins;
+ fb->loadcmap = p9100_loadcmap;
+ fb->blank = p9100_blank;
+ fb->unblank = p9100_unblank;
+
+ fb->physbase = phys;
+ fb->mmap_map = p9100_mmap_map;
+
+ sprintf(idstring, "%s at 0x%x", "p9100", disp->screen_base);
+
+ return idstring;
+}
+
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index 89f6860f2..cf7fe3418 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -156,11 +156,11 @@ static void do_install_cmap(int con, struct fb_info *info);
* Interface used by the world
*/
-void platinum_init(void);
+int platinum_init(void);
#ifdef CONFIG_FB_OF
void platinum_of_init(struct device_node *dp);
#endif
-void platinum_setup(char *options, int *ints);
+int platinum_setup(char*);
static struct fb_ops platinumfb_ops = {
@@ -581,7 +581,7 @@ static void platinum_set_par(const struct fb_par_platinum *par, struct fb_info_p
}
-__initfunc(static int init_platinum(struct fb_info_platinum *info))
+static int __init init_platinum(struct fb_info_platinum *info)
{
struct fb_var_screeninfo var;
struct display *disp;
@@ -651,7 +651,7 @@ __initfunc(static int init_platinum(struct fb_info_platinum *info))
return 1;
}
-__initfunc(void platinum_init(void))
+int __init platinum_init(void)
{
#ifndef CONFIG_FB_OF
struct device_node *dp;
@@ -660,6 +660,7 @@ __initfunc(void platinum_init(void))
if (dp != 0)
platinum_of_init(dp);
#endif /* CONFIG_FB_OF */
+ return 0;
}
#ifdef __powerpc__
@@ -670,14 +671,16 @@ __initfunc(void platinum_init(void))
#define invalidate_cache(addr)
#endif
-__initfunc(void platinum_of_init(struct device_node *dp))
+void __init platinum_of_init(struct device_node *dp)
{
struct fb_info_platinum *info;
unsigned long addr, size;
int i, bank0, bank1, bank2, bank3;
- if(dp->n_addrs != 2)
- panic("expecting 2 address for platinum (got %d)", dp->n_addrs);
+ if(dp->n_addrs != 2) {
+ printk(KERN_ERR "expecting 2 address for platinum (got %d)", dp->n_addrs);
+ return;
+ }
info = kmalloc(sizeof(*info), GFP_ATOMIC);
if (info == 0)
@@ -834,9 +837,9 @@ static int platinum_encode_fix(struct fb_fix_screeninfo *fix,
{
memset(fix, 0, sizeof(*fix));
strcpy(fix->id, "platinum");
- fix->smem_start = (void *) (info->frame_buffer_phys + 0x1000);
+ fix->smem_start = (info->frame_buffer_phys + 0x1000);
fix->smem_len = (u32) info->total_vram - 0x1000;
- fix->mmio_start = (char *) (info->platinum_regs_phys);
+ fix->mmio_start = (info->platinum_regs_phys);
fix->mmio_len = 0x1000;
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
@@ -854,12 +857,12 @@ static int platinum_encode_fix(struct fb_fix_screeninfo *fix,
/*
* Parse user speficied options (`video=platinumfb:')
*/
-__initfunc(void platinum_setup(char *options, int *ints))
+int __init platinum_setup(char *options)
{
char *this_opt;
if (!options || !*options)
- return;
+ return 0;
for (this_opt = strtok(options, ","); this_opt;
this_opt = strtok(NULL, ",")) {
@@ -895,4 +898,5 @@ __initfunc(void platinum_setup(char *options, int *ints))
}
}
}
+ return 0;
}
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index dfb0f8ae8..343ad3f52 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -50,7 +50,7 @@
#define PM2FB_MASTER_DEBUG
#ifdef PM2FB_MASTER_DEBUG
-#define DPRINTK(a,b...) printk("pm2fb: %s: " a, __FUNCTION__ , ## b)
+#define DPRINTK(a,b...) printk(KERN_DEBUG "pm2fb: %s: " a, __FUNCTION__ , ## b)
#else
#define DPRINTK(a,b...)
#endif
@@ -192,12 +192,12 @@ static struct pm2fb_info {
int board; /* Permedia2 board index (see
board_table[] below) */
struct {
- unsigned char* fb_base; /* framebuffer memory base */
+ unsigned long fb_base; /* physical framebuffer memory base */
u32 fb_size; /* framebuffer memory size */
- unsigned char* rg_base; /* register memory base */
- unsigned char* p_fb; /* physical address of frame buffer */
+ unsigned long rg_base; /* physical register memory base */
+ unsigned long p_fb; /* physical address of frame buffer */
unsigned char* v_fb; /* virtual address of frame buffer */
- unsigned char* p_regs; /* physical address of registers
+ unsigned long p_regs; /* physical address of registers
region, must be rg_base or
rg_base+PM2_REGS_SIZE depending on
the host endianness */
@@ -741,7 +741,7 @@ static void pm2fb_reset(struct pm2fb_info* p) {
set_memclock(p, p->memclock);
}
-__initfunc(static int pm2fb_conf(struct pm2fb_info* p)) {
+static int __init pm2fb_conf(struct pm2fb_info* p){
for (p->board=0; board_table[p->board].detect &&
!(board_table[p->board].detect(p)); p->board++);
@@ -750,13 +750,26 @@ __initfunc(static int pm2fb_conf(struct pm2fb_info* p)) {
return 0;
}
DPRINTK("found board: %s\n", board_table[p->board].name);
+
p->regions.p_fb=p->regions.fb_base;
+ if (!__request_region(&iomem_resource, p->regions.p_fb,
+ p->regions.fb_size, "pm2fb")) {
+ printk (KERN_ERR "pm2fb: cannot reserve fb memory, abort\n");
+ return 0;
+ }
p->regions.v_fb=MMAP(p->regions.p_fb, p->regions.fb_size);
+
#ifdef __LITTLE_ENDIAN
p->regions.p_regs=p->regions.rg_base;
#else
p->regions.p_regs=p->regions.rg_base+PM2_REGS_SIZE;
#endif
+ if (!__request_region(&iomem_resource, p->regions.p_regs,
+ PM2_REGS_SIZE, "pm2fb")) {
+ printk (KERN_ERR "pm2fb: cannot reserve mmio memory, abort\n");
+ UNMAP(p->regions.v_fb, p->regions.fb_size);
+ return 0;
+ }
p->regions.v_regs=MMAP(p->regions.p_regs, PM2_REGS_SIZE);
return 1;
}
@@ -809,9 +822,9 @@ static int cvppc_detect(struct pm2fb_info* p) {
if (!cvppc_PCI_init(&p->board_par.cvppc))
return 0;
- p->regions.fb_base=(unsigned char* )CVPPC_FB_APERTURE_ONE;
+ p->regions.fb_base=CVPPC_FB_APERTURE_ONE;
p->regions.fb_size=CVPPC_FB_SIZE;
- p->regions.rg_base=(unsigned char* )CVPPC_REGS_REGION;
+ p->regions.rg_base=CVPPC_REGS_REGION;
p->memclock=CVPPC_MEMCLOCK;
return 1;
}
@@ -852,27 +865,21 @@ static int pm2pci_detect(struct pm2fb_info* p) {
return 0;
}
DPRINTK("PCI board @%08lx %08lx %08lx rom %08lx\n",
- pci->dev->base_address[0],
- pci->dev->base_address[1],
- pci->dev->base_address[2],
- pci->dev->rom_address);
+ pci->dev->resource[0].start,
+ pci->dev->resource[1].start,
+ pci->dev->resource[2].start,
+ pci->dev->resource[PCI_ROM_RESOURCE].start);
#ifdef __sparc__
- p->regions.rg_base=(unsigned char* )
- __pa(pci->dev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK);
- p->regions.fb_base=(unsigned char* )
- __pa(pci->dev->base_address[1] & PCI_BASE_ADDRESS_MEM_MASK);
+ p->regions.rg_base= __pa(pci->dev->resource[0].start);
+ p->regions.fb_base= __pa(pci->dev->resource[1].start);
#else
if (pm2fb_options.flags & OPTF_VIRTUAL) {
- p->regions.rg_base=(unsigned char* )
- __pa(pci->dev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK);
- p->regions.fb_base=(unsigned char* )
- __pa(pci->dev->base_address[1] & PCI_BASE_ADDRESS_MEM_MASK);
+ p->regions.rg_base= __pa(pci->dev->resource[0].start);
+ p->regions.fb_base= __pa(pci->dev->resource[1].start);
}
else {
- p->regions.rg_base=(unsigned char* )
- (pci->dev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK);
- p->regions.fb_base=(unsigned char* )
- (pci->dev->base_address[1] & PCI_BASE_ADDRESS_MEM_MASK);
+ p->regions.rg_base= (pci->dev->resource[0].start);
+ p->regions.fb_base= (pci->dev->resource[0].start);
}
#endif
#ifdef __BIG_ENDIAN
@@ -1526,14 +1533,14 @@ static int pm2fb_setcolreg(unsigned regno,
}
static void pm2fb_set_disp(const void* par, struct display* disp,
- struct fb_info_gen* info) {
+ struct fb_info_gen* info) {
struct pm2fb_info* i=(struct pm2fb_info* )info;
- u32 flags;
- u32 depth;
+ unsigned long flags;
+ unsigned long depth;
save_flags(flags);
cli();
- disp->screen_base=i->regions.v_fb;
+ disp->screen_base = i->regions.v_fb;
switch (depth=((struct pm2fb_par* )par)->depth) {
#ifdef FBCON_HAS_CFB8
case 8:
@@ -1581,21 +1588,29 @@ static int pm2fb_release(struct fb_info* info, int user) {
* Begin of public functions
***************************************************************************/
-void pm2fb_cleanup(struct fb_info* info) {
- struct pm2fb_info* i=(struct pm2fb_info* )info;
+#ifdef MODULE
+static void pm2fb_cleanup(void) {
+ struct pm2fb_info* i = &fb_info;
- unregister_framebuffer(info);
+ unregister_framebuffer((struct fb_info *)i);
pm2fb_reset(i);
- /* FIXME UNMAP()??? */
+
+ UNMAP(i->regions.v_fb, i->regions.fb_size);
+ __release_region(&iomem_resource, i->regions.p_fb, i->regions.fb_size);
+
+ UNMAP(i->regions.v_regs, PM2_REGS_SIZE);
+ __release_region(&iomem_resource, i->regions.p_regs, PM2_REGS_SIZE);
+
if (board_table[i->board].cleanup)
board_table[i->board].cleanup(i);
}
+#endif /* MODULE */
-__initfunc(void pm2fb_init(void)) {
+int __init pm2fb_init(void){
memset(&fb_info, 0, sizeof(fb_info));
if (!pm2fb_conf(&fb_info))
- return;
+ return -ENXIO;
pm2fb_reset(&fb_info);
fb_info.disp.scrollmode=SCROLL_YNOMOVE;
fb_info.gen.parsize=sizeof(struct pm2fb_par);
@@ -1613,18 +1628,19 @@ __initfunc(void pm2fb_init(void)) {
fbgen_set_disp(-1, &fb_info.gen);
fbgen_install_cmap(0, &fb_info.gen);
if (register_framebuffer(&fb_info.gen.info)<0) {
- printk("pm2fb: unable to register.\n");
- return;
+ printk(KERN_ERR "pm2fb: unable to register.\n");
+ return -EINVAL;
}
- printk("fb%d: %s (%s), using %uK of video memory.\n",
+ printk(KERN_INFO "fb%d: %s (%s), using %uK of video memory.\n",
GET_FB_IDX(fb_info.gen.info.node),
board_table[fb_info.board].name,
permedia2_name,
(u32 )(fb_info.regions.fb_size>>10));
MOD_INC_USE_COUNT;
+ return 0;
}
-__initfunc(void pm2fb_mode_setup(char* options)) {
+void __init pm2fb_mode_setup(char* options){
int i;
for (i=0; user_mode[i].name[0] &&
@@ -1634,13 +1650,13 @@ __initfunc(void pm2fb_mode_setup(char* options)) {
sizeof(pm2fb_options.user_mode));
}
-__initfunc(void pm2fb_font_setup(char* options)) {
+void __init pm2fb_font_setup(char* options){
strncpy(pm2fb_options.font, options, sizeof(pm2fb_options.font));
pm2fb_options.font[sizeof(pm2fb_options.font)-1]='\0';
}
-__initfunc(void pm2fb_setup(char* options, int* ints)) {
+int __init pm2fb_setup(char* options){
char* next;
while (options) {
@@ -1658,6 +1674,7 @@ __initfunc(void pm2fb_setup(char* options, int* ints)) {
pm2fb_options.flags |= OPTF_VIRTUAL;
options=next;
}
+ return 0;
}
/***************************************************************************
@@ -1665,9 +1682,9 @@ __initfunc(void pm2fb_setup(char* options, int* ints)) {
***************************************************************************/
#ifdef MODULE
-int init_module(void) {
+int __init init_module(void) {
- pm2fb_init();
+ return pm2fb_init();
}
void cleanup_module(void) {
diff --git a/drivers/video/promcon.c b/drivers/video/promcon.c
index 984edab98..e58d32ed1 100644
--- a/drivers/video/promcon.c
+++ b/drivers/video/promcon.c
@@ -1,4 +1,4 @@
-/* $Id: promcon.c,v 1.15 1999/04/22 06:35:32 davem Exp $
+/* $Id: promcon.c,v 1.16 1999/08/10 15:56:22 davem Exp $
* Console driver utilizing PROM sun terminal emulation
*
* Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
@@ -104,7 +104,7 @@ promcon_end(struct vc_data *conp, char *b)
return b - p;
}
-__initfunc(const char *promcon_startup(void))
+const char __init *promcon_startup(void)
{
const char *display_desc = "PROM";
int node;
@@ -128,8 +128,8 @@ __initfunc(const char *promcon_startup(void))
return display_desc;
}
-__initfunc(static void
-promcon_init_unimap(struct vc_data *conp))
+static void __init
+promcon_init_unimap(struct vc_data *conp)
{
mm_segment_t old_fs = get_fs();
struct unipair *p, *p1;
@@ -591,7 +591,7 @@ struct consw prom_con = {
con_invert_region: NULL,
};
-__initfunc(void prom_con_init(void))
+void __init prom_con_init(void)
{
#ifdef CONFIG_DUMMY_CONSOLE
if (conswitchp == &dummy_con)
diff --git a/drivers/video/q40fb.c b/drivers/video/q40fb.c
index 8cacf5966..8f1e2eb88 100644
--- a/drivers/video/q40fb.c
+++ b/drivers/video/q40fb.c
@@ -6,6 +6,8 @@
#include <linux/malloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
+
+#include <asm/uaccess.h>
#include <asm/setup.h>
#include <asm/segment.h>
#include <asm/system.h>
@@ -15,8 +17,10 @@
#include <linux/module.h>
#include <asm/pgtable.h>
+#include <video/fbcon.h>
#include <video/fbcon-cfb16.h>
+#define FBIOSETSCROLLMODE 0x4611
#define Q40_PHYS_SCREEN_ADDR 0xFE800000
static unsigned long q40_screen_addr;
@@ -82,7 +86,7 @@ static int q40fb_get_fix(struct fb_fix_screeninfo *fix, int con,
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id,"Q40");
- fix->smem_start=(char*)q40_screen_addr;
+ fix->smem_start=q40_screen_addr;
fix->smem_len=1024*1024;
fix->type=FB_TYPE_PACKED_PIXELS;
fix->type_aux=0;
@@ -212,7 +216,7 @@ static int q40_setcolreg(unsigned regno, unsigned red, unsigned green,
blue>>=10;
if (regno < 16) {
- fbcon_cmap_cfb16[regno] = ((red & 31) <<5) |
+ fbcon_cmap_cfb16[regno] = ((red & 31) <<6) |
((green & 31) << 11) |
(blue & 63);
}
@@ -232,7 +236,7 @@ static int q40fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
cmap, kspc ? 0 : 2);
return 0;
#else
- printk("get cmap not supported\n");
+ printk(KERN_ERR "get cmap not supported\n");
return -EINVAL;
#endif
@@ -256,7 +260,7 @@ static int q40fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
return 0;
#else
- printk("set cmap not supported\n");
+ printk(KERN_ERR "set cmap not supported\n");
return -EINVAL;
#endif
@@ -265,7 +269,7 @@ static int q40fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
static int q40fb_pan_display(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
- printk("panning not supported\n");
+ printk(KERN_ERR "panning not supported\n");
return -EINVAL;
@@ -275,6 +279,27 @@ static int q40fb_ioctl(struct inode *inode, struct file *file,
unsigned int cmd, unsigned long arg, int con,
struct fb_info *info)
{
+#if 0
+ unsigned long i;
+ struct display *display;
+
+ if (con>=0)
+ display = &fb_display[con];
+ else
+ display = &disp[0];
+
+ if (cmd == FBIOSETSCROLLMODE)
+ {
+ i = verify_area(VERIFY_READ, (void *)arg, sizeof(unsigned long));
+ if (!i)
+ {
+ copy_from_user(&i, (void *)arg, sizeof(unsigned long));
+ display->scrollmode = i;
+ }
+ q40_updatescrollmode(display);
+ return i;
+ }
+#endif
return -EINVAL;
}
@@ -302,6 +327,8 @@ static void q40fb_set_disp(int con, struct fb_info *info)
display->inverse = 0;
display->line_length = fix.line_length;
+ display->scrollmode = SCROLL_YREDRAW;
+
#ifdef FBCON_HAS_CFB16
display->dispsw = &fbcon_cfb16;
disp->dispsw_data = fbcon_cmap_cfb16;
@@ -310,8 +337,11 @@ static void q40fb_set_disp(int con, struct fb_info *info)
#endif
}
-void q40fb_init(void)
+int q40fb_init(void)
{
+
+ if ( !MACH_IS_Q40)
+ return -ENXIO;
#if 0
q40_screen_addr = kernel_map(Q40_PHYS_SCREEN_ADDR, 1024*1024,
KERNELMAP_NO_COPYBACK, NULL);
@@ -335,12 +365,14 @@ void q40fb_init(void)
q40fb_get_var(&disp[0].var, 0, &fb_info);
q40fb_set_disp(-1, &fb_info);
- if (register_framebuffer(&fb_info) < 0)
- panic("unable to register Q40 frame buffer\n");
-
+ if (register_framebuffer(&fb_info) < 0) {
+ printk(KERN_ERR "unable to register Q40 frame buffer\n");
+ return -EINVAL;
+ }
- printk("fb%d: Q40 frame buffer alive and kicking !\n",
+ printk(KERN_INFO "fb%d: Q40 frame buffer alive and kicking !\n",
GET_FB_IDX(fb_info.node));
+ return 0;
}
diff --git a/drivers/video/retz3fb.c b/drivers/video/retz3fb.c
index 1ee42692f..dbc6eb022 100644
--- a/drivers/video/retz3fb.c
+++ b/drivers/video/retz3fb.c
@@ -109,6 +109,7 @@ struct retz3_fb_info {
unsigned long physregs;
int currcon;
int current_par_valid; /* set to 0 by memset */
+ int blitbusy;
struct display disp;
struct retz3fb_par current_par;
unsigned char color_table [256][3];
@@ -169,7 +170,10 @@ under "programs/Xserver/hw/xfree86/doc/modeDB.txt".
* Predefined Video Modes
*/
-static struct fb_videomode retz3fb_predefined[] __initdata = {
+static struct {
+ const char *name;
+ struct fb_var_screeninfo var;
+} retz3fb_predefined[] __initdata = {
/*
* NB: it is very important to adjust the pixel-clock to the color-depth.
*/
@@ -178,11 +182,7 @@ static struct fb_videomode retz3fb_predefined[] __initdata = {
"640x480", { /* 640x480, 8 bpp */
640, 480, 640, 480, 0, 0, 8, 0,
{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-#if 1
0, 0, -1, -1, FB_ACCEL_NONE, 39722, 48, 16, 33, 10, 96, 2,
-#else
- 0, 0, -1, -1, FB_ACCELF_TEXT, 38461, 28, 32, 12, 10, 96, 2,
-#endif
FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,FB_VMODE_NONINTERLACED
}
},
@@ -265,7 +265,7 @@ static int z3fb_mode __initdata = 0;
* Interface used by the world
*/
-void retz3fb_setup(char *options, int *ints);
+int retz3fb_setup(char *options);
static int retz3fb_open(struct fb_info *info, int user);
static int retz3fb_release(struct fb_info *info, int user);
@@ -290,7 +290,7 @@ static int retz3fb_ioctl(struct inode *inode, struct file *file,
* Interface to the low level console driver
*/
-void retz3fb_init(void);
+int retz3fb_init(void);
static int z3fb_switch(int con, struct fb_info *info);
static int z3fb_updatevar(int con, struct fb_info *info);
static void z3fb_blank(int blank, struct fb_info *info);
@@ -346,7 +346,7 @@ static void retz3fb_set_disp(int con, struct fb_info *info);
static int get_video_mode(const char *name);
-/* -------------------- Hardware specific routines -------------------------- */
+/* -------------------- Hardware specific routines ------------------------- */
static unsigned short find_fq(unsigned int freq)
{
@@ -490,7 +490,7 @@ static int retz3_set_video(struct fb_info *info,
#endif
if (data.v_total >= 1024)
- printk("MAYDAY: v_total >= 1024; bailing out!\n");
+ printk(KERN_ERR "MAYDAY: v_total >= 1024; bailing out!\n");
reg_w(regs, GREG_MISC_OUTPUT_W, 0xe3 | ((clocksel & 3) * 0x04));
reg_w(regs, GREG_FEATURE_CONTROL_W, 0x00);
@@ -770,7 +770,7 @@ static int retz3_set_video(struct fb_info *info,
reg_w(regs, 0x83c6, 0xe0);
break;
default:
- printk("Illegal color-depth: %i\n", bpp);
+ printk(KERN_INFO "Illegal color-depth: %i\n", bpp);
}
reg_w(regs, VDAC_ADDRESS, 0x00);
@@ -794,9 +794,9 @@ static int retz3_encode_fix(struct fb_info *info,
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id, retz3fb_name);
- fix->smem_start = (char *)(zinfo->physfbmem);
+ fix->smem_start = zinfo->physfbmem;
fix->smem_len = zinfo->fbsize;
- fix->mmio_start = (char *)(zinfo->physregs);
+ fix->mmio_start = zinfo->physregs;
fix->mmio_len = 0x00c00000;
fix->type = FB_TYPE_PACKED_PIXELS;
@@ -959,6 +959,21 @@ static int retz3_getcolreg(unsigned int regno, unsigned int *red,
}
+static inline void retz3_busy(struct display *p)
+{
+ struct retz3_fb_info *zinfo = retz3info(p->fb_info);
+ volatile unsigned char *acm = zinfo->base + ACM_OFFSET;
+ unsigned char blt_status;
+
+ if (zinfo->blitbusy) {
+ do{
+ blt_status = *((acm) + (ACM_START_STATUS + 2));
+ }while ((blt_status & 1) == 0);
+ zinfo->blitbusy = 0;
+ }
+}
+
+
static void retz3_bitblt (struct display *p,
unsigned short srcx, unsigned short srcy,
unsigned short destx, unsigned short desty,
@@ -973,7 +988,6 @@ static void retz3_bitblt (struct display *p,
unsigned short mod;
unsigned long tmp;
unsigned long pat, src, dst;
- unsigned char blt_status;
int i, xres_virtual = var->xres_virtual;
short bpp = (var->bits_per_pixel & 0xff);
@@ -983,16 +997,7 @@ static void retz3_bitblt (struct display *p,
tmp = mask | (mask << 16);
-#if 0
- /*
- * Check for blitter finished before we start messing with the
- * pattern.
- */
- do{
- blt_status = *(((volatile unsigned char *)acm) +
- (ACM_START_STATUS + 2));
- }while ((blt_status & 1) == 0);
-#endif
+ retz3_busy(p);
i = 0;
do{
@@ -1042,23 +1047,7 @@ static void retz3_bitblt (struct display *p,
*(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x00;
*(((volatile unsigned char *)acm) + ACM_START_STATUS) = 0x01;
-
- /*
- * No reason to wait for the blitter to finish, it is better
- * just to check if it has finished before we use it again.
- */
-#if 1
-#if 0
- while ((*(((volatile unsigned char *)acm) +
- (ACM_START_STATUS + 2)) & 1) == 0);
-#else
- do{
- blt_status = *(((volatile unsigned char *)acm) +
- (ACM_START_STATUS + 2));
- }
- while ((blt_status & 1) == 0);
-#endif
-#endif
+ zinfo->blitbusy = 1;
}
#if 0
@@ -1192,7 +1181,6 @@ static int retz3fb_get_var(struct fb_var_screeninfo *var, int con,
}
-#if 1
static void retz3fb_set_disp(int con, struct fb_info *info)
{
struct fb_fix_screeninfo fix;
@@ -1243,7 +1231,6 @@ static void retz3fb_set_disp(int con, struct fb_info *info)
break;
}
}
-#endif
/*
@@ -1407,12 +1394,12 @@ static struct fb_ops retz3fb_ops = {
};
-__initfunc(void retz3fb_setup(char *options, int *ints))
+int __init retz3fb_setup(char *options)
{
char *this_opt;
if (!options || !*options)
- return;
+ return 0;
for (this_opt = strtok(options, ","); this_opt;
this_opt = strtok(NULL, ",")){
@@ -1422,9 +1409,10 @@ __initfunc(void retz3fb_setup(char *options, int *ints))
} else if (!strncmp(this_opt, "font:", 5)) {
strncpy(fontname, this_opt+5, 39);
fontname[39] = '\0';
- }else
+ } else
z3fb_mode = get_video_mode(this_opt);
}
+ return 0;
}
@@ -1432,7 +1420,7 @@ __initfunc(void retz3fb_setup(char *options, int *ints))
* Initialization
*/
-__initfunc(void retz3fb_init(void))
+int __init retz3fb_init(void)
{
unsigned long board_addr, board_size;
unsigned int key;
@@ -1444,10 +1432,10 @@ __initfunc(void retz3fb_init(void))
short i;
if (!(key = zorro_find(ZORRO_PROD_MACROSYSTEMS_RETINA_Z3, 0, 0)))
- return;
+ return -ENXIO;
if (!(zinfo = kmalloc(sizeof(struct retz3_fb_info), GFP_KERNEL)))
- return;
+ return -ENOMEM;
memset(zinfo, 0, sizeof(struct retz3_fb_info));
cd = zorro_get_board (key);
@@ -1505,13 +1493,15 @@ __initfunc(void retz3fb_init(void))
do_install_cmap(0, fb_info);
if (register_framebuffer(fb_info) < 0)
- return;
+ return -EINVAL;
- printk("fb%d: %s frame buffer device, using %ldK of video memory\n",
+ printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of video memory\n",
GET_FB_IDX(fb_info->node), fb_info->modename,zinfo->fbsize>>10);
/* TODO: This driver cannot be unloaded yet */
MOD_INC_USE_COUNT;
+
+ return 0;
}
@@ -1576,11 +1566,11 @@ static void z3fb_blank(int blank, struct fb_info *info)
* Get a Video Mode
*/
-__initfunc(static int get_video_mode(const char *name))
+static int __init get_video_mode(const char *name)
{
short i;
- for (i = 0; i <= NUM_TOTAL_MODES; i++)
+ for (i = 0; i < NUM_TOTAL_MODES; i++)
if (!strcmp(name, retz3fb_predefined[i].name)){
retz3fb_default = retz3fb_predefined[i].var;
return i;
@@ -1592,8 +1582,7 @@ __initfunc(static int get_video_mode(const char *name))
#ifdef MODULE
int init_module(void)
{
- retz3fb_init();
- return 0;
+ return retz3fb_init();
}
void cleanup_module(void)
@@ -1613,8 +1602,8 @@ void cleanup_module(void)
*/
#ifdef FBCON_HAS_CFB8
-static void fbcon_retz3_8_bmove(struct display *p, int sy, int sx,
- int dy, int dx, int height, int width)
+static void retz3_8_bmove(struct display *p, int sy, int sx,
+ int dy, int dx, int height, int width)
{
int fontwidth = fontwidth(p);
@@ -1633,8 +1622,8 @@ static void fbcon_retz3_8_bmove(struct display *p, int sy, int sx,
0xffff);
}
-static void fbcon_retz3_8_clear(struct vc_data *conp, struct display *p,
- int sy, int sx, int height, int width)
+static void retz3_8_clear(struct vc_data *conp, struct display *p,
+ int sy, int sx, int height, int width)
{
unsigned short col;
int fontwidth = fontwidth(p);
@@ -1657,9 +1646,42 @@ static void fbcon_retz3_8_clear(struct vc_data *conp, struct display *p,
col);
}
+
+static void retz3_putc(struct vc_data *conp, struct display *p, int c,
+ int yy, int xx)
+{
+ retz3_busy(p);
+ fbcon_cfb8_putc(conp, p, c, yy, xx);
+}
+
+
+static void retz3_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count,
+ int yy, int xx)
+{
+ retz3_busy(p);
+ fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
+}
+
+
+static void retz3_revc(struct display *p, int xx, int yy)
+{
+ retz3_busy(p);
+ fbcon_cfb8_revc(p, xx, yy);
+}
+
+
+static void retz3_clear_margins(struct vc_data* conp, struct display* p,
+ int bottom_only)
+{
+ retz3_busy(p);
+ fbcon_cfb8_clear_margins(conp, p, bottom_only);
+}
+
+
static struct display_switch fbcon_retz3_8 = {
- fbcon_cfb8_setup, fbcon_retz3_8_bmove, fbcon_retz3_8_clear,
- fbcon_cfb8_putc, fbcon_cfb8_putcs, fbcon_cfb8_revc, NULL, NULL,
- fbcon_cfb8_clear_margins, FONTWIDTH(8)
+ fbcon_cfb8_setup, retz3_8_bmove, retz3_8_clear,
+ retz3_putc, retz3_putcs, retz3_revc, NULL, NULL,
+ retz3_clear_margins, FONTWIDTH(8)
};
#endif
diff --git a/drivers/video/sbusfb.c b/drivers/video/sbusfb.c
index 7e17bf1d6..aafa04542 100644
--- a/drivers/video/sbusfb.c
+++ b/drivers/video/sbusfb.c
@@ -53,8 +53,8 @@
* Interface used by the world
*/
-void sbusfb_init(void);
-void sbusfb_setup(char *options, int *ints);
+int sbusfb_init(void);
+int sbusfb_setup(char*);
static int currcon;
static int defx_margin = -1, defy_margin = -1;
@@ -743,7 +743,7 @@ static int sbusfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
* Setup: parse used options
*/
-__initfunc(void sbusfb_setup(char *options, int *ints))
+int __init sbusfb_setup(char *options)
{
char *p;
@@ -775,6 +775,7 @@ __initfunc(void sbusfb_setup(char *options, int *ints))
if (*p != ',') break;
p++;
}
+ return 0;
}
static int sbusfbcon_switch(int con, struct fb_info *info)
@@ -960,8 +961,8 @@ void sbusfb_palette(int enter)
extern void (*prom_palette)(int);
-__initfunc(static void sbusfb_init_fb(int node, int parent, int fbtype,
- struct linux_sbus_device *sbdp))
+static void __init sbusfb_init_fb(int node, int parent, int fbtype,
+ struct linux_sbus_device *sbdp)
{
struct fb_fix_screeninfo *fix;
struct fb_var_screeninfo *var;
@@ -1085,6 +1086,11 @@ sizechange:
case FBTYPE_MDICOLOR:
p = cgfourteenfb_init(fb); break;
#endif
+#ifdef CONFIG_FB_P9100
+ case FBTYPE_P9100COLOR:
+ /* Temporary crock. For now we are a cg3 */
+ p = p9100fb_init(fb); type->fb_type = FBTYPE_SUN3COLOR; break;
+#endif
}
if (!p) {
@@ -1128,7 +1134,7 @@ sizechange:
kfree(fb);
return;
}
- printk("fb%d: %s\n", GET_FB_IDX(fb->info.node), p);
+ printk(KERN_INFO "fb%d: %s\n", GET_FB_IDX(fb->info.node), p);
}
static inline int known_card(char *name)
@@ -1148,10 +1154,12 @@ static inline int known_card(char *name)
return FBTYPE_SUN2BW;
if (!strcmp(name, "tcx"))
return FBTYPE_TCXCOLOR;
+ if (!strcmp(name, "p9100"))
+ return FBTYPE_P9100COLOR;
return FBTYPE_NOTYPE;
}
-__initfunc(void sbusfb_init(void))
+int __init sbusfb_init(void)
{
int type;
struct linux_sbus_device *sbdp;
@@ -1159,7 +1167,7 @@ __initfunc(void sbusfb_init(void))
char prom_name[40];
extern int con_is_present(void);
- if (!con_is_present()) return;
+ if (!con_is_present()) return -ENXIO;
#ifdef CONFIG_FB_CREATOR
{
@@ -1187,7 +1195,7 @@ __initfunc(void sbusfb_init(void))
}
}
#endif
- if (!SBus_chain) return;
+ if (!SBus_chain) return 0;
for_all_sbusdev(sbdp, sbus) {
type = known_card(sbdp->prom_name);
if (type == FBTYPE_NOTYPE) continue;
@@ -1199,4 +1207,5 @@ __initfunc(void sbusfb_init(void))
sbdp->num_registers, sbdp);
sbusfb_init_fb(sbdp->prom_node, sbdp->my_bus->prom_node, type, sbdp);
}
+ return 0;
}
diff --git a/drivers/video/sgivwfb.c b/drivers/video/sgivwfb.c
index 71aafc340..ce02149cf 100644
--- a/drivers/video/sgivwfb.c
+++ b/drivers/video/sgivwfb.c
@@ -89,7 +89,7 @@ static struct sgivwfb_par par_current = {
/*
* Interface used by the world
*/
-void sgivwfb_setup(char *options, int *ints);
+int sgivwfb_setup(char*);
static int sgivwfb_open(struct fb_info *info, int user);
static int sgivwfb_release(struct fb_info *info, int user);
@@ -126,7 +126,7 @@ static struct fb_ops sgivwfb_ops = {
/*
* Interface to the low level console driver
*/
-void sgivwfb_init(void);
+int sgivwfb_init(void);
static int sgivwfbcon_switch(int con, struct fb_info *info);
static int sgivwfbcon_updatevar(int con, struct fb_info *info);
static void sgivwfbcon_blank(int blank, struct fb_info *info);
@@ -165,7 +165,7 @@ static unsigned long bytes_per_pixel(int bpp)
length = 4;
break;
default:
- printk("sgivwfb: unsupported bpp=%d\n", bpp);
+ printk(KERN_INFO "sgivwfb: unsupported bpp=%d\n", bpp);
length = 0;
break;
}
@@ -271,7 +271,7 @@ static void activate_par(struct sgivwfb_par *par)
if (wholeTilesX*maxPixelsPerTileX < xpmax)
wholeTilesX++;
- printk("sgivwfb: pixPerTile=%d wholeTilesX=%d\n",
+ printk(KERN_DEBUG "sgivwfb: pixPerTile=%d wholeTilesX=%d\n",
maxPixelsPerTileX, wholeTilesX);
/* dbe_InitGammaMap(); */
@@ -465,7 +465,7 @@ static void activate_par(struct sgivwfb_par *par)
}
if (i==100000)
- printk("sgivwfb: timeout waiting for frame DMA enable.\n");
+ printk(KERN_INFO "sgivwfb: timeout waiting for frame DMA enable.\n");
outputVal = 0;
htmp = currentTiming->hblank_end - 19;
@@ -501,7 +501,7 @@ static void sgivwfb_encode_fix(struct fb_fix_screeninfo *fix,
{
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id, sgivwfb_name);
- fix->smem_start = (char *) sgivwfb_mem_phys;
+ fix->smem_start = sgivwfb_mem_phys;
fix->smem_len = sgivwfb_mem_size;
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
@@ -517,7 +517,7 @@ static void sgivwfb_encode_fix(struct fb_fix_screeninfo *fix,
fix->xpanstep = 0;
fix->ypanstep = ypan;
fix->line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
- fix->mmio_start = (char *) DBE_REG_PHYS;
+ fix->mmio_start = DBE_REG_PHYS;
fix->mmio_len = DBE_REG_SIZE;
}
@@ -688,7 +688,7 @@ static int sgivwfb_set_var(struct fb_var_screeninfo *var, int con,
/* XXX FIXME - should try to pick best refresh rate */
/* for now, pick closest dot-clock within 3MHz*/
req_dot = (int)((1.0e3/1.0e6) / (1.0e-12 * (float)var->pixclock));
- printk("sgivwfb: requested pixclock=%d ps (%d KHz)\n", var->pixclock,
+ printk(KERN_INFO "sgivwfb: requested pixclock=%d ps (%d KHz)\n", var->pixclock,
req_dot);
test_mode=min_mode;
while (dbeVTimings[min_mode].width == dbeVTimings[test_mode].width) {
@@ -700,7 +700,7 @@ static int sgivwfb_set_var(struct fb_var_screeninfo *var, int con,
test_mode--;
min_mode = test_mode;
timing = &dbeVTimings[min_mode];
- printk("sgivwfb: granted dot-clock=%d KHz\n", timing->cfreq);
+ printk(KERN_INFO "sgivwfb: granted dot-clock=%d KHz\n", timing->cfreq);
/* Adjust virtual resolution, if necessary */
if (var->xres > var->xres_virtual || (!ywrap && !ypan))
@@ -775,9 +775,9 @@ static int sgivwfb_set_var(struct fb_var_screeninfo *var, int con,
oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
oldbpp != var->bits_per_pixel || !par_current.valid) {
struct fb_fix_screeninfo fix;
- printk("sgivwfb: new video mode xres=%d yres=%d bpp=%d\n",
+ printk(KERN_INFO "sgivwfb: new video mode xres=%d yres=%d bpp=%d\n",
var->xres, var->yres, var->bits_per_pixel);
- printk(" vxres=%d vyres=%d\n",
+ printk(KERN_INFO " vxres=%d vyres=%d\n",
var->xres_virtual, var->yres_virtual);
activate_par(&par_current);
sgivwfb_encode_fix(&fix, var);
@@ -915,37 +915,38 @@ static int sgivwfb_mmap(struct fb_info *info, struct file *file,
if (remap_page_range(vma->vm_start, offset, size, vma->vm_page_prot))
return -EAGAIN;
vma->vm_file = file;
- printk("sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n", offset, vma->vm_start);
+ printk(KERN_DEBUG "sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n", offset, vma->vm_start);
return 0;
}
-__initfunc(void sgivwfb_setup(char *options, int *ints))
+int __init sgivwfb_setup(char *options)
{
char *this_opt;
fb_info.fontname[0] = '\0';
if (!options || !*options)
- return;
+ return 0;
for (this_opt = strtok(options, ","); this_opt;
this_opt = strtok(NULL, ",")) {
if (!strncmp(this_opt, "font:", 5))
strcpy(fb_info.fontname, this_opt+5);
}
+ return 0;
}
/*
* Initialisation
*/
-__initfunc(void sgivwfb_init(void))
+int __init sgivwfb_init(void)
{
- printk("sgivwfb: framebuffer at 0x%lx, size %ldk\n",
+ printk(KERN_INFO "sgivwfb: framebuffer at 0x%lx, size %ldk\n",
sgivwfb_mem_phys, sgivwfb_mem_size/1024);
regs = (asregs*)ioremap_nocache(DBE_REG_PHYS, DBE_REG_SIZE);
if (!regs) {
- printk("sgivwfb: couldn't ioremap registers\n");
+ printk(KERN_ERR "sgivwfb: couldn't ioremap registers\n");
goto fail_ioremap_regs;
}
@@ -965,7 +966,7 @@ __initfunc(void sgivwfb_init(void))
fbmem = ioremap_nocache((unsigned long)sgivwfb_mem_phys, sgivwfb_mem_size);
if (!fbmem) {
- printk("sgivwfb: couldn't ioremap fbmem\n");
+ printk(KERN_ERR "sgivwfb: couldn't ioremap fbmem\n");
goto fail_ioremap_fbmem;
}
@@ -973,21 +974,21 @@ __initfunc(void sgivwfb_init(void))
sgivwfb_set_var(&par_current.var, -1, &fb_info);
if (register_framebuffer(&fb_info) < 0) {
- printk("sgivwfb: couldn't register framebuffer\n");
+ printk(KERN_ERR "sgivwfb: couldn't register framebuffer\n");
goto fail_register_framebuffer;
}
- printk("fb%d: Virtual frame buffer device, using %ldK of video memory\n",
+ printk(KERN_INFO "fb%d: Virtual frame buffer device, using %ldK of video memory\n",
GET_FB_IDX(fb_info.node), sgivwfb_mem_size>>10);
- return;
+ return 0;
fail_register_framebuffer:
iounmap((char*)fbmem);
fail_ioremap_fbmem:
iounmap(regs);
fail_ioremap_regs:
- return;
+ return -ENXIO;
}
static int sgivwfbcon_switch(int con, struct fb_info *info)
@@ -1022,8 +1023,7 @@ static void sgivwfbcon_blank(int blank, struct fb_info *info)
#ifdef MODULE
int init_module(void)
{
- sgivwfb_init();
- return 0;
+ return sgivwfb_init();
}
void cleanup_module(void)
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index 59a2da716..2eb7962f8 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -73,6 +73,8 @@ static struct fb_var_screeninfo default_var;
static int currcon = 0;
static int inverse = 0;
+int xxxfb_init(void);
+int xxxfb_setup(char*);
/* ------------------- chipset specific functions -------------------------- */
@@ -297,7 +299,7 @@ struct fbgen_hwswitch xxx_switch = {
* Initialization
*/
-__initfunc(void xxxfb_init(void))
+int __init xxxfb_init(void)
{
fb_info.gen.fbhw = &xxx_switch;
fb_info.gen.fbhw->detect();
@@ -316,12 +318,13 @@ __initfunc(void xxxfb_init(void))
fbgen_set_disp(-1, &fb_info.gen);
fbgen_install_cmap(0, &fb_info.gen);
if (register_framebuffer(&fb_info.gen.info) < 0)
- return;
- printk("fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.gen.info.node),
+ return -EINVAL;
+ printk(KERN_INFO "fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.gen.info.node),
fb_info.gen.info.modename);
/* uncomment this if your driver cannot be unloaded */
/* MOD_INC_USE_COUNT; */
+ return 0;
}
@@ -345,7 +348,7 @@ void xxxfb_cleanup(struct fb_info *info)
* Setup
*/
-__initfunc(void xxxfb_setup(char *options, int *ints))
+int __init xxxfb_setup(char *options)
{
/* Parse user speficied options (`video=xxxfb:') */
}
@@ -393,8 +396,7 @@ static struct fb_ops xxxfb_ops = {
#ifdef MODULE
int init_module(void)
{
- xxxfb_init();
- return 0;
+ return xxxfb_init();
}
void cleanup_module(void)
diff --git a/drivers/video/tcxfb.c b/drivers/video/tcxfb.c
index 8e9d2fc41..c56894a4a 100644
--- a/drivers/video/tcxfb.c
+++ b/drivers/video/tcxfb.c
@@ -1,4 +1,4 @@
-/* $Id: tcxfb.c,v 1.7 1999/01/26 10:55:03 jj Exp $
+/* $Id: tcxfb.c,v 1.8 1999/08/10 15:56:26 davem Exp $
* tcxfb.c: TCX 24/8bit frame buffer driver
*
* Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
@@ -206,7 +206,7 @@ static void tcx_margins (struct fb_info_sbusfb *fb, struct display *p, int x_mar
static char idstring[60] __initdata = { 0 };
-__initfunc(char *tcxfb_init(struct fb_info_sbusfb *fb))
+char __init *tcxfb_init(struct fb_info_sbusfb *fb)
{
struct fb_fix_screeninfo *fix = &fb->fix;
struct display *disp = &fb->disp;
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 59902a57a..a8c985035 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -125,7 +125,10 @@ const unsigned int bt463_cursor_source[4] = {
* fbcon should provide a general mechanism for doing something like this.
*/
-static struct fb_videomode tgafb_predefined[] __initdata = {
+static struct {
+ const char *name;
+ struct fb_var_screeninfo var;
+} tgafb_predefined[] __initdata = {
{ "640x480-60", {
640, 480, 640, 480, 0, 0, 0, 0,
{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
@@ -287,8 +290,8 @@ static void tgafb_set_disp(const void *fb_par, struct display *disp,
static int tgafb_open(struct fb_info *info, int user);
static int tgafb_release(struct fb_info *info, int user);
-void tgafb_setup(char *options, int *ints);
-void tgafb_init(void);
+int tgafb_setup(char*);
+int tgafb_init(void);
void tgafb_cleanup(struct fb_info *info);
static void tgafb_set_pll(int f);
@@ -325,9 +328,9 @@ static int tgafb_encode_fix(struct fb_fix_screeninfo *fix, const void *fb_par,
fix->visual = FB_VISUAL_TRUECOLOR;
fix->line_length = par->xres * (par->bits_per_pixel >> 3);
- fix->smem_start = (char *)__pa(fb_info.tga_fb_base + dense_mem(fb_info.tga_fb_base));
+ fix->smem_start = fb_info.tga_fb_base;
fix->smem_len = fix->line_length * par->yres;
- fix->mmio_start = (char *)__pa(fb_info.tga_regs_base);
+ fix->mmio_start = fb_info.tga_regs_base;
fix->mmio_len = 0x1000; /* Is this sufficient? */
fix->xpanstep = fix->ypanstep = fix->ywrapstep = 0;
fix->accel = FB_ACCEL_DEC_TGA;
@@ -934,7 +937,7 @@ static int tgafb_blank(int blank, struct fb_info_gen *info)
static void tgafb_set_disp(const void *fb_par, struct display *disp,
struct fb_info_gen *info)
{
- disp->screen_base = (char *)fb_info.tga_fb_base + dense_mem(fb_info.tga_fb_base);
+ disp->screen_base = ioremap(fb_info.tga_fb_base);
switch (fb_info.tga_type) {
#ifdef FBCON_HAS_CFB8
case 0: /* 8-plane */
@@ -996,7 +999,7 @@ static struct fb_ops tgafb_ops = {
* Setup
*/
-__initfunc(void tgafb_setup(char *options, int *ints)) {
+int __init tgafb_setup(char *options) {
char *this_opt;
int i;
@@ -1016,6 +1019,7 @@ __initfunc(void tgafb_setup(char *options, int *ints)) {
printk(KERN_ERR "tgafb: unknown parameter %s\n", this_opt);
}
}
+ return 0;
}
@@ -1023,16 +1027,16 @@ __initfunc(void tgafb_setup(char *options, int *ints)) {
* Initialisation
*/
-__initfunc(void tgafb_init(void))
+int __init tgafb_init(void)
{
struct pci_dev *pdev;
pdev = pci_find_device(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA, NULL);
if (!pdev)
- return;
- fb_info.tga_mem_base = pdev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK;
+ return -ENXIO;
+ fb_info.tga_mem_base = pdev->resource[0].start;
#ifdef DEBUG
- printk("tgafb_init: mem_base 0x%x\n", fb_info.tga_mem_base);
+ printk(KERN_DEBUG "tgafb_init: mem_base 0x%x\n", fb_info.tga_mem_base);
#endif /* DEBUG */
fb_info.tga_type = (readl((unsigned long)fb_info.tga_mem_base) >> 12) & 0x0f;
@@ -1078,9 +1082,10 @@ __initfunc(void tgafb_init(void))
fbgen_set_disp(-1, &fb_info.gen);
fbgen_install_cmap(0, &fb_info.gen);
if (register_framebuffer(&fb_info.gen.info) < 0)
- return;
- printk("fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.gen.info.node),
+ return -EINVAL;
+ printk(KERN_INFO "fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.gen.info.node),
fb_info.gen.info.modename);
+ return 0;
}
@@ -1101,8 +1106,7 @@ void tgafb_cleanup(struct fb_info *info)
#ifdef MODULE
int init_module(void)
{
- tgafb_init();
- return 0;
+ return tgafb_init();
}
void cleanup_module(void)
diff --git a/drivers/video/valkyriefb.c b/drivers/video/valkyriefb.c
index d7f2131de..2541d14a4 100644
--- a/drivers/video/valkyriefb.c
+++ b/drivers/video/valkyriefb.c
@@ -113,9 +113,9 @@ struct fb_info_valkyrie {
/*
* Exported functions
*/
-void valkyriefb_init(void);
+int valkyriefb_init(void);
void valkyrie_of_init(struct device_node *dp);
-void valkyriefb_setup(char *options, int *ints);
+int valkyriefb_setup(char*);
static int valkyrie_open(struct fb_info *info, int user);
static int valkyrie_release(struct fb_info *info, int user);
@@ -218,7 +218,7 @@ static int valkyrie_set_var(struct fb_var_screeninfo *var, int con,
}
if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) {
- /* printk("Not activating, in valkyrie_set_var.\n"); */
+ /* printk(KERN_ERR "Not activating, in valkyrie_set_var.\n"); */
valkyrie_par_to_var(&par, var);
return 0;
}
@@ -471,14 +471,14 @@ static void set_valkyrie_clock(unsigned char *params)
}
}
-__initfunc(static void init_valkyrie(struct fb_info_valkyrie *p))
+static void __init init_valkyrie(struct fb_info_valkyrie *p)
{
struct fb_par_valkyrie *par = &p->par;
struct fb_var_screeninfo var;
int j, k;
p->sense = read_valkyrie_sense(p);
- printk("Monitor sense value = 0x%x, ", p->sense);
+ printk(KERN_INFO "Monitor sense value = 0x%x, ", p->sense);
/* Try to pick a video mode out of NVRAM if we have one. */
if (default_vmode == VMODE_NVRAM) {
@@ -504,7 +504,7 @@ __initfunc(static void init_valkyrie(struct fb_info_valkyrie *p))
|| valkyrie_vram_reqd(default_vmode, default_cmode) > p->total_vram)
default_cmode = CMODE_8;
- printk("using video mode %d and color mode %d.\n", default_vmode, default_cmode);
+ printk(KERN_INFO "using video mode %d and color mode %d.\n", default_vmode, default_cmode);
mac_vmode_to_var(default_vmode, default_cmode, &var);
if (valkyrie_var_to_par(&var, par, &p->info)) {
@@ -534,7 +534,7 @@ __initfunc(static void init_valkyrie(struct fb_info_valkyrie *p))
return;
}
- printk("fb%d: valkyrie frame buffer device\n", GET_FB_IDX(p->info.node));
+ printk(KERN_INFO "fb%d: valkyrie frame buffer device\n", GET_FB_IDX(p->info.node));
}
static void valkyrie_set_par(const struct fb_par_valkyrie *par,
@@ -584,7 +584,7 @@ static void valkyrie_set_par(const struct fb_par_valkyrie *par,
#endif /* CONFIG_FB_COMPAT_XPMAC */
}
-__initfunc(void valkyriefb_init(void))
+int __init valkyriefb_init(void)
{
#ifndef CONFIG_FB_OF
struct device_node *dp;
@@ -593,15 +593,18 @@ __initfunc(void valkyriefb_init(void))
if (dp != 0)
valkyrie_of_init(dp);
#endif /* CONFIG_FB_OF */
+ return 0;
}
-__initfunc(void valkyrie_of_init(struct device_node *dp))
+void __init valkyrie_of_init(struct device_node *dp)
{
struct fb_info_valkyrie *p;
unsigned long addr, size;
- if(dp->n_addrs != 1)
- panic("expecting 1 address for valkyrie (got %d)", dp->n_addrs);
+ if(dp->n_addrs != 1) {
+ printk(KERN_ERR "expecting 1 address for valkyrie (got %d)", dp->n_addrs);
+ return;
+ }
p = kmalloc(sizeof(*p), GFP_ATOMIC);
if (p == 0)
@@ -764,7 +767,7 @@ static void valkyrie_init_fix(struct fb_fix_screeninfo *fix, struct fb_info_valk
{
memset(fix, 0, sizeof(*fix));
strcpy(fix->id, "valkyrie");
- fix->mmio_start = (char *)p->valkyrie_regs_phys;
+ fix->mmio_start = p->valkyrie_regs_phys;
fix->mmio_len = sizeof(struct valkyrie_regs);
fix->type = FB_TYPE_PACKED_PIXELS;
@@ -780,7 +783,7 @@ static void valkyrie_par_to_fix(struct fb_par_valkyrie *par,
struct fb_fix_screeninfo *fix,
struct fb_info_valkyrie *p)
{
- fix->smem_start = (void *)(p->frame_buffer_phys + 0x1000);
+ fix->smem_start = p->frame_buffer_phys + 0x1000;
#if 1
fix->smem_len = valkyrie_vram_reqd(par->vmode, par->cmode);
#else
@@ -848,12 +851,12 @@ static void __init valkyrie_init_info(struct fb_info *info, struct fb_info_valky
/*
* Parse user speficied options (`video=valkyriefb:')
*/
-__initfunc(void valkyriefb_setup(char *options, int *ints))
+int __init valkyriefb_setup(char *options)
{
char *this_opt;
if (!options || !*options)
- return;
+ return 0;
for (this_opt = strtok(options, ","); this_opt;
this_opt = strtok(NULL, ",")) {
@@ -893,4 +896,5 @@ __initfunc(void valkyriefb_setup(char *options, int *ints))
can_soft_blank = 1;
}
}
+ return 0;
}
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
index 78af83ef0..bb98bd8c7 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/vesafb.c
@@ -41,7 +41,7 @@
*/
/* card */
-char *video_base;
+unsigned long video_base; /* physical addr */
int video_size;
char *video_vbase; /* mapped */
@@ -96,8 +96,7 @@ static int mtrr = 0;
static int currcon = 0;
static int pmi_setpal = 0; /* pmi for palette changes ??? */
-static int ypan = 0;
-static int ywrap = 0;
+static int ypan = 0; /* 0..nothing, 1..ypan, 2..ywrap */
static unsigned short *pmi_base = 0;
static void (*pmi_start)(void);
static void (*pmi_pal)(void);
@@ -130,13 +129,13 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var, int con,
{
int offset;
- if (!ypan && !ywrap)
+ if (!ypan)
return -EINVAL;
if (var->xoffset)
return -EINVAL;
- if (ypan && var->yoffset+var->yres > var->yres_virtual)
+ if (var->yoffset > var->yres_virtual)
return -EINVAL;
- if (ywrap && var->yoffset > var->yres_virtual)
+ if ((ypan==1) && var->yoffset+var->yres > var->yres_virtual)
return -EINVAL;
offset = (var->yoffset * video_linelength + var->xoffset) / 4;
@@ -154,7 +153,7 @@ static int vesafb_pan_display(struct fb_var_screeninfo *var, int con,
static int vesafb_update_var(int con, struct fb_info *info)
{
- if (con == currcon && (ywrap || ypan)) {
+ if (con == currcon && ypan) {
struct fb_var_screeninfo *var = &fb_display[currcon].var;
return vesafb_pan_display(var,con,info);
}
@@ -167,13 +166,13 @@ static int vesafb_get_fix(struct fb_fix_screeninfo *fix, int con,
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id,"VESA VGA");
- fix->smem_start=(char *) video_base;
+ fix->smem_start=video_base;
fix->smem_len=video_size;
fix->type = video_type;
fix->visual = video_visual;
fix->xpanstep = 0;
- fix->ypanstep = (ywrap || ypan) ? 1 : 0;
- fix->ywrapstep = ywrap ? 1 : 0;
+ fix->ypanstep = ypan ? 1 : 0;
+ fix->ywrapstep = (ypan>1) ? 1 : 0;
fix->line_length=video_linelength;
return 0;
}
@@ -245,7 +244,7 @@ static void vesafb_set_disp(int con)
}
memcpy(&vesafb_sw, sw, sizeof(*sw));
display->dispsw = &vesafb_sw;
- if (!ypan && !ywrap) {
+ if (!ypan) {
display->scrollmode = SCROLL_YREDRAW;
vesafb_sw.bmove = fbcon_redraw_bmove;
}
@@ -265,7 +264,7 @@ static int vesafb_set_var(struct fb_var_screeninfo *var, int con,
var->bits_per_pixel != vesafb_defined.bits_per_pixel ||
var->nonstd) {
if (first) {
- printk("Vesafb does not support changing the video mode\n");
+ printk(KERN_ERR "Vesafb does not support changing the video mode\n");
first = 0;
}
return -EINVAL;
@@ -274,7 +273,7 @@ static int vesafb_set_var(struct fb_var_screeninfo *var, int con,
if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_TEST)
return 0;
- if (ypan || ywrap) {
+ if (ypan) {
if (vesafb_defined.yres_virtual != var->yres_virtual) {
vesafb_defined.yres_virtual = var->yres_virtual;
if (con != -1) {
@@ -471,14 +470,14 @@ static struct fb_ops vesafb_ops = {
vesafb_ioctl
};
-void vesafb_setup(char *options, int *ints)
+int vesafb_setup(char *options)
{
char *this_opt;
fb_info.fontname[0] = '\0';
if (!options || !*options)
- return;
+ return 0;
for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) {
if (!*this_opt) continue;
@@ -486,11 +485,11 @@ void vesafb_setup(char *options, int *ints)
if (! strcmp(this_opt, "inverse"))
inverse=1;
else if (! strcmp(this_opt, "redraw"))
- ywrap=0,ypan=0;
+ ypan=0;
else if (! strcmp(this_opt, "ypan"))
- ywrap=0,ypan=1;
+ ypan=1;
else if (! strcmp(this_opt, "ywrap"))
- ywrap=1,ypan=0;
+ ypan=2;
else if (! strcmp(this_opt, "vgapal"))
pmi_setpal=0;
else if (! strcmp(this_opt, "pmipal"))
@@ -500,6 +499,7 @@ void vesafb_setup(char *options, int *ints)
else if (!strncmp(this_opt, "font:", 5))
strcpy(fb_info.fontname, this_opt+5);
}
+ return 0;
}
static int vesafb_switch(int con, struct fb_info *info)
@@ -523,14 +523,14 @@ static void vesafb_blank(int blank, struct fb_info *info)
/* Not supported */
}
-__initfunc(void vesafb_init(void))
+int __init vesafb_init(void)
{
int i,j;
if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
- return;
+ return -ENXIO;
- video_base = (char*)screen_info.lfb_base;
+ video_base = screen_info.lfb_base;
video_bpp = screen_info.lfb_depth;
video_width = screen_info.lfb_width;
video_height = screen_info.lfb_height;
@@ -538,28 +538,37 @@ __initfunc(void vesafb_init(void))
video_size = screen_info.lfb_size * 65536;
video_visual = (video_bpp == 8) ?
FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
- video_vbase = ioremap((unsigned long)video_base, video_size);
- printk("vesafb: framebuffer at 0x%p, mapped to 0x%p, size %dk\n",
+ if (!__request_region(&iomem_resource, video_base, video_size,
+ "vesafb")) {
+ printk(KERN_ERR
+ "vesafb: abort, cannot reserve video memory at 0x%lu\n",
+ video_base);
+ return -1;
+ }
+
+ video_vbase = ioremap(video_base, video_size);
+
+ printk(KERN_INFO "vesafb: framebuffer at 0x%lu, mapped to 0x%p, size %dk\n",
video_base, video_vbase, video_size/1024);
- printk("vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
+ printk(KERN_INFO "vesafb: mode is %dx%dx%d, linelength=%d, pages=%d\n",
video_width, video_height, video_bpp, video_linelength, screen_info.pages);
if (screen_info.vesapm_seg) {
- printk("vesafb: protected mode interface info at %04x:%04x\n",
+ printk(KERN_INFO "vesafb: protected mode interface info at %04x:%04x\n",
screen_info.vesapm_seg,screen_info.vesapm_off);
}
if (screen_info.vesapm_seg < 0xc000)
- ywrap = ypan = pmi_setpal = 0; /* not available or some DOS TSR ... */
+ ypan = pmi_setpal = 0; /* not available or some DOS TSR ... */
- if (ypan || ywrap || pmi_setpal) {
- pmi_base = (unsigned short*)(__PAGE_OFFSET+((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
+ if (ypan || pmi_setpal) {
+ pmi_base = (unsigned short*)bus_to_virt(((unsigned long)screen_info.vesapm_seg << 4) + screen_info.vesapm_off);
pmi_start = (void*)((char*)pmi_base + pmi_base[1]);
pmi_pal = (void*)((char*)pmi_base + pmi_base[2]);
- printk("vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
+ printk(KERN_INFO "vesafb: pmi: set display start = %p, set palette = %p\n",pmi_start,pmi_pal);
if (pmi_base[3]) {
- printk("vesafb: pmi: ports = ");
+ printk(KERN_INFO "vesafb: pmi: ports = ");
for (i = pmi_base[3]/2; pmi_base[i] != 0xffff; i++)
printk("%x ",pmi_base[i]);
printk("\n");
@@ -570,8 +579,8 @@ __initfunc(void vesafb_init(void))
* Rules are: we have to set up a descriptor for the requested
* memory area and pass it in the ES register to the BIOS function.
*/
- printk("vesafb: can't handle memory requests, pmi disabled\n");
- ywrap = ypan = pmi_setpal = 0;
+ printk(KERN_INFO "vesafb: can't handle memory requests, pmi disabled\n");
+ ypan = pmi_setpal = 0;
}
}
}
@@ -582,13 +591,13 @@ __initfunc(void vesafb_init(void))
vesafb_defined.yres_virtual=video_size / video_linelength;
vesafb_defined.bits_per_pixel=video_bpp;
- if ((ypan || ywrap) && vesafb_defined.yres_virtual > video_height) {
- printk("vesafb: scrolling: %s using protected mode interface, yres_virtual=%d\n",
- ywrap ? "ywrap" : "ypan",vesafb_defined.yres_virtual);
+ if (ypan && vesafb_defined.yres_virtual > video_height) {
+ printk(KERN_INFO "vesafb: scrolling: %s using protected mode interface, yres_virtual=%d\n",
+ (ypan > 1) ? "ywrap" : "ypan",vesafb_defined.yres_virtual);
} else {
- printk("vesafb: scrolling: redraw\n");
+ printk(KERN_INFO "vesafb: scrolling: redraw\n");
vesafb_defined.yres_virtual = video_height;
- ypan = ywrap = 0;
+ ypan = 0;
}
video_height_virtual = vesafb_defined.yres_virtual;
@@ -610,7 +619,7 @@ __initfunc(void vesafb_init(void))
vesafb_defined.blue.length = screen_info.blue_size;
vesafb_defined.transp.offset = screen_info.rsvd_pos;
vesafb_defined.transp.length = screen_info.rsvd_size;
- printk("vesafb: directcolor: "
+ printk(KERN_INFO "vesafb: directcolor: "
"size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
screen_info.rsvd_size,
screen_info.red_size,
@@ -633,9 +642,13 @@ __initfunc(void vesafb_init(void))
}
video_cmap_len = 256;
}
- request_region(0x3c0, 32, "vga+");
+
+ /* request failure does not faze us, as vgacon probably has this
+ * region already (FIXME) */
+ __request_region(&ioport_resource, 0x3c0, 32, "vesafb");
+
if (mtrr)
- mtrr_add((unsigned long)video_base, video_size, MTRR_TYPE_WRCOMB, 1);
+ mtrr_add(video_base, video_size, MTRR_TYPE_WRCOMB, 1);
strcpy(fb_info.modename, "VESA VGA");
fb_info.changevar = NULL;
@@ -649,10 +662,11 @@ __initfunc(void vesafb_init(void))
vesafb_set_disp(-1);
if (register_framebuffer(&fb_info)<0)
- return;
+ return -EINVAL;
- printk("fb%d: %s frame buffer device\n",
+ printk(KERN_INFO "fb%d: %s frame buffer device\n",
GET_FB_IDX(fb_info.node), fb_info.modename);
+ return 0;
}
/*
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index ccc5e2a27..165b03077 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -78,7 +78,7 @@ static int vfb_enable = 0; /* disabled by default */
* Interface used by the world
*/
-void vfb_setup(char *options, int *ints);
+int vfb_setup(char*);
static int vfb_open(struct fb_info *info, int user);
static int vfb_release(struct fb_info *info, int user);
@@ -102,7 +102,7 @@ static int vfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
* Interface to the low level console driver
*/
-void vfb_init(void);
+int vfb_init(void);
static int vfbcon_switch(int con, struct fb_info *info);
static int vfbcon_updatevar(int con, struct fb_info *info);
static void vfbcon_blank(int blank, struct fb_info *info);
@@ -406,7 +406,7 @@ static int vfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
}
-__initfunc(void vfb_setup(char *options, int *ints))
+int __init vfb_setup(char *options)
{
char *this_opt;
@@ -415,13 +415,14 @@ __initfunc(void vfb_setup(char *options, int *ints))
vfb_enable = 1;
if (!options || !*options)
- return;
+ return 0;
for (this_opt = strtok(options, ","); this_opt;
this_opt = strtok(NULL, ",")) {
if (!strncmp(this_opt, "font:", 5))
strcpy(fb_info.fontname, this_opt+5);
}
+ return 0;
}
@@ -429,13 +430,13 @@ __initfunc(void vfb_setup(char *options, int *ints))
* Initialisation
*/
-__initfunc(void vfb_init(void))
+int __init vfb_init(void)
{
if (!vfb_enable)
- return;
+ return -ENXIO;
if (!(videomemory = (u_long)vmalloc(videomemorysize)))
- return;
+ return -ENOMEM;
strcpy(fb_info.modename, vfb_name);
fb_info.changevar = NULL;
@@ -451,11 +452,12 @@ __initfunc(void vfb_init(void))
if (register_framebuffer(&fb_info) < 0) {
vfree((void *)videomemory);
- return;
+ return -EINVAL;
}
- printk("fb%d: Virtual frame buffer device, using %ldK of video memory\n",
+ printk(KERN_INFO "fb%d: Virtual frame buffer device, using %ldK of video memory\n",
GET_FB_IDX(fb_info.node), videomemorysize>>10);
+ return 0;
}
@@ -505,7 +507,7 @@ static void vfb_encode_fix(struct fb_fix_screeninfo *fix,
{
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id, vfb_name);
- fix->smem_start = (char *)videomemory;
+ fix->smem_start = videomemory;
fix->smem_len = videomemorysize;
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
@@ -636,8 +638,7 @@ static void do_install_cmap(int con, struct fb_info *info)
#ifdef MODULE
int init_module(void)
{
- vfb_init();
- return 0;
+ return vfb_init();
}
void cleanup_module(void)
diff --git a/drivers/video/vga.h b/drivers/video/vga.h
new file mode 100644
index 000000000..7c05ba331
--- /dev/null
+++ b/drivers/video/vga.h
@@ -0,0 +1,444 @@
+/*
+ * linux/include/video/vga.h -- standard VGA chipset interaction
+ *
+ * Copyright 1999 Jeff Garzik <jgarzik@pobox.com>
+ *
+ * Copyright history from vga16fb.c:
+ * Copyright 1999 Ben Pfaff and Petr Vandrovec
+ * Based on VGA info at http://www.goodnet.com/~tinara/FreeVGA/home.htm
+ * Based on VESA framebuffer (c) 1998 Gerd Knorr
+ *
+ * This file is subject to the terms and conditions of the GNU General
+ * Public License. See the file COPYING in the main directory of this
+ * archive for more details.
+ *
+ */
+
+#ifndef __linux_video_vga_h__
+#define __linux_video_vga_h__
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#ifndef CONFIG_AMIGA
+#include <asm/vga.h>
+#endif
+#include <asm/byteorder.h>
+
+
+/* Some of the code below is taken from SVGAlib. The original,
+ unmodified copyright notice for that code is below. */
+/* VGAlib version 1.2 - (c) 1993 Tommy Frandsen */
+/* */
+/* This library is free software; you can redistribute it and/or */
+/* modify it without any restrictions. This library is distributed */
+/* in the hope that it will be useful, but without any warranty. */
+
+/* Multi-chipset support Copyright 1993 Harm Hanemaayer */
+/* partially copyrighted (C) 1993 by Hartmut Schirmer */
+
+/* VGA data register ports */
+#define VGA_CRT_DC 0x3D5 /* CRT Controller Data Register - color emulation */
+#define VGA_CRT_DM 0x3B5 /* CRT Controller Data Register - mono emulation */
+#define VGA_ATT_R 0x3C1 /* Attribute Controller Data Read Register */
+#define VGA_ATT_W 0x3C0 /* Attribute Controller Data Write Register */
+#define VGA_GFX_D 0x3CF /* Graphics Controller Data Register */
+#define VGA_SEQ_D 0x3C5 /* Sequencer Data Register */
+#define VGA_MIS_R 0x3CC /* Misc Output Read Register */
+#define VGA_MIS_W 0x3C2 /* Misc Output Write Register */
+#define VGA_FTC_R 0x3CA /* Feature Control Read Register */
+#define VGA_IS1_RC 0x3DA /* Input Status Register 1 - color emulation */
+#define VGA_IS1_RM 0x3BA /* Input Status Register 1 - mono emulation */
+#define VGA_PEL_D 0x3C9 /* PEL Data Register */
+#define VGA_PEL_MSK 0x3C6 /* PEL mask register */
+
+/* EGA-specific registers */
+#define EGA_GFX_E0 0x3CC /* Graphics enable processor 0 */
+#define EGA_GFX_E1 0x3CA /* Graphics enable processor 1 */
+
+/* VGA index register ports */
+#define VGA_CRT_IC 0x3D4 /* CRT Controller Index - color emulation */
+#define VGA_CRT_IM 0x3B4 /* CRT Controller Index - mono emulation */
+#define VGA_ATT_IW 0x3C0 /* Attribute Controller Index & Data Write Register */
+#define VGA_GFX_I 0x3CE /* Graphics Controller Index */
+#define VGA_SEQ_I 0x3C4 /* Sequencer Index */
+#define VGA_PEL_IW 0x3C8 /* PEL Write Index */
+#define VGA_PEL_IR 0x3C7 /* PEL Read Index */
+
+/* standard VGA indexes max counts */
+#define VGA_CRT_C 0x19 /* Number of CRT Controller Registers */
+#define VGA_ATT_C 0x15 /* Number of Attribute Controller Registers */
+#define VGA_GFX_C 0x09 /* Number of Graphics Controller Registers */
+#define VGA_SEQ_C 0x05 /* Number of Sequencer Registers */
+#define VGA_MIS_C 0x01 /* Number of Misc Output Register */
+
+/* VGA misc register bit masks */
+#define VGA_MIS_COLOR 0x01
+#define VGA_MIS_ENB_MEM_ACCESS 0x02
+#define VGA_MIS_DCLK_28322_720 0x04
+#define VGA_MIS_ENB_PLL_LOAD (0x04 | 0x08)
+#define VGA_MIS_SEL_HIGH_PAGE 0x20
+
+/* VGA CRT controller register indices */
+#define VGA_CRTC_H_TOTAL 0
+#define VGA_CRTC_H_DISP 1
+#define VGA_CRTC_H_BLANK_START 2
+#define VGA_CRTC_H_BLANK_END 3
+#define VGA_CRTC_H_SYNC_START 4
+#define VGA_CRTC_H_SYNC_END 5
+#define VGA_CRTC_V_TOTAL 6
+#define VGA_CRTC_OVERFLOW 7
+#define VGA_CRTC_PRESET_ROW 8
+#define VGA_CRTC_MAX_SCAN 9
+#define VGA_CRTC_CURSOR_START 0x0A
+#define VGA_CRTC_CURSOR_END 0x0B
+#define VGA_CRTC_START_HI 0x0C
+#define VGA_CRTC_START_LO 0x0D
+#define VGA_CRTC_CURSOR_HI 0x0E
+#define VGA_CRTC_CURSOR_LO 0x0F
+#define VGA_CRTC_V_SYNC_START 0x10
+#define VGA_CRTC_V_SYNC_END 0x11
+#define VGA_CRTC_V_DISP_END 0x12
+#define VGA_CRTC_OFFSET 0x13
+#define VGA_CRTC_UNDERLINE 0x14
+#define VGA_CRTC_V_BLANK_START 0x15
+#define VGA_CRTC_V_BLANK_END 0x16
+#define VGA_CRTC_MODE 0x17
+#define VGA_CRTC_LINE_COMPARE 0x18
+#define VGA_CRTC_REGS VGA_CRT_C
+
+/* VGA CRT controller bit masks */
+#define VGA_CR11_LOCK_CR0_CR7 0x80 /* lock writes to CR0 - CR7 */
+#define VGA_CR17_H_V_SIGNALS_ENABLED 0x80
+
+/* VGA attribute controller register indices */
+#define VGA_ATC_PALETTE0 0x00
+#define VGA_ATC_PALETTE1 0x01
+#define VGA_ATC_PALETTE2 0x02
+#define VGA_ATC_PALETTE3 0x03
+#define VGA_ATC_PALETTE4 0x04
+#define VGA_ATC_PALETTE5 0x05
+#define VGA_ATC_PALETTE6 0x06
+#define VGA_ATC_PALETTE7 0x07
+#define VGA_ATC_PALETTE8 0x08
+#define VGA_ATC_PALETTE9 0x09
+#define VGA_ATC_PALETTEA 0x0A
+#define VGA_ATC_PALETTEB 0x0B
+#define VGA_ATC_PALETTEC 0x0C
+#define VGA_ATC_PALETTED 0x0D
+#define VGA_ATC_PALETTEE 0x0E
+#define VGA_ATC_PALETTEF 0x0F
+#define VGA_ATC_MODE 0x10
+#define VGA_ATC_OVERSCAN 0x11
+#define VGA_ATC_PLANE_ENABLE 0x12
+#define VGA_ATC_PEL 0x13
+#define VGA_ATC_COLOR_PAGE 0x14
+
+#define VGA_AR_ENABLE_DISPLAY 0x20
+
+/* VGA sequencer register indices */
+#define VGA_SEQ_RESET 0x00
+#define VGA_SEQ_CLOCK_MODE 0x01
+#define VGA_SEQ_PLANE_WRITE 0x02
+#define VGA_SEQ_CHARACTER_MAP 0x03
+#define VGA_SEQ_MEMORY_MODE 0x04
+
+/* VGA sequencer register bit masks */
+#define VGA_SR01_CHAR_CLK_8DOTS 0x01 /* bit 0: character clocks 8 dots wide are generated */
+#define VGA_SR01_SCREEN_OFF 0x20 /* bit 5: Screen is off */
+#define VGA_SR02_ALL_PLANES 0x0F /* bits 3-0: enable access to all planes */
+#define VGA_SR04_EXT_MEM 0x02 /* bit 1: allows complete mem access to 256K */
+#define VGA_SR04_SEQ_MODE 0x04 /* bit 2: directs system to use a sequential addressing mode */
+#define VGA_SR04_CHN_4M 0x08 /* bit 3: selects modulo 4 addressing for CPU access to display memory */
+
+/* VGA graphics controller register indices */
+#define VGA_GFX_SR_VALUE 0x00
+#define VGA_GFX_SR_ENABLE 0x01
+#define VGA_GFX_COMPARE_VALUE 0x02
+#define VGA_GFX_DATA_ROTATE 0x03
+#define VGA_GFX_PLANE_READ 0x04
+#define VGA_GFX_MODE 0x05
+#define VGA_GFX_MISC 0x06
+#define VGA_GFX_COMPARE_MASK 0x07
+#define VGA_GFX_BIT_MASK 0x08
+
+/* VGA graphics controller bit masks */
+#define VGA_GR06_GRAPHICS_MODE 0x01
+
+/* macro for composing an 8-bit VGA register index and value
+ * into a single 16-bit quantity */
+#define VGA_OUT16VAL(v, r) (((v) << 8) | (r))
+
+/* decide whether we should enable the faster 16-bit VGA register writes */
+#ifdef __LITTLE_ENDIAN
+#define VGA_OUTW_WRITE
+#endif
+
+
+/*
+ * generic VGA port read/write
+ */
+
+extern inline unsigned char vga_io_r (unsigned short port)
+{
+ return inb (port);
+}
+
+extern inline void vga_io_w (unsigned short port, unsigned char val)
+{
+ outb (val, port);
+}
+
+extern inline void vga_io_w_fast (unsigned short port, unsigned char reg,
+ unsigned char val)
+{
+ outw (VGA_OUT16VAL (val, reg), port);
+}
+
+extern inline unsigned char vga_mm_r (caddr_t regbase, unsigned short port)
+{
+ return readb (regbase + port);
+}
+
+extern inline void vga_mm_w (caddr_t regbase, unsigned short port, unsigned char val)
+{
+ writeb (val, regbase + port);
+}
+
+extern inline void vga_mm_w_fast (caddr_t regbase, unsigned short port,
+ unsigned char reg, unsigned char val)
+{
+ writew (VGA_OUT16VAL (val, reg), regbase + port);
+}
+
+extern inline unsigned char vga_r (caddr_t regbase, unsigned short port)
+{
+ if (regbase)
+ return vga_mm_r (regbase, port);
+ else
+ return vga_io_r (port);
+}
+
+extern inline void vga_w (caddr_t regbase, unsigned short port, unsigned char val)
+{
+ if (regbase)
+ vga_mm_w (regbase, port, val);
+ else
+ vga_io_w (port, val);
+}
+
+
+extern inline void vga_w_fast (caddr_t regbase, unsigned short port,
+ unsigned char reg, unsigned char val)
+{
+ if (regbase)
+ vga_mm_w_fast (regbase, port, reg, val);
+ else
+ vga_io_w_fast (port, reg, val);
+}
+
+
+/*
+ * VGA CRTC register read/write
+ */
+
+extern inline unsigned char vga_rcrt (caddr_t regbase, unsigned char reg)
+{
+ vga_w (regbase, VGA_CRT_IC, reg);
+ return vga_r (regbase, VGA_CRT_DC);
+}
+
+extern inline void vga_wcrt (caddr_t regbase, unsigned char reg, unsigned char val)
+{
+#ifdef VGA_OUTW_WRITE
+ vga_w_fast (regbase, VGA_CRT_IC, reg, val);
+#else
+ vga_w (regbase, VGA_CRT_IC, reg);
+ vga_w (regbase, VGA_CRT_DC, val);
+#endif /* VGA_OUTW_WRITE */
+}
+
+extern inline unsigned char vga_io_rcrt (unsigned char reg)
+{
+ vga_io_w (VGA_CRT_IC, reg);
+ return vga_io_r (VGA_CRT_DC);
+}
+
+extern inline void vga_io_wcrt (unsigned char reg, unsigned char val)
+{
+#ifdef VGA_OUTW_WRITE
+ vga_io_w_fast (VGA_CRT_IC, reg, val);
+#else
+ vga_io_w (VGA_CRT_IC, reg);
+ vga_io_w (VGA_CRT_DC, val);
+#endif /* VGA_OUTW_WRITE */
+}
+
+extern inline unsigned char vga_mm_rcrt (caddr_t regbase, unsigned char reg)
+{
+ vga_mm_w (regbase, VGA_CRT_IC, reg);
+ return vga_mm_r (regbase, VGA_CRT_DC);
+}
+
+extern inline void vga_mm_wcrt (caddr_t regbase, unsigned char reg, unsigned char val)
+{
+#ifdef VGA_OUTW_WRITE
+ vga_mm_w_fast (regbase, VGA_CRT_IC, reg, val);
+#else
+ vga_mm_w (regbase, VGA_CRT_IC, reg);
+ vga_mm_w (regbase, VGA_CRT_DC, val);
+#endif /* VGA_OUTW_WRITE */
+}
+
+
+/*
+ * VGA sequencer register read/write
+ */
+
+extern inline unsigned char vga_rseq (caddr_t regbase, unsigned char reg)
+{
+ vga_w (regbase, VGA_SEQ_I, reg);
+ return vga_r (regbase, VGA_SEQ_D);
+}
+
+extern inline void vga_wseq (caddr_t regbase, unsigned char reg, unsigned char val)
+{
+#ifdef VGA_OUTW_WRITE
+ vga_w_fast (regbase, VGA_SEQ_I, reg, val);
+#else
+ vga_w (regbase, VGA_SEQ_I, reg);
+ vga_w (regbase, VGA_SEQ_D, val);
+#endif /* VGA_OUTW_WRITE */
+}
+
+extern inline unsigned char vga_io_rseq (unsigned char reg)
+{
+ vga_io_w (VGA_SEQ_I, reg);
+ return vga_io_r (VGA_SEQ_D);
+}
+
+extern inline void vga_io_wseq (unsigned char reg, unsigned char val)
+{
+#ifdef VGA_OUTW_WRITE
+ vga_io_w_fast (VGA_SEQ_I, reg, val);
+#else
+ vga_io_w (VGA_SEQ_I, reg);
+ vga_io_w (VGA_SEQ_D, val);
+#endif /* VGA_OUTW_WRITE */
+}
+
+extern inline unsigned char vga_mm_rseq (caddr_t regbase, unsigned char reg)
+{
+ vga_mm_w (regbase, VGA_SEQ_I, reg);
+ return vga_mm_r (regbase, VGA_SEQ_D);
+}
+
+extern inline void vga_mm_wseq (caddr_t regbase, unsigned char reg, unsigned char val)
+{
+#ifdef VGA_OUTW_WRITE
+ vga_mm_w_fast (regbase, VGA_SEQ_I, reg, val);
+#else
+ vga_mm_w (regbase, VGA_SEQ_I, reg);
+ vga_mm_w (regbase, VGA_SEQ_D, val);
+#endif /* VGA_OUTW_WRITE */
+}
+
+
+
+/*
+ * VGA graphics controller register read/write
+ */
+
+extern inline unsigned char vga_rgfx (caddr_t regbase, unsigned char reg)
+{
+ vga_w (regbase, VGA_GFX_I, reg);
+ return vga_r (regbase, VGA_GFX_D);
+}
+
+extern inline void vga_wgfx (caddr_t regbase, unsigned char reg, unsigned char val)
+{
+#ifdef VGA_OUTW_WRITE
+ vga_w_fast (regbase, VGA_GFX_I, reg, val);
+#else
+ vga_w (regbase, VGA_GFX_I, reg);
+ vga_w (regbase, VGA_GFX_D, val);
+#endif /* VGA_OUTW_WRITE */
+}
+
+extern inline unsigned char vga_io_rgfx (unsigned char reg)
+{
+ vga_io_w (VGA_GFX_I, reg);
+ return vga_io_r (VGA_GFX_D);
+}
+
+extern inline void vga_io_wgfx (unsigned char reg, unsigned char val)
+{
+#ifdef VGA_OUTW_WRITE
+ vga_io_w_fast (VGA_GFX_I, reg, val);
+#else
+ vga_io_w (VGA_GFX_I, reg);
+ vga_io_w (VGA_GFX_D, val);
+#endif /* VGA_OUTW_WRITE */
+}
+
+extern inline unsigned char vga_mm_rgfx (caddr_t regbase, unsigned char reg)
+{
+ vga_mm_w (regbase, VGA_GFX_I, reg);
+ return vga_mm_r (regbase, VGA_GFX_D);
+}
+
+extern inline void vga_mm_wgfx (caddr_t regbase, unsigned char reg, unsigned char val)
+{
+#ifdef VGA_OUTW_WRITE
+ vga_mm_w_fast (regbase, VGA_GFX_I, reg, val);
+#else
+ vga_mm_w (regbase, VGA_GFX_I, reg);
+ vga_mm_w (regbase, VGA_GFX_D, val);
+#endif /* VGA_OUTW_WRITE */
+}
+
+
+/*
+ * VGA attribute controller register read/write
+ */
+
+extern inline unsigned char vga_rattr (caddr_t regbase, unsigned char reg)
+{
+ vga_w (regbase, VGA_ATT_IW, reg);
+ return vga_r (regbase, VGA_ATT_R);
+}
+
+extern inline void vga_wattr (caddr_t regbase, unsigned char reg, unsigned char val)
+{
+ vga_w (regbase, VGA_ATT_IW, reg);
+ vga_w (regbase, VGA_ATT_W, val);
+}
+
+extern inline unsigned char vga_io_rattr (unsigned char reg)
+{
+ vga_io_w (VGA_ATT_IW, reg);
+ return vga_io_r (VGA_ATT_R);
+}
+
+extern inline void vga_io_wattr (unsigned char reg, unsigned char val)
+{
+ vga_io_w (VGA_ATT_IW, reg);
+ vga_io_w (VGA_ATT_W, val);
+}
+
+extern inline unsigned char vga_mm_rattr (caddr_t regbase, unsigned char reg)
+{
+ vga_mm_w (regbase, VGA_ATT_IW, reg);
+ return vga_mm_r (regbase, VGA_ATT_R);
+}
+
+extern inline void vga_mm_wattr (caddr_t regbase, unsigned char reg, unsigned char val)
+{
+ vga_mm_w (regbase, VGA_ATT_IW, reg);
+ vga_mm_w (regbase, VGA_ATT_W, val);
+}
+
+
+
+
+#endif /* __linux_video_vga_h__ */
diff --git a/drivers/video/vga16fb.c b/drivers/video/vga16fb.c
index 7f7b1af4d..9b014c45e 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/vga16fb.c
@@ -27,10 +27,14 @@
#include <video/fbcon.h>
#include <video/fbcon-vga-planes.h>
+#include "vga.h"
#define dac_reg (0x3c8)
#define dac_val (0x3c9)
+#define VGA_FB_PHYS 0xA0000
+#define VGA_FB_PHYS_LEN 65535
+
/* --------------------------------------------------------------------- */
/*
@@ -63,104 +67,12 @@ static struct vga16fb_info {
int vesa_blanked;
} vga16fb;
-/* Some of the code below is taken from SVGAlib. The original,
- unmodified copyright notice for that code is below. */
-/* VGAlib version 1.2 - (c) 1993 Tommy Frandsen */
-/* */
-/* This library is free software; you can redistribute it and/or */
-/* modify it without any restrictions. This library is distributed */
-/* in the hope that it will be useful, but without any warranty. */
-
-/* Multi-chipset support Copyright 1993 Harm Hanemaayer */
-/* partially copyrighted (C) 1993 by Hartmut Schirmer */
-
-/* VGA data register ports */
-#define CRT_DC 0x3D5 /* CRT Controller Data Register - color emulation */
-#define CRT_DM 0x3B5 /* CRT Controller Data Register - mono emulation */
-#define ATT_R 0x3C1 /* Attribute Controller Data Read Register */
-#define GRA_D 0x3CF /* Graphics Controller Data Register */
-#define SEQ_D 0x3C5 /* Sequencer Data Register */
-#define MIS_R 0x3CC /* Misc Output Read Register */
-#define MIS_W 0x3C2 /* Misc Output Write Register */
-#define IS1_RC 0x3DA /* Input Status Register 1 - color emulation */
-#define IS1_RM 0x3BA /* Input Status Register 1 - mono emulation */
-#define PEL_D 0x3C9 /* PEL Data Register */
-#define PEL_MSK 0x3C6 /* PEL mask register */
-
-/* EGA-specific registers */
-#define GRA_E0 0x3CC /* Graphics enable processor 0 */
-#define GRA_E1 0x3CA /* Graphics enable processor 1 */
-
-
-/* VGA index register ports */
-#define CRT_IC 0x3D4 /* CRT Controller Index - color emulation */
-#define CRT_IM 0x3B4 /* CRT Controller Index - mono emulation */
-#define ATT_IW 0x3C0 /* Attribute Controller Index & Data Write Register */
-#define GRA_I 0x3CE /* Graphics Controller Index */
-#define SEQ_I 0x3C4 /* Sequencer Index */
-#define PEL_IW 0x3C8 /* PEL Write Index */
-#define PEL_IR 0x3C7 /* PEL Read Index */
-
-/* standard VGA indexes max counts */
-#define CRT_C 24 /* 24 CRT Controller Registers */
-#define ATT_C 21 /* 21 Attribute Controller Registers */
-#define GRA_C 9 /* 9 Graphics Controller Registers */
-#define SEQ_C 5 /* 5 Sequencer Registers */
-#define MIS_C 1 /* 1 Misc Output Register */
-
-#define CRTC_H_TOTAL 0
-#define CRTC_H_DISP 1
-#define CRTC_H_BLANK_START 2
-#define CRTC_H_BLANK_END 3
-#define CRTC_H_SYNC_START 4
-#define CRTC_H_SYNC_END 5
-#define CRTC_V_TOTAL 6
-#define CRTC_OVERFLOW 7
-#define CRTC_PRESET_ROW 8
-#define CRTC_MAX_SCAN 9
-#define CRTC_CURSOR_START 0x0A
-#define CRTC_CURSOR_END 0x0B
-#define CRTC_START_HI 0x0C
-#define CRTC_START_LO 0x0D
-#define CRTC_CURSOR_HI 0x0E
-#define CRTC_CURSOR_LO 0x0F
-#define CRTC_V_SYNC_START 0x10
-#define CRTC_V_SYNC_END 0x11
-#define CRTC_V_DISP_END 0x12
-#define CRTC_OFFSET 0x13
-#define CRTC_UNDERLINE 0x14
-#define CRTC_V_BLANK_START 0x15
-#define CRTC_V_BLANK_END 0x16
-#define CRTC_MODE 0x17
-#define CRTC_LINE_COMPARE 0x18
-#define CRTC_REGS 0x19
-
-#define ATC_MODE 0x10
-#define ATC_OVERSCAN 0x11
-#define ATC_PLANE_ENABLE 0x12
-#define ATC_PEL 0x13
-#define ATC_COLOR_PAGE 0x14
-
-#define SEQ_CLOCK_MODE 0x01
-#define SEQ_PLANE_WRITE 0x02
-#define SEQ_CHARACTER_MAP 0x03
-#define SEQ_MEMORY_MODE 0x04
-
-#define GDC_SR_VALUE 0x00
-#define GDC_SR_ENABLE 0x01
-#define GDC_COMPARE_VALUE 0x02
-#define GDC_DATA_ROTATE 0x03
-#define GDC_PLANE_READ 0x04
-#define GDC_MODE 0x05
-#define GDC_MISC 0x06
-#define GDC_COMPARE_MASK 0x07
-#define GDC_BIT_MASK 0x08
struct vga16fb_par {
- u8 crtc[CRTC_REGS];
- u8 atc[ATT_C];
- u8 gdc[GRA_C];
- u8 seq[SEQ_C];
+ u8 crtc[VGA_CRT_C];
+ u8 atc[VGA_ATT_C];
+ u8 gdc[VGA_GFX_C];
+ u8 seq[VGA_SEQ_C];
u8 misc;
u8 vss;
struct fb_var_screeninfo var;
@@ -192,6 +104,8 @@ static struct { u_short blue, green, red, pad; } palette[256];
static int currcon = 0;
+static int release_io_ports = 0;
+
/* --------------------------------------------------------------------- */
/*
@@ -216,17 +130,17 @@ static int vga16fb_release(struct fb_info *info, int user)
static void vga16fb_pan_var(struct fb_info *info, struct fb_var_screeninfo *var)
{
u32 pos = (var->xres_virtual * var->yoffset + var->xoffset) >> 3;
- outb(CRTC_START_HI, CRT_IC);
- outb(pos >> 8, CRT_DC);
- outb(CRTC_START_LO, CRT_IC);
- outb(pos & 0xFF, CRT_DC);
+ outb(VGA_CRTC_START_HI, VGA_CRT_IC);
+ outb(pos >> 8, VGA_CRT_DC);
+ outb(VGA_CRTC_START_LO, VGA_CRT_IC);
+ outb(pos & 0xFF, VGA_CRT_DC);
#if 0
/* if someone supports xoffset in bit resolution */
- inb(IS1_RC); /* reset flip-flop */
- outb(ATC_PEL, ATT_IW);
- outb(xoffset & 7, ATT_IW);
- inb(IS1_RC);
- outb(0x20, ATT_IW);
+ inb(VGA_IS1_RC); /* reset flip-flop */
+ outb(VGA_ATC_PEL, VGA_ATT_IW);
+ outb(xoffset & 7, VGA_ATT_IW);
+ inb(VGA_IS1_RC);
+ outb(0x20, VGA_ATT_IW);
#endif
}
@@ -249,8 +163,8 @@ static int vga16fb_get_fix(struct fb_fix_screeninfo *fix, int con,
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id,"VGA16 VGA");
- fix->smem_start = (char *) 0xa0000;
- fix->smem_len = 65536;
+ fix->smem_start = VGA_FB_PHYS;
+ fix->smem_len = VGA_FB_PHYS_LEN;
fix->type = FB_TYPE_VGA_PLANES;
fix->visual = FB_VISUAL_PSEUDOCOLOR;
fix->xpanstep = 8;
@@ -338,7 +252,7 @@ static void vga16fb_clock_chip(struct vga16fb_par *par,
}
}
par->misc |= best->misc;
- par->seq[SEQ_CLOCK_MODE] |= best->seq_clock_mode;
+ par->seq[VGA_SEQ_CLOCK_MODE] |= best->seq_clock_mode;
par->var.pixclock = best->pixclock;
}
@@ -388,17 +302,17 @@ static int vga16fb_decode_var(const struct fb_var_screeninfo *var,
FAIL("hslen too big");
if (right + hslen + left > 64)
FAIL("hblank too big");
- par->crtc[CRTC_H_TOTAL] = xtotal - 5;
- par->crtc[CRTC_H_BLANK_START] = xres - 1;
- par->crtc[CRTC_H_DISP] = xres - 1;
+ par->crtc[VGA_CRTC_H_TOTAL] = xtotal - 5;
+ par->crtc[VGA_CRTC_H_BLANK_START] = xres - 1;
+ par->crtc[VGA_CRTC_H_DISP] = xres - 1;
pos = xres + right;
- par->crtc[CRTC_H_SYNC_START] = pos;
+ par->crtc[VGA_CRTC_H_SYNC_START] = pos;
pos += hslen;
- par->crtc[CRTC_H_SYNC_END] = pos & 0x1F;
+ par->crtc[VGA_CRTC_H_SYNC_END] = pos & 0x1F;
pos += left - 2; /* blank_end + 2 <= total + 5 */
- par->crtc[CRTC_H_BLANK_END] = (pos & 0x1F) | 0x80;
+ par->crtc[VGA_CRTC_H_BLANK_END] = (pos & 0x1F) | 0x80;
if (pos & 0x20)
- par->crtc[CRTC_H_SYNC_END] |= 0x80;
+ par->crtc[VGA_CRTC_H_SYNC_END] |= 0x80;
yres = var->yres;
lower = var->lower_margin;
@@ -443,59 +357,59 @@ static int vga16fb_decode_var(const struct fb_var_screeninfo *var,
FAIL("ytotal too big");
if (vslen > 16)
FAIL("vslen too big");
- par->crtc[CRTC_V_TOTAL] = ytotal - 2;
+ par->crtc[VGA_CRTC_V_TOTAL] = ytotal - 2;
r7 = 0x10; /* disable linecompare */
if (ytotal & 0x100) r7 |= 0x01;
if (ytotal & 0x200) r7 |= 0x20;
- par->crtc[CRTC_PRESET_ROW] = 0;
- par->crtc[CRTC_MAX_SCAN] = 0x40; /* 1 scanline, no linecmp */
+ par->crtc[VGA_CRTC_PRESET_ROW] = 0;
+ par->crtc[VGA_CRTC_MAX_SCAN] = 0x40; /* 1 scanline, no linecmp */
par->var.vmode = var->vmode;
if (var->vmode & FB_VMODE_DOUBLE)
- par->crtc[CRTC_MAX_SCAN] |= 0x80;
- par->crtc[CRTC_CURSOR_START] = 0x20;
- par->crtc[CRTC_CURSOR_END] = 0x00;
+ par->crtc[VGA_CRTC_MAX_SCAN] |= 0x80;
+ par->crtc[VGA_CRTC_CURSOR_START] = 0x20;
+ par->crtc[VGA_CRTC_CURSOR_END] = 0x00;
pos = yoffset * vxres + (xoffset >> 3);
- par->crtc[CRTC_START_HI] = pos >> 8;
- par->crtc[CRTC_START_LO] = pos & 0xFF;
- par->crtc[CRTC_CURSOR_HI] = 0x00;
- par->crtc[CRTC_CURSOR_LO] = 0x00;
+ par->crtc[VGA_CRTC_START_HI] = pos >> 8;
+ par->crtc[VGA_CRTC_START_LO] = pos & 0xFF;
+ par->crtc[VGA_CRTC_CURSOR_HI] = 0x00;
+ par->crtc[VGA_CRTC_CURSOR_LO] = 0x00;
pos = yres - 1;
- par->crtc[CRTC_V_DISP_END] = pos & 0xFF;
- par->crtc[CRTC_V_BLANK_START] = pos & 0xFF;
+ par->crtc[VGA_CRTC_V_DISP_END] = pos & 0xFF;
+ par->crtc[VGA_CRTC_V_BLANK_START] = pos & 0xFF;
if (pos & 0x100)
r7 |= 0x0A; /* 0x02 -> DISP_END, 0x08 -> BLANK_START */
if (pos & 0x200) {
r7 |= 0x40; /* 0x40 -> DISP_END */
- par->crtc[CRTC_MAX_SCAN] |= 0x20; /* BLANK_START */
+ par->crtc[VGA_CRTC_MAX_SCAN] |= 0x20; /* BLANK_START */
}
pos += lower;
- par->crtc[CRTC_V_SYNC_START] = pos & 0xFF;
+ par->crtc[VGA_CRTC_V_SYNC_START] = pos & 0xFF;
if (pos & 0x100)
r7 |= 0x04;
if (pos & 0x200)
r7 |= 0x80;
pos += vslen;
- par->crtc[CRTC_V_SYNC_END] = (pos & 0x0F) | 0x10; /* disabled IRQ */
+ par->crtc[VGA_CRTC_V_SYNC_END] = (pos & 0x0F) | 0x10; /* disabled IRQ */
pos += upper - 1; /* blank_end + 1 <= ytotal + 2 */
- par->crtc[CRTC_V_BLANK_END] = pos & 0xFF; /* 0x7F for original VGA,
+ par->crtc[VGA_CRTC_V_BLANK_END] = pos & 0xFF; /* 0x7F for original VGA,
but some SVGA chips requires all 8 bits to set */
if (vxres >= 512)
FAIL("vxres too long");
- par->crtc[CRTC_OFFSET] = vxres >> 1;
- par->crtc[CRTC_UNDERLINE] = 0x1F;
- par->crtc[CRTC_MODE] = rMode | 0xE3;
- par->crtc[CRTC_LINE_COMPARE] = 0xFF;
- par->crtc[CRTC_OVERFLOW] = r7;
+ par->crtc[VGA_CRTC_OFFSET] = vxres >> 1;
+ par->crtc[VGA_CRTC_UNDERLINE] = 0x1F;
+ par->crtc[VGA_CRTC_MODE] = rMode | 0xE3;
+ par->crtc[VGA_CRTC_LINE_COMPARE] = 0xFF;
+ par->crtc[VGA_CRTC_OVERFLOW] = r7;
par->vss = 0x00; /* 3DA */
for (i = 0x00; i < 0x10; i++)
par->atc[i] = i;
- par->atc[ATC_MODE] = 0x81;
- par->atc[ATC_OVERSCAN] = 0x00; /* 0 for EGA, 0xFF for VGA */
- par->atc[ATC_PLANE_ENABLE] = 0x0F;
- par->atc[ATC_PEL] = xoffset & 7;
- par->atc[ATC_COLOR_PAGE] = 0x00;
+ par->atc[VGA_ATC_MODE] = 0x81;
+ par->atc[VGA_ATC_OVERSCAN] = 0x00; /* 0 for EGA, 0xFF for VGA */
+ par->atc[VGA_ATC_PLANE_ENABLE] = 0x0F;
+ par->atc[VGA_ATC_PEL] = xoffset & 7;
+ par->atc[VGA_ATC_COLOR_PAGE] = 0x00;
par->misc = 0xC3; /* enable CPU, ports 0x3Dx, positive sync */
par->var.sync = var->sync;
@@ -504,20 +418,20 @@ static int vga16fb_decode_var(const struct fb_var_screeninfo *var,
if (var->sync & FB_SYNC_VERT_HIGH_ACT)
par->misc &= ~0x80;
- par->seq[SEQ_CLOCK_MODE] = 0x01;
- par->seq[SEQ_PLANE_WRITE] = 0x0F;
- par->seq[SEQ_CHARACTER_MAP] = 0x00;
- par->seq[SEQ_MEMORY_MODE] = 0x06;
+ par->seq[VGA_SEQ_CLOCK_MODE] = 0x01;
+ par->seq[VGA_SEQ_PLANE_WRITE] = 0x0F;
+ par->seq[VGA_SEQ_CHARACTER_MAP] = 0x00;
+ par->seq[VGA_SEQ_MEMORY_MODE] = 0x06;
- par->gdc[GDC_SR_VALUE] = 0x00;
- par->gdc[GDC_SR_ENABLE] = 0x0F;
- par->gdc[GDC_COMPARE_VALUE] = 0x00;
- par->gdc[GDC_DATA_ROTATE] = 0x20;
- par->gdc[GDC_PLANE_READ] = 0;
- par->gdc[GDC_MODE] = 0x00;
- par->gdc[GDC_MISC] = 0x05;
- par->gdc[GDC_COMPARE_MASK] = 0x0F;
- par->gdc[GDC_BIT_MASK] = 0xFF;
+ par->gdc[VGA_GFX_SR_VALUE] = 0x00;
+ par->gdc[VGA_GFX_SR_ENABLE] = 0x0F;
+ par->gdc[VGA_GFX_COMPARE_VALUE] = 0x00;
+ par->gdc[VGA_GFX_DATA_ROTATE] = 0x20;
+ par->gdc[VGA_GFX_PLANE_READ] = 0;
+ par->gdc[VGA_GFX_MODE] = 0x00;
+ par->gdc[VGA_GFX_MISC] = 0x05;
+ par->gdc[VGA_GFX_COMPARE_MASK] = 0x0F;
+ par->gdc[VGA_GFX_BIT_MASK] = 0xFF;
vga16fb_clock_chip(par, var->pixclock, info);
@@ -543,64 +457,64 @@ static int vga16fb_set_par(const struct vga16fb_par *par,
{
int i;
- outb(inb(MIS_R) | 0x01, MIS_W);
+ outb(inb(VGA_MIS_R) | 0x01, VGA_MIS_W);
/* Enable graphics register modification */
if (!info->isVGA) {
- outb(0x00, GRA_E0);
- outb(0x01, GRA_E1);
+ outb(0x00, EGA_GFX_E0);
+ outb(0x01, EGA_GFX_E1);
}
/* update misc output register */
- outb(par->misc, MIS_W);
+ outb(par->misc, VGA_MIS_W);
/* synchronous reset on */
- outb(0x00, SEQ_I);
- outb(0x01, SEQ_D);
+ outb(0x00, VGA_SEQ_I);
+ outb(0x01, VGA_SEQ_D);
/* write sequencer registers */
- outb(1, SEQ_I);
- outb(par->seq[1] | 0x20, SEQ_D);
- for (i = 2; i < SEQ_C; i++) {
- outb(i, SEQ_I);
- outb(par->seq[i], SEQ_D);
+ outb(1, VGA_SEQ_I);
+ outb(par->seq[1] | 0x20, VGA_SEQ_D);
+ for (i = 2; i < VGA_SEQ_C; i++) {
+ outb(i, VGA_SEQ_I);
+ outb(par->seq[i], VGA_SEQ_D);
}
/* synchronous reset off */
- outb(0x00, SEQ_I);
- outb(0x03, SEQ_D);
+ outb(0x00, VGA_SEQ_I);
+ outb(0x03, VGA_SEQ_D);
/* deprotect CRT registers 0-7 */
- outb(0x11, CRT_IC);
- outb(par->crtc[0x11], CRT_DC);
+ outb(0x11, VGA_CRT_IC);
+ outb(par->crtc[0x11], VGA_CRT_DC);
/* write CRT registers */
- for (i = 0; i < CRTC_REGS; i++) {
- outb(i, CRT_IC);
- outb(par->crtc[i], CRT_DC);
+ for (i = 0; i < VGA_CRT_C; i++) {
+ outb(i, VGA_CRT_IC);
+ outb(par->crtc[i], VGA_CRT_DC);
}
/* write graphics controller registers */
- for (i = 0; i < GRA_C; i++) {
- outb(i, GRA_I);
- outb(par->gdc[i], GRA_D);
+ for (i = 0; i < VGA_GFX_C; i++) {
+ outb(i, VGA_GFX_I);
+ outb(par->gdc[i], VGA_GFX_D);
}
/* write attribute controller registers */
- for (i = 0; i < ATT_C; i++) {
- inb_p(IS1_RC); /* reset flip-flop */
- outb_p(i, ATT_IW);
- outb_p(par->atc[i], ATT_IW);
+ for (i = 0; i < VGA_ATT_C; i++) {
+ inb_p(VGA_IS1_RC); /* reset flip-flop */
+ outb_p(i, VGA_ATT_IW);
+ outb_p(par->atc[i], VGA_ATT_IW);
}
/* Wait for screen to stabilize. */
mdelay(50);
- outb(0x01, SEQ_I);
- outb(par->seq[1], SEQ_D);
+ outb(0x01, VGA_SEQ_I);
+ outb(par->seq[1], VGA_SEQ_D);
- inb(IS1_RC);
- outb(0x20, ATT_IW);
+ inb(VGA_IS1_RC);
+ outb(0x20, VGA_ATT_IW);
return 0;
}
@@ -799,14 +713,14 @@ static struct fb_ops vga16fb_ops = {
vga16fb_ioctl
};
-void vga16fb_setup(char *options, int *ints)
+int vga16fb_setup(char *options)
{
char *this_opt;
vga16fb.fb_info.fontname[0] = '\0';
if (!options || !*options)
- return;
+ return 0;
for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) {
if (!*this_opt) continue;
@@ -814,6 +728,7 @@ void vga16fb_setup(char *options, int *ints)
if (!strncmp(this_opt, "font:", 5))
strcpy(vga16fb.fb_info.fontname, this_opt+5);
}
+ return 0;
}
static int vga16fb_switch(int con, struct fb_info *fb)
@@ -1003,14 +918,20 @@ static void vga16fb_blank(int blank, struct fb_info *fb_info)
}
}
-__initfunc(void vga16fb_init(void))
+int __init vga16_init(void)
{
int i,j;
- printk("vga16fb: initializing\n");
+ printk(KERN_DEBUG "vga16fb: initializing\n");
+
+ if (!__request_region(&iomem_resource, VGA_FB_PHYS, VGA_FB_PHYS_LEN,
+ "vga16fb")) {
+ printk (KERN_ERR "vga16fb: unable to reserve VGA memory, exiting\n");
+ return -1;
+ }
- vga16fb.video_vbase = ioremap((unsigned long)0xa0000, 65536);
- printk("vga16fb: mapped to 0x%p\n", vga16fb.video_vbase);
+ vga16fb.video_vbase = ioremap(VGA_FB_PHYS, VGA_FB_PHYS_LEN);
+ printk(KERN_INFO "vga16fb: mapped to 0x%p\n", vga16fb.video_vbase);
vga16fb.isVGA = ORIG_VIDEO_ISVGA;
vga16fb.palette_blanked = 0;
@@ -1027,10 +948,11 @@ __initfunc(void vga16fb_init(void))
palette[i].green = default_grn[j];
palette[i].blue = default_blu[j];
}
- if (vga16fb.isVGA)
- request_region(0x3c0, 32, "vga+");
- else
- request_region(0x3C0, 32, "ega");
+
+ /* note - does not cause failure, b/c vgacon probably still owns this
+ * region (FIXME) */
+ if (__request_region(&ioport_resource, 0x3C0, 32, "vga16fb"))
+ release_io_ports = 1;
disp.var = vga16fb_defined;
@@ -1047,12 +969,37 @@ __initfunc(void vga16fb_init(void))
vga16fb_set_disp(-1, &vga16fb);
if (register_framebuffer(&vga16fb.fb_info)<0)
- return;
+ return -EINVAL;
- printk("fb%d: %s frame buffer device\n",
+ printk(KERN_INFO "fb%d: %s frame buffer device\n",
GET_FB_IDX(vga16fb.fb_info.node), vga16fb.fb_info.modename);
+
+ return 0;
+}
+
+#ifndef MODULE
+int __init vga16fb_init(void)
+{
+ return vga16_init();
+}
+
+#else /* MODULE */
+
+int init_module(void)
+{
+ return vga16_init();
+}
+
+void cleanup_module(void)
+{
+ unregister_framebuffer(&vga16fb.fb_info);
+ iounmap(vga16fb.video_vbase);
+ __release_region(&iomem_resource, VGA_FB_PHYS, VGA_FB_PHYS_LEN);
+ if (release_io_ports)
+ __release_region(&ioport_resource, 0x3c0, 32);
}
+#endif
/*
* Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/drivers/video/vga_font.c b/drivers/video/vga_font.c
new file mode 100644
index 000000000..d6683ee4b
--- /dev/null
+++ b/drivers/video/vga_font.c
@@ -0,0 +1,352 @@
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/modversions.h>
+
+
+#define cmapsz 8192
+
+unsigned char vga_font[cmapsz] = {
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x81, 0xa5, 0x81, 0x81, 0xbd,
+0x99, 0x81, 0x81, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xff,
+0xdb, 0xff, 0xff, 0xc3, 0xe7, 0xff, 0xff, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x6c, 0xfe, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x7c, 0xfe,
+0x7c, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18,
+0x3c, 0x3c, 0xe7, 0xe7, 0xe7, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
+0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xe7, 0xc3, 0xc3, 0xe7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x42, 0x42, 0x66, 0x3c, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xc3, 0x99, 0xbd,
+0xbd, 0x99, 0xc3, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x1e, 0x0e,
+0x1a, 0x32, 0x78, 0xcc, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x3c, 0x66, 0x66, 0x66, 0x66, 0x3c, 0x18, 0x7e, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x33, 0x3f, 0x30, 0x30, 0x30,
+0x30, 0x70, 0xf0, 0xe0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0x63,
+0x7f, 0x63, 0x63, 0x63, 0x63, 0x67, 0xe7, 0xe6, 0xc0, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x18, 0x18, 0xdb, 0x3c, 0xe7, 0x3c, 0xdb, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfe, 0xf8,
+0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x06, 0x0e,
+0x1e, 0x3e, 0xfe, 0x3e, 0x1e, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+0x66, 0x00, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7f, 0xdb,
+0xdb, 0xdb, 0x7b, 0x1b, 0x1b, 0x1b, 0x1b, 0x1b, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x7c, 0xc6, 0x60, 0x38, 0x6c, 0xc6, 0xc6, 0x6c, 0x38, 0x0c, 0xc6,
+0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c,
+0x7e, 0x18, 0x18, 0x18, 0x7e, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x3c, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x7e, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0x0c, 0xfe, 0x0c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x60, 0xfe, 0x60, 0x30, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xc0,
+0xc0, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x24, 0x66, 0xff, 0x66, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x38, 0x7c, 0x7c, 0xfe, 0xfe, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0x7c, 0x7c,
+0x38, 0x38, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x66, 0x66, 0x24, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6c,
+0x6c, 0xfe, 0x6c, 0x6c, 0x6c, 0xfe, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x18, 0x7c, 0xc6, 0xc2, 0xc0, 0x7c, 0x06, 0x06, 0x86, 0xc6, 0x7c,
+0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0xc6, 0x0c, 0x18,
+0x30, 0x60, 0xc6, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c,
+0x6c, 0x38, 0x76, 0xdc, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x30, 0x30, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x30, 0x30, 0x30,
+0x30, 0x30, 0x18, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18,
+0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x3c, 0xff, 0x3c, 0x66, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
+0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x02, 0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0x80, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xce, 0xde, 0xf6, 0xe6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x38, 0x78, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+0x06, 0x0c, 0x18, 0x30, 0x60, 0xc0, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0x06, 0x06, 0x3c, 0x06, 0x06, 0x06, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x6c, 0xcc, 0xfe,
+0x0c, 0x0c, 0x0c, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
+0xc0, 0xc0, 0xfc, 0x06, 0x06, 0x06, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x60, 0xc0, 0xc0, 0xfc, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0x06, 0x06, 0x0c, 0x18,
+0x30, 0x30, 0x30, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+0xc6, 0xc6, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x06, 0x06, 0x0c, 0x78,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00,
+0x00, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x18, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x06,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x00,
+0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60,
+0x30, 0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x60, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0x0c, 0x18, 0x18, 0x18, 0x00, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xde, 0xde,
+0xde, 0xdc, 0xc0, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38,
+0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x66, 0x66, 0x66, 0x66, 0xfc,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0xc2, 0xc0, 0xc0, 0xc0,
+0xc0, 0xc2, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x6c,
+0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x6c, 0xf8, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68, 0x60, 0x62, 0x66, 0xfe,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x66, 0x62, 0x68, 0x78, 0x68,
+0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
+0xc2, 0xc0, 0xc0, 0xde, 0xc6, 0xc6, 0x66, 0x3a, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x0c,
+0x0c, 0x0c, 0x0c, 0x0c, 0xcc, 0xcc, 0xcc, 0x78, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xe6, 0x66, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0x66, 0xe6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x60, 0x60, 0x60, 0x60, 0x60,
+0x60, 0x62, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xe7,
+0xff, 0xff, 0xdb, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6, 0xc6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66,
+0x66, 0x66, 0x7c, 0x60, 0x60, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xd6, 0xde, 0x7c,
+0x0c, 0x0e, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66, 0x66, 0x7c, 0x6c,
+0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6,
+0xc6, 0x60, 0x38, 0x0c, 0x06, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xff, 0xdb, 0x99, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
+0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xc3, 0xc3, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x66,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0x66, 0x3c, 0x18, 0x18,
+0x3c, 0x66, 0xc3, 0xc3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3,
+0xc3, 0x66, 0x3c, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xff, 0xc3, 0x86, 0x0c, 0x18, 0x30, 0x60, 0xc1, 0xc3, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x30, 0x30, 0x30, 0x30, 0x30,
+0x30, 0x30, 0x30, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80,
+0xc0, 0xe0, 0x70, 0x38, 0x1c, 0x0e, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x3c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00,
+0x30, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x0c, 0x7c,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x60,
+0x60, 0x78, 0x6c, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc0, 0xc0, 0xc0, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x0c, 0x0c, 0x3c, 0x6c, 0xcc,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xf0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xcc, 0xcc,
+0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0xcc, 0x78, 0x00, 0x00, 0x00, 0xe0, 0x60,
+0x60, 0x6c, 0x76, 0x66, 0x66, 0x66, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x18, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x0e, 0x06, 0x06,
+0x06, 0x06, 0x06, 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0xe0, 0x60,
+0x60, 0x66, 0x6c, 0x78, 0x78, 0x6c, 0x66, 0xe6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe6, 0xff, 0xdb,
+0xdb, 0xdb, 0xdb, 0xdb, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x66, 0x66,
+0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x76, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x7c, 0x0c, 0x0c, 0x1e, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xdc, 0x76, 0x66, 0x60, 0x60, 0x60, 0xf0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0xc6, 0x60,
+0x38, 0x0c, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x30,
+0x30, 0xfc, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0xc3, 0xc3,
+0xc3, 0x66, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xc3, 0xc3, 0xc3, 0xdb, 0xdb, 0xff, 0x66, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0x3c, 0x66, 0xc3,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xfe, 0xcc, 0x18, 0x30, 0x60, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x0e, 0x18, 0x18, 0x18, 0x70, 0x18, 0x18, 0x18, 0x18, 0x0e,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x18,
+0x18, 0x18, 0x0e, 0x18, 0x18, 0x18, 0x18, 0x70, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0xc6,
+0xc6, 0xc6, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x66,
+0xc2, 0xc0, 0xc0, 0xc0, 0xc2, 0x66, 0x3c, 0x0c, 0x06, 0x7c, 0x00, 0x00,
+0x00, 0x00, 0xcc, 0x00, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x00, 0x7c, 0xc6, 0xfe,
+0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c,
+0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xcc, 0x00, 0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0x78, 0x0c, 0x7c,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38,
+0x00, 0x78, 0x0c, 0x7c, 0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x3c, 0x66, 0x60, 0x60, 0x66, 0x3c, 0x0c, 0x06,
+0x3c, 0x00, 0x00, 0x00, 0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xfe,
+0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
+0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x60, 0x30, 0x18, 0x00, 0x7c, 0xc6, 0xfe, 0xc0, 0xc0, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00, 0x38, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x66,
+0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x60, 0x30, 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x10, 0x38, 0x6c, 0xc6, 0xc6,
+0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x38, 0x00,
+0x38, 0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x30, 0x60, 0x00, 0xfe, 0x66, 0x60, 0x7c, 0x60, 0x60, 0x66, 0xfe,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0x3b, 0x1b,
+0x7e, 0xd8, 0xdc, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x6c,
+0xcc, 0xcc, 0xfe, 0xcc, 0xcc, 0xcc, 0xcc, 0xce, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x10, 0x38, 0x6c, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0x00, 0x7c, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18,
+0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x30, 0x78, 0xcc, 0x00, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0xcc, 0x76,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x30, 0x18, 0x00, 0xcc, 0xcc, 0xcc,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00,
+0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7e, 0x06, 0x0c, 0x78, 0x00,
+0x00, 0xc6, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0xc6, 0x00, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6,
+0xc6, 0xc6, 0xc6, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e,
+0xc3, 0xc0, 0xc0, 0xc0, 0xc3, 0x7e, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x38, 0x6c, 0x64, 0x60, 0xf0, 0x60, 0x60, 0x60, 0x60, 0xe6, 0xfc,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc3, 0x66, 0x3c, 0x18, 0xff, 0x18,
+0xff, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x66, 0x66,
+0x7c, 0x62, 0x66, 0x6f, 0x66, 0x66, 0x66, 0xf3, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x0e, 0x1b, 0x18, 0x18, 0x18, 0x7e, 0x18, 0x18, 0x18, 0x18, 0x18,
+0xd8, 0x70, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0x78, 0x0c, 0x7c,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x18, 0x30,
+0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x18, 0x30, 0x60, 0x00, 0x7c, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x30, 0x60, 0x00, 0xcc, 0xcc, 0xcc,
+0xcc, 0xcc, 0xcc, 0x76, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc,
+0x00, 0xdc, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x00, 0x00, 0x00, 0x00,
+0x76, 0xdc, 0x00, 0xc6, 0xe6, 0xf6, 0xfe, 0xde, 0xce, 0xc6, 0xc6, 0xc6,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x6c, 0x6c, 0x3e, 0x00, 0x7e, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
+0x38, 0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x30, 0x30, 0x00, 0x30, 0x30, 0x60, 0xc0, 0xc6, 0xc6, 0x7c,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc0,
+0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0xfe, 0x06, 0x06, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30, 0x60, 0xce, 0x9b, 0x06,
+0x0c, 0x1f, 0x00, 0x00, 0x00, 0xc0, 0xc0, 0xc2, 0xc6, 0xcc, 0x18, 0x30,
+0x66, 0xce, 0x96, 0x3e, 0x06, 0x06, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18,
+0x00, 0x18, 0x18, 0x18, 0x3c, 0x3c, 0x3c, 0x18, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x6c, 0xd8, 0x6c, 0x36, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xd8, 0x6c, 0x36,
+0x6c, 0xd8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x44, 0x11, 0x44,
+0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44, 0x11, 0x44,
+0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
+0x55, 0xaa, 0x55, 0xaa, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
+0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x18, 0xf8,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36,
+0x36, 0xf6, 0x06, 0xf6, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x06, 0xf6,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0xf6, 0x06, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xfe, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8, 0x18, 0xf8,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x37,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x37, 0x30, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xf7, 0x00, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xff, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x37, 0x30, 0x37, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36,
+0x36, 0xf7, 0x00, 0xf7, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0xff,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x3f,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f,
+0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x36, 0x36, 0x36, 0xff, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36, 0x36,
+0x18, 0x18, 0x18, 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0xf8,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf0, 0xf0, 0xf0, 0xf0,
+0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+0x0f, 0x0f, 0x0f, 0x0f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x76, 0xdc, 0xd8, 0xd8, 0xd8, 0xdc, 0x76, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x78, 0xcc, 0xcc, 0xcc, 0xd8, 0xcc, 0xc6, 0xc6, 0xc6, 0xcc,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xc6, 0xc6, 0xc0, 0xc0, 0xc0,
+0xc0, 0xc0, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0xfe, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0xfe, 0xc6, 0x60, 0x30, 0x18, 0x30, 0x60, 0xc6, 0xfe,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0xd8, 0xd8,
+0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x66, 0x66, 0x66, 0x66, 0x66, 0x7c, 0x60, 0x60, 0xc0, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x18, 0x3c, 0x66, 0x66,
+0x66, 0x3c, 0x18, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38,
+0x6c, 0xc6, 0xc6, 0xfe, 0xc6, 0xc6, 0x6c, 0x38, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x38, 0x6c, 0xc6, 0xc6, 0xc6, 0x6c, 0x6c, 0x6c, 0x6c, 0xee,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x30, 0x18, 0x0c, 0x3e, 0x66,
+0x66, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x7e, 0xdb, 0xdb, 0xdb, 0x7e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x03, 0x06, 0x7e, 0xdb, 0xdb, 0xf3, 0x7e, 0x60, 0xc0,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7c, 0x60,
+0x60, 0x60, 0x30, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c,
+0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0xc6, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00, 0x00, 0xfe, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x7e, 0x18,
+0x18, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30,
+0x18, 0x0c, 0x06, 0x0c, 0x18, 0x30, 0x00, 0x7e, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x0c, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0c, 0x00, 0x7e,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0e, 0x1b, 0x1b, 0x1b, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+0x18, 0x18, 0x18, 0x18, 0xd8, 0xd8, 0xd8, 0x70, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x7e, 0x00, 0x18, 0x18, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xdc, 0x00,
+0x76, 0xdc, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x6c, 0x6c,
+0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0c, 0x0c,
+0x0c, 0x0c, 0x0c, 0xec, 0x6c, 0x6c, 0x3c, 0x1c, 0x00, 0x00, 0x00, 0x00,
+0x00, 0xd8, 0x6c, 0x6c, 0x6c, 0x6c, 0x6c, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xd8, 0x30, 0x60, 0xc8, 0xf8, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+};
+
diff --git a/drivers/video/vgacon.c b/drivers/video/vgacon.c
index 95a758dd1..696845f8a 100644
--- a/drivers/video/vgacon.c
+++ b/drivers/video/vgacon.c
@@ -116,7 +116,7 @@ static int vga_video_font_height;
static unsigned int vga_rolled_over = 0;
-void no_scroll(char *str, int *ints)
+static int __init no_scroll(char *str)
{
/*
* Disabling scrollback is required for the Braillex ib80-piezo
@@ -124,8 +124,11 @@ void no_scroll(char *str, int *ints)
* Use the "no-scroll" bootflag.
*/
vga_hardscroll_user_enable = vga_hardscroll_enabled = 0;
+ return 1;
}
+__setup("no-scroll", no_scroll);
+
/*
* By replacing the four outb_p with two back to back outw, we can reduce
* the window of opportunity to see text mislocated to the RHS of the
@@ -159,11 +162,11 @@ static inline void write_vga(unsigned char reg, unsigned int val)
restore_flags(flags);
}
-__initfunc(static const char *vgacon_startup(void))
+static const char __init *vgacon_startup(void)
{
const char *display_desc = NULL;
u16 saved1, saved2;
- u16 *p;
+ volatile u16 *p;
if (ORIG_VIDEO_ISVGA == VIDEO_TYPE_VLFB) {
no_vga:
@@ -186,18 +189,21 @@ __initfunc(static const char *vgacon_startup(void))
vga_video_port_val = 0x3b5;
if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
{
+ static struct resource ega_console_resource = { "ega", 0x3B0, 0x3BF };
vga_video_type = VIDEO_TYPE_EGAM;
vga_vram_end = 0xb8000;
display_desc = "EGA+";
- request_region(0x3b0,16,"ega");
+ request_resource(&ioport_resource, &ega_console_resource);
}
else
{
+ static struct resource mda1_console_resource = { "mda", 0x3B0, 0x3BB };
+ static struct resource mda2_console_resource = { "mda", 0x3BF, 0x3BF };
vga_video_type = VIDEO_TYPE_MDA;
vga_vram_end = 0xb2000;
display_desc = "*MDA";
- request_region(0x3b0,12,"mda");
- request_region(0x3bf, 1,"mda");
+ request_resource(&ioport_resource, &mda1_console_resource);
+ request_resource(&ioport_resource, &mda2_console_resource);
vga_video_font_height = 14;
}
}
@@ -214,13 +220,15 @@ __initfunc(static const char *vgacon_startup(void))
vga_vram_end = 0xc0000;
if (!ORIG_VIDEO_ISVGA) {
+ static struct resource ega_console_resource = { "ega", 0x3C0, 0x3DF };
vga_video_type = VIDEO_TYPE_EGAC;
display_desc = "EGA";
- request_region(0x3c0,32,"ega");
+ request_resource(&ioport_resource, &ega_console_resource);
} else {
+ static struct resource vga_console_resource = { "vga+", 0x3C0, 0x3DF };
vga_video_type = VIDEO_TYPE_VGAC;
display_desc = "VGA+";
- request_region(0x3c0,32,"vga+");
+ request_resource(&ioport_resource, &vga_console_resource);
#ifdef VGA_CAN_DO_64KB
/*
@@ -261,13 +269,15 @@ __initfunc(static const char *vgacon_startup(void))
}
else
{
+ static struct resource cga_console_resource = { "cga", 0x3D4, 0x3D5 };
vga_video_type = VIDEO_TYPE_CGA;
vga_vram_end = 0xba000;
display_desc = "*CGA";
- request_region(0x3d4,2,"cga");
+ request_resource(&ioport_resource, &cga_console_resource);
vga_video_font_height = 8;
}
}
+
vga_vram_base = VGA_MAP_MEM(vga_vram_base);
vga_vram_end = VGA_MAP_MEM(vga_vram_end);
@@ -275,7 +285,7 @@ __initfunc(static const char *vgacon_startup(void))
* Find out if there is a graphics card present.
* Are there smarter methods around?
*/
- p = (u16 *)vga_vram_base;
+ p = (volatile u16 *)vga_vram_base;
saved1 = scr_readw(p);
saved2 = scr_readw(p + 1);
scr_writew(0xAA55, p);
diff --git a/drivers/video/virgefb.c b/drivers/video/virgefb.c
index a19c1c9e5..1e9abfe3d 100644
--- a/drivers/video/virgefb.c
+++ b/drivers/video/virgefb.c
@@ -85,10 +85,21 @@
(*((unsigned word volatile *)(CyberRegs + reg)) = dat)
#define wl_3d(reg,dat) \
(*((unsigned long volatile *)(CyberRegs + reg)) = dat)
-
#define rl_3d(reg) \
(*((unsigned long volatile *)(CyberRegs + reg)))
+#define Select_Zorro2_FrameBuffer(flag) \
+ do { \
+ *((unsigned char volatile *)((Cyber_vcode_switch_base) + 0x08)) = \
+ ((flag * 0x40) & 0xffff); asm volatile ("nop"); \
+ } while (0)
+/*
+ * may be needed when we initialize the board?
+ * 8bit: flag = 2, 16 bit: flag = 1, 24/32bit: flag = 0
+ * _when_ the board is initialized, depth doesnt matter, we allways write
+ * to the same address, aperture seems not to matter on Z2.
+ */
+
struct virgefb_par {
int xres;
int yres;
@@ -175,7 +186,10 @@ static unsigned char cv3d_on_zorro2;
* Predefined Video Modes
*/
-static struct fb_videomode virgefb_predefined[] __initdata = {
+static struct {
+ const char *name;
+ struct fb_var_screeninfo var;
+} virgefb_predefined[] __initdata = {
{
"640x480-8", { /* Cybervision 8 bpp */
640, 480, 640, 480, 0, 0, 8, 0,
@@ -236,28 +250,28 @@ static struct fb_videomode virgefb_predefined[] __initdata = {
"1024x768-16", { /* Cybervision 16 bpp */
1024, 768, 1024, 768, 0, 0, 16, 0,
{11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}, {
"1152x886-16", { /* Cybervision 16 bpp */
1152, 886, 1152, 886, 0, 0, 16, 0,
{11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}, {
"1280x1024-16", { /* Cybervision 16 bpp */
1280, 1024, 1280, 1024, 0, 0, 16, 0,
{11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}, {
"1600x1200-16", { /* Cybervision 16 bpp */
1600, 1200, 1600, 1200, 0, 0, 16, 0,
{11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, 0, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}
@@ -268,10 +282,6 @@ static struct fb_videomode virgefb_predefined[] __initdata = {
static int Cyberfb_inverse = 0;
-#if 0
-static int Cyberfb_Cyber8 = 0; /* Use Cybervision board */
-static int Cyberfb_Cyber16 = 0; /* Use Cybervision board */
-#endif
/*
* Some default modes
@@ -287,7 +297,7 @@ static struct fb_var_screeninfo virgefb_default;
* Interface used by the world
*/
-void virgefb_setup(char *options, int *ints);
+int virgefb_setup(char*);
static int virgefb_open(struct fb_info *info, int user);
static int virgefb_release(struct fb_info *info, int user);
@@ -311,7 +321,7 @@ static int virgefb_ioctl(struct inode *inode, struct file *file, u_int cmd,
* Interface to the low level console driver
*/
-void virgefb_init(void);
+int virgefb_init(void);
static int Cyberfb_switch(int con, struct fb_info *info);
static int Cyberfb_updatevar(int con, struct fb_info *info);
static void Cyberfb_blank(int blank, struct fb_info *info);
@@ -392,6 +402,7 @@ static int Cyber_init(void)
} else {
CyberSize = 0x00400000; /* 4 MB */
}
+
memset ((char*)CyberMem, 0, CyberSize);
/* Disable hardware cursor */
@@ -430,19 +441,19 @@ static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id, virgefb_name);
if (cv3d_on_zorro2) {
- fix->smem_start = (char*) CyberMem_phys;
+ fix->smem_start = CyberMem_phys;
} else {
switch (par->bpp) {
case 8:
- fix->smem_start = (char*) (CyberMem_phys + CYBMEM_OFFSET_8);
+ fix->smem_start = (CyberMem_phys + CYBMEM_OFFSET_8);
break;
case 16:
- fix->smem_start = (char*) (CyberMem_phys + CYBMEM_OFFSET_16);
+ fix->smem_start = (CyberMem_phys + CYBMEM_OFFSET_16);
break;
}
}
fix->smem_len = CyberSize;
- fix->mmio_start = (char*) CyberRegs_phys;
+ fix->mmio_start = CyberRegs_phys;
fix->mmio_len = 0x10000; /* TODO: verify this for the CV64/3D */
fix->type = FB_TYPE_PACKED_PIXELS;
@@ -667,7 +678,13 @@ void Cyber_blank(int blank)
* CV3D low-level support
*/
-#define Cyber3D_WaitQueue(v) { do { while ((rl_3d(0x8504) & 0x1f00) < (((v)+2) << 8)); } while (0); }
+#define Cyber3D_WaitQueue(v) \
+{ \
+ do { \
+ while ((rl_3d(0x8504) & 0x1f00) < (((v)+2) << 8)); \
+ } \
+ while (0); \
+}
static inline void Cyber3D_WaitBusy(void)
{
@@ -699,11 +716,22 @@ unsigned long status;
*/
static void Cyber3D_BitBLT(u_short curx, u_short cury, u_short destx,
- u_short desty, u_short width, u_short height)
+ u_short desty, u_short width, u_short height, u_short depth)
{
- unsigned int blitcmd = S3V_BITBLT | S3V_DRAW | S3V_DST_8BPP;
+ unsigned int blitcmd = S3V_BITBLT | S3V_DRAW | S3V_BLT_COPY;
- blitcmd |= S3V_BLT_COPY;
+ switch (depth) {
+#ifdef FBCON_HAS_CFB8
+ case 8 :
+ blitcmd |= S3V_DST_8BPP;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB16
+ case 16 :
+ blitcmd |= S3V_DST_16BPP;
+ break;
+#endif
+ }
/* Set drawing direction */
/* -Y, X maj, -X (default) */
@@ -748,16 +776,29 @@ static void Cyber3D_BitBLT(u_short curx, u_short cury, u_short destx,
*/
static void Cyber3D_RectFill(u_short x, u_short y, u_short width,
- u_short height, u_short color)
+ u_short height, u_short color, u_short depth)
{
unsigned int tmp;
- unsigned int blitcmd = S3V_RECTFILL | S3V_DRAW | S3V_DST_8BPP |
+ unsigned int blitcmd = S3V_RECTFILL | S3V_DRAW |
S3V_BLT_CLEAR | S3V_MONO_PAT | (1 << 26) | (1 << 25);
if (blit_maybe_busy)
Cyber3D_WaitBusy();
blit_maybe_busy = 1;
+ switch (depth) {
+#ifdef FBCON_HAS_CFB8
+ case 8 :
+ blitcmd |= S3V_DST_8BPP;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB16
+ case 16 :
+ blitcmd |= S3V_DST_16BPP;
+ break;
+#endif
+ }
+
tmp = color & 0xff;
wl_3d(0xa4f4, tmp);
@@ -775,7 +816,7 @@ static void Cyber3D_RectFill(u_short x, u_short y, u_short width,
#if 0
static void Cyber_MoveCursor (u_short x, u_short y)
{
- printk("Yuck .... MoveCursor on a 3D\n");
+ printk(KERN_DEBUG "Yuck .... MoveCursor on a 3D\n");
return;
}
#endif
@@ -1087,14 +1128,14 @@ static struct fb_ops virgefb_ops = {
};
-__initfunc(void virgefb_setup(char *options, int *ints))
+int __init virgefb_setup(char *options)
{
char *this_opt;
fb_info.fontname[0] = '\0';
if (!options || !*options)
- return;
+ return 0;
for (this_opt = strtok(options, ","); this_opt; this_opt = strtok(NULL, ","))
if (!strcmp(this_opt, "inverse")) {
@@ -1114,6 +1155,7 @@ __initfunc(void virgefb_setup(char *options, int *ints))
DPRINTK("default mode: xres=%d, yres=%d, bpp=%d\n",virgefb_default.xres,
virgefb_default.yres,
virgefb_default.bits_per_pixel);
+ return 0;
}
@@ -1121,14 +1163,14 @@ __initfunc(void virgefb_setup(char *options, int *ints))
* Initialization
*/
-__initfunc(void virgefb_init(void))
+void __init virgefb_init(void)
{
struct virgefb_par par;
unsigned long board_addr;
const struct ConfigDev *cd;
if (!(CyberKey = zorro_find(ZORRO_PROD_PHASE5_CYBERVISION64_3D, 0, 0)))
- return;
+ return -ENXIO;
cd = zorro_get_board (CyberKey);
zorro_config_board (CyberKey, 0);
@@ -1152,18 +1194,17 @@ __initfunc(void virgefb_init(void))
Cyber_vcode_switch_base = (unsigned long) \
ZTWO_VADDR(board_addr + 0x003a0000);
cv3d_on_zorro2 = 1;
- printk("CV3D detected running in Z2 mode.\n");
+ printk(KERN_INFO "CV3D detected running in Z2 mode.\n");
}
else
{
CyberVGARegs = (unsigned long)ioremap(board_addr +0x0c000000, 0x00010000);
-
CyberRegs_phys = board_addr + 0x05000000;
CyberMem_phys = board_addr + 0x04000000; /* was 0x04800000 */
CyberRegs = ioremap(CyberRegs_phys, 0x00010000);
CyberMem = (unsigned long)ioremap(CyberMem_phys, 0x01000000); /* was 0x00400000 */
cv3d_on_zorro2 = 0;
- printk("CV3D detected running in Z3 mode\n");
+ printk(KERN_INFO "CV3D detected running in Z3 mode.\n");
}
fbhw = &Cyber_switch;
@@ -1188,15 +1229,16 @@ __initfunc(void virgefb_init(void))
do_install_cmap(0, &fb_info);
if (register_framebuffer(&fb_info) < 0) {
- printk("virgefb.c: register_framebuffer failed\n");
- return;
+ printk(KERN_ERR "virgefb.c: register_framebuffer failed\n");
+ return -EINVAL;
}
- printk("fb%d: %s frame buffer device, using %ldK of video memory\n",
+ printk(KERN_INFO "fb%d: %s frame buffer device, using %ldK of video memory\n",
GET_FB_IDX(fb_info.node), fb_info.modename, CyberSize>>10);
/* TODO: This driver cannot be unloaded yet */
MOD_INC_USE_COUNT;
+ return 0;
}
@@ -1242,7 +1284,7 @@ static void Cyberfb_blank(int blank, struct fb_info *info)
* Get a Video Mode
*/
-__initfunc(static int get_video_mode(const char *name))
+static int __init get_video_mode(const char *name)
{
int i;
@@ -1269,7 +1311,7 @@ static void fbcon_virge8_bmove(struct display *p, int sy, int sx, int dy,
sx *= 8; dx *= 8; width *= 8;
Cyber3D_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
(u_short)(dy*fontheight(p)), (u_short)width,
- (u_short)(height*fontheight(p)));
+ (u_short)(height*fontheight(p)), 8);
}
static void fbcon_virge8_clear(struct vc_data *conp, struct display *p, int sy,
@@ -1281,7 +1323,7 @@ static void fbcon_virge8_clear(struct vc_data *conp, struct display *p, int sy,
bg = attr_bgcol_ec(p,conp);
Cyber3D_RectFill((u_short)sx, (u_short)(sy*fontheight(p)),
(u_short)width, (u_short)(height*fontheight(p)),
- (u_short)bg);
+ (u_short)bg, 8);
}
static void fbcon_virge8_putc(struct vc_data *conp, struct display *p, int c, int yy,
@@ -1326,10 +1368,10 @@ static struct display_switch fbcon_virge8 = {
static void fbcon_virge16_bmove(struct display *p, int sy, int sx, int dy,
int dx, int height, int width)
{
- sx *= 16; dx *= 16; width *= 16;
+ sx *= 8; dx *= 8; width *= 8;
Cyber3D_BitBLT((u_short)sx, (u_short)(sy*fontheight(p)), (u_short)dx,
(u_short)(dy*fontheight(p)), (u_short)width,
- (u_short)(height*fontheight(p)));
+ (u_short)(height*fontheight(p)), 16);
}
static void fbcon_virge16_clear(struct vc_data *conp, struct display *p, int sy,
@@ -1337,11 +1379,11 @@ static void fbcon_virge16_clear(struct vc_data *conp, struct display *p, int sy,
{
unsigned char bg;
- sx *= 16; width *= 16;
+ sx *= 8; width *= 8;
bg = attr_bgcol_ec(p,conp);
Cyber3D_RectFill((u_short)sx, (u_short)(sy*fontheight(p)),
(u_short)width, (u_short)(height*fontheight(p)),
- (u_short)bg);
+ (u_short)bg, 16);
}
static void fbcon_virge16_putc(struct vc_data *conp, struct display *p, int c, int yy,
@@ -1385,8 +1427,7 @@ static struct display_switch fbcon_virge16 = {
#ifdef MODULE
int init_module(void)
{
- virgefb_init();
- return 0;
+ return virgefb_init();
}
void cleanup_module(void)