summaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-08-25 09:12:35 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-08-25 09:12:35 +0000
commitc7fc24dc4420057f103afe8fc64524ebc25c5d37 (patch)
tree3682407a599b8f9f03fc096298134cafba1c9b2f /drivers/video
parent1d793fade8b063fde3cf275bf1a5c2d381292cd9 (diff)
o Merge with Linux 2.1.116.
o New Newport console code. o New G364 console code.
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/Config.in266
-rw-r--r--drivers/video/Makefile320
-rw-r--r--drivers/video/S3triofb.c326
-rw-r--r--drivers/video/acornfb.c382
-rw-r--r--drivers/video/amifb.c73
-rw-r--r--drivers/video/atafb.c94
-rw-r--r--drivers/video/aty.h101
-rw-r--r--drivers/video/atyfb.c3749
-rw-r--r--drivers/video/bwtwofb.c222
-rw-r--r--drivers/video/cgsixfb.c683
-rw-r--r--drivers/video/cgthreefb.c247
-rw-r--r--drivers/video/chipsfb.c565
-rw-r--r--drivers/video/clgenfb.c2121
-rw-r--r--drivers/video/clgenfb.h175
-rw-r--r--drivers/video/controlfb.c997
-rw-r--r--drivers/video/controlfb.h262
-rw-r--r--drivers/video/creatorfb.c537
-rw-r--r--drivers/video/cyberfb.c97
-rw-r--r--drivers/video/dnfb.c42
-rw-r--r--drivers/video/dummycon.c71
-rw-r--r--drivers/video/fbcmap.c4
-rw-r--r--drivers/video/fbcon-afb.c41
-rw-r--r--drivers/video/fbcon-afb.h14
-rw-r--r--drivers/video/fbcon-cfb16.c253
-rw-r--r--drivers/video/fbcon-cfb16.h15
-rw-r--r--drivers/video/fbcon-cfb2.c41
-rw-r--r--drivers/video/fbcon-cfb2.h14
-rw-r--r--drivers/video/fbcon-cfb24.c264
-rw-r--r--drivers/video/fbcon-cfb24.h15
-rw-r--r--drivers/video/fbcon-cfb32.c225
-rw-r--r--drivers/video/fbcon-cfb32.h15
-rw-r--r--drivers/video/fbcon-cfb4.c44
-rw-r--r--drivers/video/fbcon-cfb4.h14
-rw-r--r--drivers/video/fbcon-cfb8.c215
-rw-r--r--drivers/video/fbcon-cfb8.h15
-rw-r--r--drivers/video/fbcon-ilbm.c43
-rw-r--r--drivers/video/fbcon-ilbm.h14
-rw-r--r--drivers/video/fbcon-iplan2p2.c43
-rw-r--r--drivers/video/fbcon-iplan2p2.h14
-rw-r--r--drivers/video/fbcon-iplan2p4.c43
-rw-r--r--drivers/video/fbcon-iplan2p4.h14
-rw-r--r--drivers/video/fbcon-iplan2p8.c35
-rw-r--r--drivers/video/fbcon-iplan2p8.h14
-rw-r--r--drivers/video/fbcon-mac.c41
-rw-r--r--drivers/video/fbcon-mac.h14
-rw-r--r--drivers/video/fbcon-mfb.c42
-rw-r--r--drivers/video/fbcon-mfb.h14
-rw-r--r--drivers/video/fbcon-vga.c206
-rw-r--r--drivers/video/fbcon-vga.h27
-rw-r--r--drivers/video/fbcon.c1304
-rw-r--r--drivers/video/fbcon.h106
-rw-r--r--drivers/video/fbgen.c58
-rw-r--r--drivers/video/font.h46
-rw-r--r--drivers/video/font_6x11.c18
-rw-r--r--drivers/video/font_8x16.c18
-rw-r--r--drivers/video/font_8x8.c18
-rw-r--r--drivers/video/font_acorn_8x8.c277
-rw-r--r--drivers/video/font_pearl_8x8.c (renamed from drivers/video/pearl_8x8.c)17
-rw-r--r--drivers/video/font_sun12x22.c6220
-rw-r--r--drivers/video/font_sun8x16.c275
-rw-r--r--drivers/video/fonts.c158
-rw-r--r--drivers/video/g364fb.c3
-rw-r--r--drivers/video/hpfb.c428
-rw-r--r--drivers/video/macfb.c48
-rw-r--r--drivers/video/macmodes.c391
-rw-r--r--drivers/video/macmodes.h60
-rw-r--r--drivers/video/mdafb.c480
-rw-r--r--drivers/video/newport_con.c6
-rw-r--r--drivers/video/offb.c169
-rw-r--r--drivers/video/platinumfb.c1052
-rw-r--r--drivers/video/platinumfb.h399
-rw-r--r--drivers/video/prom.uni11
-rw-r--r--drivers/video/promcon.c600
-rw-r--r--drivers/video/retz3fb.c103
-rw-r--r--drivers/video/sbusfb.c1128
-rw-r--r--drivers/video/sbusfb.h116
-rw-r--r--drivers/video/skeletonfb.c31
-rw-r--r--drivers/video/tcxfb.c290
-rw-r--r--drivers/video/tgafb.c52
-rw-r--r--drivers/video/txtcon.c178
-rw-r--r--drivers/video/vesafb.c478
-rw-r--r--drivers/video/vfb.c64
-rw-r--r--drivers/video/vgacon.c1072
-rw-r--r--drivers/video/vgafb.c764
-rw-r--r--drivers/video/virgefb.c111
85 files changed, 26327 insertions, 3305 deletions
diff --git a/drivers/video/Config.in b/drivers/video/Config.in
index b4766876b..82d77bd12 100644
--- a/drivers/video/Config.in
+++ b/drivers/video/Config.in
@@ -3,10 +3,10 @@
#
if [ "$CONFIG_FB" = "y" ]; then
-
- mainmenu_option next_comment
- comment 'Frame buffer devices'
-
+ define_bool CONFIG_DUMMY_CONSOLE y
+ if [ "$CONFIG_ARCH_ACORN" = "y" ]; then
+ bool 'Acorn VIDC support' CONFIG_FB_ACORN
+ fi
if [ "$CONFIG_APOLLO" = "y" ]; then
define_bool CONFIG_FB_APOLLO y
fi
@@ -17,10 +17,13 @@ if [ "$CONFIG_FB" = "y" ]; then
bool 'Amiga ECS chipset support' CONFIG_FB_AMIGA_ECS
bool 'Amiga AGA chipset support' CONFIG_FB_AMIGA_AGA
fi
+ fi
+ if [ "$CONFIG_ZORRO" = "y" ]; then
tristate 'Amiga CyberVision support' CONFIG_FB_CYBER
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
fi
fi
if [ "$CONFIG_ATARI" = "y" ]; then
@@ -29,87 +32,236 @@ if [ "$CONFIG_FB" = "y" ]; then
fi
if [ "$CONFIG_PPC" = "y" ]; then
bool 'Open Firmware frame buffer device support' CONFIG_FB_OF
- bool 'S3 Trio frame buffer device support' CONFIG_FB_S3TRIO
if [ "$CONFIG_FB_OF" = "y" ]; then
-# bool 'Apple "control" display support' CONFIG_FB_CONTROL
-# bool 'Apple "platinum" display support' CONFIG_FB_PLATINUM
+ 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
# 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
+ bool 'Chips 65550 display support' CONFIG_FB_CT65550
+ bool 'S3 Trio display support' CONFIG_FB_S3TRIO
fi
fi
if [ "$CONFIG_MAC" = "y" ]; then
define_bool CONFIG_FB_MAC y
fi
- if [ "$CONFIG_TGA_CONSOLE" = "y" ]; then
- define_bool CONFIG_FB_TGA y
+ if [ "$CONFIG_HP300" = "y" ]; then
+ define_bool CONFIG_FB_HP300 y
+ fi
+ # I used CONFIG_ARM here because the ARCH construct doesn't seem to work
+ # with xconfig. --pb
+ if [ "$ARCH" = "i386" -o "$ARCH" = "alpha" -o "$ARCH" = "ppc" -o \
+ "$CONFIG_ARM" = "y" ]; then
+ if [ "$CONFIG_ARM" != "y" -o "$CONFIG_ARCH_ACORN" != "y" ] ; then
+ tristate 'VGA chipset support (text only)' CONFIG_FB_VGA
+ fi
+ fi
+ if [ "$ARCH" = "alpha" ]; then
+ tristate 'TGA framebuffer support' CONFIG_FB_TGA
+ fi
+ if [ "$ARCH" = "i386" ]; then
+ bool 'VESA VGA graphics console' CONFIG_FB_VESA
+ define_bool CONFIG_VIDEO_SELECT y
+ tristate 'MDA dual-headed support' CONFIG_FB_MDA
+ fi
+ if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then
+ bool 'SBUS and UPA framebuffers' CONFIG_FB_SBUS
+ if [ "$CONFIG_FB_SBUS" != "n" ]; then
+ if [ "$ARCH" = "sparc64" ]; then
+ bool ' Creator/Creator3D support' CONFIG_FB_CREATOR
+ fi
+ bool ' CGsix (GX,TurboGX) support' CONFIG_FB_CGSIX
+ bool ' BWtwo support' CONFIG_FB_BWTWO
+ bool ' CGthree support' CONFIG_FB_CGTHREE
+ if [ "$ARCH" = "sparc" ]; then
+ bool ' TCX (SS4/SS5 only) support' CONFIG_FB_TCX
+ fi
+ fi
+ fi
+ if [ "$ARCH" = "sparc64" ]; 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
+ fi
+ fi
fi
tristate 'Virtual Frame Buffer support (ONLY FOR TESTING!)' CONFIG_FB_VIRTUAL
bool 'Advanced low level driver options' CONFIG_FBCON_ADVANCED
if [ "$CONFIG_FBCON_ADVANCED" = "y" ]; then
- bool 'Monochrome support' CONFIG_FBCON_MFB
- bool '2 bpp packed pixels support' CONFIG_FBCON_CFB2
- bool '4 bpp packed pixels support' CONFIG_FBCON_CFB4
- bool '8 bpp packed pixels support' CONFIG_FBCON_CFB8
- bool '16 bpp packed pixels support' CONFIG_FBCON_CFB16
- bool '24 bpp packed pixels support' CONFIG_FBCON_CFB24
- bool '32 bpp packed pixels support' CONFIG_FBCON_CFB32
- bool 'Amiga bitplanes support' CONFIG_FBCON_AFB
- bool 'Amiga interleaved bitplanes support' CONFIG_FBCON_ILBM
- bool 'Atari interleaved bitplanes (2 planes) support' CONFIG_FBCON_IPLAN2P2
- bool 'Atari interleaved bitplanes (4 planes) support' CONFIG_FBCON_IPLAN2P4
- bool 'Atari interleaved bitplanes (8 planes) support' CONFIG_FBCON_IPLAN2P8
- bool 'Mac variable bpp packed pixels support' CONFIG_FBCON_MAC
+ tristate 'Monochrome support' CONFIG_FBCON_MFB
+ tristate '2 bpp packed pixels support' CONFIG_FBCON_CFB2
+ tristate '4 bpp packed pixels support' CONFIG_FBCON_CFB4
+ tristate '8 bpp packed pixels support' CONFIG_FBCON_CFB8
+ tristate '16 bpp packed pixels support' CONFIG_FBCON_CFB16
+ tristate '24 bpp packed pixels support' CONFIG_FBCON_CFB24
+ tristate '32 bpp packed pixels support' CONFIG_FBCON_CFB32
+ tristate 'Amiga bitplanes support' CONFIG_FBCON_AFB
+ tristate 'Amiga interleaved bitplanes support' CONFIG_FBCON_ILBM
+ tristate 'Atari interleaved bitplanes (2 planes) support' CONFIG_FBCON_IPLAN2P2
+ tristate 'Atari interleaved bitplanes (4 planes) support' CONFIG_FBCON_IPLAN2P4
+ 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
+ tristate 'VGA characters/attributes support' CONFIG_FBCON_VGA
else
- if [ "$CONFIG_FB_AMIGA" = "y" -o "$CONFIG_FB_AMIGA" = "m" -o \
- "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATARI" = "m" -o \
- "$CONFIG_FB_CYBER" = "y" -o "$CONFIG_FB_CYBER" = "m" -o \
- "$CONFIG_FB_RETINAZ3" = "y" -o "$CONFIG_FB_RETINAZ3" = "m" -o \
- "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_VIRGE" = "m" -o \
- "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_MAC" = "m" -o \
- "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
+ # Guess what we need
+ if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_AMIGA" = "y" -o \
+ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_CYBER" = "y" -o \
+ "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_RETINAZ3" = "y" -o \
+ "$CONFIG_FB_VIRGE" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
+ "$CONFIG_FB_BWTWO" = "y" -o "$CONFIG_FB_CLGEN" = "y" ]; then
define_bool CONFIG_FBCON_MFB y
+ else
+ if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_AMIGA" = "m" -o \
+ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_CYBER" = "m" -o \
+ "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_RETINAZ3" = "m" -o \
+ "$CONFIG_FB_VIRGE" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
+ "$CONFIG_FB_BWTWO" = "m" -o "$CONFIG_FB_CLGEN" = "m" ]; then
+ define_bool CONFIG_FBCON_MFB m
+ fi
fi
- if [ "$CONFIG_FB_AMIGA" = "y" -o "$CONFIG_FB_AMIGA" = "m" ]; then
- define_bool CONFIG_FBCON_ILBM y
+ if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
+ "$CONFIG_FB_VIRTUAL" = "y" ]; then
+ define_bool CONFIG_FBCON_CFB2 y
+ define_bool CONFIG_FBCON_CFB4 y
+ else
+ if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_MAC" = "m" -o \
+ "$CONFIG_FB_VIRTUAL" = "m" ]; then
+ define_bool CONFIG_FBCON_CFB2 m
+ define_bool CONFIG_FBCON_CFB4 m
+ fi
+ fi
+ if [ "$CONFIG_FB_ACORN" = "y" -o "$CONFIG_FB_ATARI" = "y" -o \
+ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
+ "$CONFIG_FB_OF" = "y" -o "$CONFIG_FB_TGA" = "y" -o \
+ "$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
+ "$CONFIG_FB_TCX" = "y" -o "$CONFIG_FB_CGTHREE" = "y" -o \
+ "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" ]; then
+ define_bool CONFIG_FBCON_CFB8 y
+ else
+ if [ "$CONFIG_FB_ACORN" = "m" -o "$CONFIG_FB_ATARI" = "m" -o \
+ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_MAC" = "y" -o \
+ "$CONFIG_FB_OF" = "m" -o "$CONFIG_FB_TGA" = "m" -o \
+ "$CONFIG_FB_VESA" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
+ "$CONFIG_FB_TCX" = "m" -o "$CONFIG_FB_CGTHREE" = "m" -o \
+ "$CONFIG_FB_CONTROL" = "m" ]; then
+ define_bool CONFIG_FBCON_CFB8 m
+ fi
+ fi
+ if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \
+ "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_VESA" = "y" -o \
+ "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_TBOX" = "y" -o \
+ "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" ]; then
+ define_bool CONFIG_FBCON_CFB16 y
+ else
+ if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
+ "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VESA" = "m" -o \
+ "$CONFIG_FB_VIRTUAL" = "m" -o "$CONFIG_FB_TBOX" = "m" -o \
+ "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" ]; then
+ define_bool CONFIG_FBCON_CFB16 m
+ fi
+ fi
+ if [ "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
+ "$CONFIG_FB_CLGEN" = "y" ]; then
+ define_bool CONFIG_FBCON_CFB24 y
+ else
+ if [ "$CONFIG_FB_ATY" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
+ "$CONFIG_FB_CLGEN" = "m" ]; then
+ define_bool CONFIG_FBCON_CFB24 m
+ fi
+ fi
+ if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATY" = "y" -o \
+ "$CONFIG_FB_VESA" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" -o \
+ "$CONFIG_FB_CONTROL" = "y" -o "$CONFIG_FB_CLGEN" = "y" ]; then
+ define_bool CONFIG_FBCON_CFB32 y
+ else
+ if [ "$CONFIG_FB_ATARI" = "m" -o "$CONFIG_FB_ATY" = "m" -o \
+ "$CONFIG_FB_VESA" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" -o \
+ "$CONFIG_FB_CONTROL" = "m" -o "$CONFIG_FB_CLGEN" = "m" ]; then
+ define_bool CONFIG_FBCON_CFB32 m
+ fi
+ fi
+ if [ "$CONFIG_FB_AMIGA" = "y" ]; then
define_bool CONFIG_FBCON_AFB y
+ define_bool CONFIG_FBCON_ILBM y
+ else
+ if [ "$CONFIG_FB_AMIGA" = "m" ]; then
+ define_bool CONFIG_FBCON_AFB m
+ define_bool CONFIG_FBCON_ILBM m
+ fi
fi
- if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATARI" = "m" ]; then
+ if [ "$CONFIG_FB_ATARI" = "y" ]; then
define_bool CONFIG_FBCON_IPLAN2P2 y
define_bool CONFIG_FBCON_IPLAN2P4 y
define_bool CONFIG_FBCON_IPLAN2P8 y
+# define_bool CONFIG_FBCON_IPLAN2P16 y
+ else
+ if [ "$CONFIG_FB_ATARI" = "m" ]; then
+ define_bool CONFIG_FBCON_IPLAN2P2 m
+ define_bool CONFIG_FBCON_IPLAN2P4 m
+ define_bool CONFIG_FBCON_IPLAN2P8 m
+# define_bool CONFIG_FBCON_IPLAN2P16 m
+ fi
fi
- if [ "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_MAC" = "m" -o \
- "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
+ if [ "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_VIRTUAL" = "y" ]; then
define_bool CONFIG_FBCON_MAC y
- define_bool CONFIG_FBCON_CFB2 y
- define_bool CONFIG_FBCON_CFB4 y
+ else
+ if [ "$CONFIG_FB_MAC" = "m" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
+ define_bool CONFIG_FBCON_MAC m
+ fi
fi
- if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATARI" = "m" -o \
- "$CONFIG_FB_OF" = "y" -o "$CONFIG_FB_OF" = "m" -o \
- "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_MAC" = "m" -o \
- "$CONFIG_FB_TGA" = "y" -o "$CONFIG_FB_TGA" = "m" -o \
- "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
- define_bool CONFIG_FBCON_CFB8 y
+ if [ "$CONFIG_FB_MDA" = "y" -o "$CONFIG_FB_VGA" = "y" ]; then
+ define_bool CONFIG_FBCON_VGA y
+ else
+ if [ "$CONFIG_FB_MDA" = "m" -o "$CONFIG_FB_VGA" = "m" ]; then
+ define_bool CONFIG_FBCON_VGA m
+ fi
fi
- if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATARI" = "m" -o \
- "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_ATY" = "m" -o \
- "$CONFIG_FB_MAC" = "y" -o "$CONFIG_FB_MAC" = "m" -o \
- "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
- define_bool CONFIG_FBCON_CFB16 y
+ fi
+ bool 'Support only 8 pixels wide fonts' CONFIG_FBCON_FONTWIDTH8_ONLY
+ if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then
+ bool 'Sparc console 8x16 font' CONFIG_FONT_SUN8x16
+ if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then
+ bool 'Sparc console 12x22 font (not supported by all drivers)' CONFIG_FONT_SUN12x22
fi
- if [ "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
- define_bool CONFIG_FBCON_CFB24 y
+ bool 'Select other fonts' CONFIG_FBCON_FONTS
+ if [ "$CONFIG_FBCON_FONTS" = "y" ]; then
+ bool ' VGA 8x8 font' CONFIG_FONT_8x8
+ bool ' VGA 8x16 font' CONFIG_FONT_8x16
+ if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then
+ bool ' Mac console 6x11 font (not supported by all drivers)' CONFIG_FONT_6x11
+ fi
+ bool ' Pearl (old m68k) console 8x8 font' CONFIG_FONT_PEARL_8x8
+ bool ' Acorn console 8x8 font' CONFIG_FONT_ACORN_8x8
fi
- if [ "$CONFIG_FB_ATARI" = "y" -o "$CONFIG_FB_ATARI" = "m" -o \
- "$CONFIG_FB_ATY" = "y" -o "$CONFIG_FB_ATY" = "m" -o \
- "$CONFIG_FB_VIRTUAL" = "y" -o "$CONFIG_FB_VIRTUAL" = "m" ]; then
- define_bool CONFIG_FBCON_CFB32 y
+ else
+ bool 'Select compiled-in fonts' CONFIG_FBCON_FONTS
+ if [ "$CONFIG_FBCON_FONTS" = "y" ]; then
+ bool ' VGA 8x8 font' CONFIG_FONT_8x8
+ bool ' VGA 8x16 font' CONFIG_FONT_8x16
+ bool ' Sparc console 8x16 font' CONFIG_FONT_SUN8x16
+ if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then
+ bool ' Sparc console 12x22 font (not supported by all drivers)' CONFIG_FONT_SUN12x22
+ bool ' Mac console 6x11 font (not supported by all drivers)' CONFIG_FONT_6x11
+ fi
+ bool ' Pearl (old m68k) console 8x8 font' CONFIG_FONT_PEARL_8x8
+ bool ' Acorn console 8x8 font' CONFIG_FONT_ACORN_8x8
+ else
+ define_bool CONFIG_FONT_8x8 y
+ define_bool CONFIG_FONT_8x16 y
+ if [ "$CONFIG_MAC" = "y" ]; then
+ if [ "$CONFIG_FBCON_FONTWIDTH8_ONLY" = "n" ]; then
+ define_bool CONFIG_FONT_6x11 y
+ fi
+ fi
+ if [ "$CONFIG_AMIGA" = "y" ]; then
+ define_bool CONFIG_FONT_PEARL_8x8 y
+ fi
+ if [ "$CONFIG_ARM" = "y" ]; then
+ define_bool CONFIG_FONT_ACORN_8x8 y
+ fi
fi
fi
-
- endmenu
fi
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 2349e4720..412754020 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -21,13 +21,55 @@ MOD_LIST_NAME := VIDEO_MODULES
# Frame Buffer Console
+# Nasty trick to make sure all wanted stuff is linked in
+O_TARGET = fbdev.o
+L_OBJS += fbdev.o
+
+ifeq ($(CONFIG_DUMMY_CONSOLE),y)
+ L_OBJS += dummycon.o
+endif
+
+ifeq ($(CONFIG_PROM_CONSOLE),y)
+ L_OBJS += promcon.o promcon_tbl.o
+endif
+
ifeq ($(CONFIG_FB),y)
- L_OBJS += fonts.o font_8x8.o font_8x16.o pearl_8x8.o font_6x11.o
- LX_OBJS += fbcon.o fbcmap.o fbgen.o
+ L_OBJS += fonts.o
+ OX_OBJS += fbcon.o fbcmap.o
+# fbgen is not compiled by default since nobody uses it yet, except clgenfb
+ ifeq ($(CONFIG_FONT_8x8),y)
+ L_OBJS += font_8x8.o
+ endif
+ ifeq ($(CONFIG_FONT_8x16),y)
+ L_OBJS += font_8x16.o
+ endif
+ ifeq ($(CONFIG_FONT_SUN8x16),y)
+ L_OBJS += font_sun8x16.o
+ endif
+ ifeq ($(CONFIG_FONT_SUN12x22),y)
+ L_OBJS += font_sun12x22.o
+ endif
+ ifeq ($(CONFIG_FONT_6x11),y)
+ L_OBJS += font_6x11.o
+ endif
+ ifeq ($(CONFIG_FONT_ACORN_8x8),y)
+ L_OBJS += font_acorn_8x8.o
+ endif
+ ifeq ($(CONFIG_FONT_PEARL_8x8),y)
+ L_OBJS += font_pearl_8x8.o
+ endif
endif
# Frame Buffer Devices
+ifeq ($(CONFIG_FB_ACORN),y)
+L_OBJS += acornfb.o
+else
+ ifeq ($(CONFIG_FB_ACORN),m)
+ M_OBJS += acornfb.o
+ endif
+endif
+
ifeq ($(CONFIG_FB_AMIGA),y)
L_OBJS += amifb.o
else
@@ -52,6 +94,18 @@ ifeq ($(CONFIG_FB_ATY),y)
L_OBJS += atyfb.o
endif
+ifeq ($(CONFIG_FB_CONTROL),y)
+L_OBJS += controlfb.o
+endif
+
+ifeq ($(CONFIG_FB_PLATINUM),y)
+L_OBJS += platinumfb.o
+endif
+
+ifeq ($(CONFIG_FB_CT65550),y)
+L_OBJS += chipsfb.o
+endif
+
ifeq ($(CONFIG_FB_CYBER),y)
L_OBJS += cyberfb.o
else
@@ -64,8 +118,12 @@ ifeq ($(CONFIG_FB_MAC),y)
L_OBJS += macfb.o
endif
+ifeq ($(CONFIG_FB_HP300),y)
+L_OBJS += hpfb.o
+endif
+
ifeq ($(CONFIG_FB_OF),y)
-L_OBJS += offb.o
+L_OBJS += offb.o macmodes.o
endif
ifeq ($(CONFIG_FB_RETINAZ3),y)
@@ -76,6 +134,16 @@ else
endif
endif
+ifeq ($(CONFIG_FB_CLGEN),y)
+L_OBJS += clgenfb.o
+OX_OBJS += fbgen.o
+else
+ ifeq ($(CONFIG_FB_CLGEN),m)
+ M_OBJS += clgenfb.o
+ OX_OBJS += fbgen.o
+ endif
+endif
+
ifeq ($(CONFIG_FB_S3TRIO),y)
L_OBJS += S3triofb.o
else
@@ -86,6 +154,30 @@ endif
ifeq ($(CONFIG_FB_TGA),y)
L_OBJS += tgafb.o
+else
+ ifeq ($(CONFIG_FB_TGA),m)
+ M_OBJS += tgafb.o
+ endif
+endif
+
+ifeq ($(CONFIG_FB_VGA),y)
+L_OBJS += vgafb.o
+else
+ ifeq ($(CONFIG_FB_VGA),m)
+ M_OBJS += vgafb.o
+ endif
+endif
+
+ifeq ($(CONFIG_FB_VESA),y)
+L_OBJS += vesafb.o
+endif
+
+ifeq ($(CONFIG_FB_MDA),y)
+L_OBJS += mdafb.o
+else
+ ifeq ($(CONFIG_FB_MDA),m)
+ M_OBJS += mdafb.o
+ endif
endif
ifeq ($(CONFIG_FB_VIRGE),y)
@@ -96,6 +188,84 @@ else
endif
endif
+ifeq ($(CONFIG_FB_SBUS),y)
+L_OBJS += sbusfb.o
+ ifeq ($(CONFIG_FB_CREATOR),y)
+ L_OBJS += creatorfb.o
+ else
+ ifeq ($(CONFIG_FB_CREATOR),m)
+ M_OBJS += creatorfb.o
+ endif
+ endif
+ ifeq ($(CONFIG_FB_CGSIX),y)
+ L_OBJS += cgsixfb.o
+ else
+ ifeq ($(CONFIG_FB_CGSIX),m)
+ M_OBJS += cgsixfb.o
+ endif
+ endif
+ ifeq ($(CONFIG_FB_BWTWO),y)
+ L_OBJS += bwtwofb.o
+ else
+ ifeq ($(CONFIG_FB_BWTWO),m)
+ M_OBJS += bwtwofb.o
+ endif
+ endif
+ ifeq ($(CONFIG_FB_CGTHREE),y)
+ L_OBJS += cgthreefb.o
+ else
+ ifeq ($(CONFIG_FB_CGTHREE),m)
+ M_OBJS += cgthreefb.o
+ endif
+ endif
+ ifeq ($(CONFIG_FB_TCX),y)
+ L_OBJS += tcxfb.o
+ else
+ ifeq ($(CONFIG_FB_TCX),m)
+ M_OBJS += tcxfb.o
+ endif
+ endif
+else
+ ifeq ($(CONFIG_FB_SBUS),m)
+ M_OBJS += sbusfb.o
+ ifeq ($(CONFIG_FB_CREATOR),y)
+ M_OBJS += creatorfb.o
+ else
+ ifeq ($(CONFIG_FB_CREATOR),m)
+ M_OBJS += creatorfb.o
+ endif
+ endif
+ ifeq ($(CONFIG_FB_CGSIX),y)
+ M_OBJS += cgsixfb.o
+ else
+ ifeq ($(CONFIG_FB_CGSIX),m)
+ M_OBJS += cgsixfb.o
+ endif
+ endif
+ ifeq ($(CONFIG_FB_BWTWO),y)
+ M_OBJS += bwtwofb.o
+ else
+ ifeq ($(CONFIG_FB_BWTWO),m)
+ M_OBJS += bwtwofb.o
+ endif
+ endif
+ ifeq ($(CONFIG_FB_CGTHREE),y)
+ M_OBJS += cgthreefb.o
+ else
+ ifeq ($(CONFIG_FB_CGTHREE),m)
+ M_OBJS += cgthreefb.o
+ endif
+ endif
+ ifeq ($(CONFIG_FB_TCX),y)
+ M_OBJS += tcxfb.o
+ else
+ ifeq ($(CONFIG_FB_TCX),m)
+ M_OBJS += tcxfb.o
+ endif
+ endif
+ endif
+endif
+
ifeq ($(CONFIG_FB_VIRTUAL),y)
L_OBJS += vfb.o
else
@@ -106,70 +276,147 @@ endif
# Generic Low Level Drivers
-ifdef CONFIG_FBCON_AFB
-LX_OBJS += fbcon-afb.o
+ifeq ($(CONFIG_FBCON_AFB),y)
+OX_OBJS += fbcon-afb.o
+else
+ ifeq ($(CONFIG_FBCON_AFB),m)
+ MX_OBJS += fbcon-afb.o
+ endif
endif
-ifdef CONFIG_FBCON_CFB2
-LX_OBJS += fbcon-cfb2.o
+ifeq ($(CONFIG_FBCON_CFB2),y)
+OX_OBJS += fbcon-cfb2.o
+else
+ ifeq ($(CONFIG_FBCON_CFB2),m)
+ MX_OBJS += fbcon-cfb2.o
+ endif
endif
-ifdef CONFIG_FBCON_CFB4
-LX_OBJS += fbcon-cfb4.o
+ifeq ($(CONFIG_FBCON_CFB4),y)
+OX_OBJS += fbcon-cfb4.o
+else
+ ifeq ($(CONFIG_FBCON_CFB4),m)
+ MX_OBJS += fbcon-cfb4.o
+ endif
endif
-ifdef CONFIG_FBCON_CFB8
-LX_OBJS += fbcon-cfb8.o
+ifeq ($(CONFIG_FBCON_CFB8),y)
+OX_OBJS += fbcon-cfb8.o
+else
+ ifeq ($(CONFIG_FBCON_CFB8),m)
+ MX_OBJS += fbcon-cfb8.o
+ endif
endif
-ifdef CONFIG_FBCON_CFB16
-LX_OBJS += fbcon-cfb16.o
+ifeq ($(CONFIG_FBCON_CFB16),y)
+OX_OBJS += fbcon-cfb16.o
+else
+ ifeq ($(CONFIG_FBCON_CFB16),m)
+ MX_OBJS += fbcon-cfb16.o
+ endif
endif
-ifdef CONFIG_FBCON_CFB24
-LX_OBJS += fbcon-cfb24.o
+ifeq ($(CONFIG_FBCON_CFB24),y)
+OX_OBJS += fbcon-cfb24.o
+else
+ ifeq ($(CONFIG_FBCON_CFB24),m)
+ MX_OBJS += fbcon-cfb24.o
+ endif
endif
-ifdef CONFIG_FBCON_CFB32
-LX_OBJS += fbcon-cfb32.o
+ifeq ($(CONFIG_FBCON_CFB32),y)
+OX_OBJS += fbcon-cfb32.o
+else
+ ifeq ($(CONFIG_FBCON_CFB32),m)
+ MX_OBJS += fbcon-cfb32.o
+ endif
endif
-ifdef CONFIG_FBCON_ILBM
-LX_OBJS += fbcon-ilbm.o
+ifeq ($(CONFIG_FBCON_ILBM),y)
+OX_OBJS += fbcon-ilbm.o
+else
+ ifeq ($(CONFIG_FBCON_ILBM),m)
+ MX_OBJS += fbcon-ilbm.o
+ endif
endif
-ifdef CONFIG_FBCON_IPLAN2P2
-LX_OBJS += fbcon-iplan2p2.o
+ifeq ($(CONFIG_FBCON_IPLAN2P2),y)
+OX_OBJS += fbcon-iplan2p2.o
+else
+ ifeq ($(CONFIG_FBCON_IPLAN2P2),m)
+ MX_OBJS += fbcon-iplan2p2.o
+ endif
endif
-ifdef CONFIG_FBCON_IPLAN2P4
-LX_OBJS += fbcon-iplan2p4.o
+ifeq ($(CONFIG_FBCON_IPLAN2P4),y)
+OX_OBJS += fbcon-iplan2p4.o
+else
+ ifeq ($(CONFIG_FBCON_IPLAN2P4),m)
+ MX_OBJS += fbcon-iplan2p4.o
+ endif
+endif
+
+ifeq ($(CONFIG_FBCON_IPLAN2P8),y)
+OX_OBJS += fbcon-iplan2p8.o
+else
+ ifeq ($(CONFIG_FBCON_IPLAN2P8),m)
+ MX_OBJS += fbcon-iplan2p8.o
+ endif
endif
-ifdef CONFIG_FBCON_IPLAN2P8
-LX_OBJS += fbcon-iplan2p8.o
+ifeq ($(CONFIG_FBCON_IPLAN2P16),y)
+OX_OBJS += fbcon-iplan2p16.o
+else
+ ifeq ($(CONFIG_FBCON_IPLAN2P16),m)
+ MX_OBJS += fbcon-iplan2p16.o
+ endif
+endif
+
+ifeq ($(CONFIG_FBCON_MAC),y)
+OX_OBJS += fbcon-mac.o
+else
+ ifeq ($(CONFIG_FBCON_MAC),m)
+ MX_OBJS += fbcon-mac.o
+ endif
endif
-ifdef CONFIG_FBCON_MAC
-LX_OBJS += fbcon-mac.o
+ifeq ($(CONFIG_FBCON_MFB),y)
+OX_OBJS += fbcon-mfb.o
+else
+ ifeq ($(CONFIG_FBCON_MFB),m)
+ MX_OBJS += fbcon-mfb.o
+ endif
endif
-ifdef CONFIG_FBCON_MFB
-LX_OBJS += fbcon-mfb.o
+ifeq ($(CONFIG_FBCON_VGA),y)
+OX_OBJS += fbcon-vga.o
+else
+ ifeq ($(CONFIG_FBCON_VGA),m)
+ MX_OBJS += fbcon-vga.o
+ endif
endif
-# GSP Console
ifdef CONFIG_AMIGA_GSP
-L_OBJS := $(L_OBJS) gspcon.o gspcore.o
+L_OBJS += gspcon.o gspcore.o
endif
# VGA Text Console
-ifdef CONFIG_ABSTRACT_CONSOLE
ifdef CONFIG_VGA_CONSOLE
-L_OBJS := $(L_OBJS) vgacon.o
+L_OBJS += vgacon.o
endif
+
+# Newport Text Console
+
+ifdef CONFIG_SGI
+L_OBJS := $(L_OBJS) newport_con.o
+endif
+
+# G364 Console for Mips Magnum 4000 / Olivetti M700-10
+
+ifdef CONFIG_VIDEO_G364
+L_OBJS := $(L_OBJS) g364fb.o
endif
include $(TOPDIR)/Rules.make
@@ -177,3 +424,10 @@ include $(TOPDIR)/Rules.make
gspcore.c: gspcore.gsp
$(GSPA) $< > $*.hex
$(GSPH2C) $*.hex > gspcore.c
+
+promcon_tbl.c: prom.uni
+ ../char/conmakehash prom.uni | \
+ sed -e '/#include <[^>]*>/p' -e 's/types/init/' \
+ -e 's/dfont\(_uni.*\]\)/promfont\1 __initdata/' > promcon_tbl.c
+
+promcon_tbl.o: promcon_tbl.c $(TOPDIR)/include/linux/types.h
diff --git a/drivers/video/S3triofb.c b/drivers/video/S3triofb.c
index 16c0b888a..eb94dec73 100644
--- a/drivers/video/S3triofb.c
+++ b/drivers/video/S3triofb.c
@@ -24,8 +24,8 @@
*/
#include <linux/config.h>
-#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/module.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/mm.h>
@@ -36,11 +36,18 @@
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/init.h>
+#include <linux/selection.h>
#include <asm/io.h>
#include <asm/prom.h>
+#include <asm/pci-bridge.h>
#include <linux/pci.h>
+#ifdef CONFIG_FB_COMPAT_XPMAC
+#include <asm/vc_ioctl.h>
+#endif
+#include "fbcon.h"
#include "fbcon-cfb8.h"
+#include "s3blit.h"
#define mem_in8(addr) in_8((void *)(addr))
@@ -60,7 +67,7 @@ static struct display disp;
static struct fb_info fb_info;
static struct { u_char red, green, blue, pad; } palette[256];
static char s3trio_name[16] = "S3Trio ";
-
+static char *s3trio_base;
static struct fb_fix_screeninfo fb_fix;
static struct fb_var_screeninfo fb_var = { 0, };
@@ -70,10 +77,8 @@ static struct fb_var_screeninfo fb_var = { 0, };
* Interface used by the world
*/
-void of_video_setup(char *options, int *ints);
-
-static int s3trio_open(struct fb_info *info);
-static int s3trio_release(struct fb_info *info);
+static int s3trio_open(struct fb_info *info, int user);
+static int s3trio_release(struct fb_info *info, int user);
static int s3trio_get_fix(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info);
static int s3trio_get_var(struct fb_var_screeninfo *var, int con,
@@ -89,30 +94,24 @@ static int s3trio_pan_display(struct fb_var_screeninfo *var, int con,
static int s3trio_ioctl(struct inode *inode, struct file *file, u_int cmd,
u_long arg, int con, struct fb_info *info);
-#ifdef CONFIG_FB_COMPAT_XPMAC
-extern struct vc_mode display_info;
-extern struct fb_info *console_fb_info;
-extern int (*console_setmode_ptr)(struct vc_mode *, int);
-extern int (*console_set_cmap_ptr)(struct fb_cmap *, int, int,
- struct fb_info *);
-static int s3trio_console_setmode(struct vc_mode *mode, int doit);
-#endif /* CONFIG_FB_COMPAT_XPMAC */
/*
* Interface to the low level console driver
*/
-unsigned long s3trio_fb_init(unsigned long mem_start);
+void 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);
+#if 0
static int s3triofbcon_setcmap(struct fb_cmap *cmap, int con);
+#endif
/*
* Text console acceleration
*/
-#ifdef CONFIG_FBCON_CFB8
+#ifdef FBCON_HAS_CFB8
static struct display_switch fbcon_trio8;
#endif
@@ -138,12 +137,12 @@ static int s3trio_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
u_int *transp, struct fb_info *info);
static int s3trio_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
u_int transp, struct fb_info *info);
-static void do_install_cmap(int con);
+static void do_install_cmap(int con, struct fb_info *info);
static struct fb_ops s3trio_ops = {
s3trio_open, s3trio_release, s3trio_get_fix, s3trio_get_var, s3trio_set_var,
- s3trio_get_cmap, s3trio_set_cmap, s3trio_pan_display, NULL, s3trio_ioctl
+ s3trio_get_cmap, s3trio_set_cmap, s3trio_pan_display, s3trio_ioctl
};
@@ -151,7 +150,7 @@ static struct fb_ops s3trio_ops = {
* Open/Release the frame buffer device
*/
-static int s3trio_open(struct fb_info *info)
+static int s3trio_open(struct fb_info *info, int user)
{
/*
* Nothing, only a usage count for the moment
@@ -161,7 +160,7 @@ static int s3trio_open(struct fb_info *info)
return(0);
}
-static int s3trio_release(struct fb_info *info)
+static int s3trio_release(struct fb_info *info, int user)
{
MOD_DEC_USE_COUNT;
return(0);
@@ -200,11 +199,16 @@ static int s3trio_set_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
if (var->xres > fb_var.xres || var->yres > fb_var.yres ||
- var->xres_virtual > fb_var.xres_virtual ||
- var->yres_virtual > fb_var.yres_virtual ||
- var->bits_per_pixel > fb_var.bits_per_pixel ||
- var->nonstd || var->vmode != FB_VMODE_NONINTERLACED)
+ var->bits_per_pixel > fb_var.bits_per_pixel )
+ /* || var->nonstd || var->vmode != FB_VMODE_NONINTERLACED) */
return -EINVAL;
+ if (var->xres_virtual > fb_var.xres_virtual) {
+ outw(IO_OUT16VAL((var->xres_virtual /8) & 0xff, 0x13), 0x3d4);
+ outw(IO_OUT16VAL(((var->xres_virtual /8 ) & 0x300) >> 3, 0x51), 0x3d4);
+ fb_var.xres_virtual = var->xres_virtual;
+ fb_fix.line_length = var->xres_virtual;
+ }
+ fb_var.yres_virtual = var->yres_virtual;
memcpy(var, &fb_var, sizeof(fb_var));
return 0;
}
@@ -219,12 +223,25 @@ static int s3trio_set_var(struct fb_var_screeninfo *var, int con,
static int s3trio_pan_display(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
- if (var->xoffset || var->yoffset)
+ unsigned int base;
+
+ if (var->xoffset > (var->xres_virtual - var->xres))
return -EINVAL;
- else
- return 0;
+ if (var->yoffset > (var->yres_virtual - var->yres))
+ return -EINVAL;
+
+ fb_var.xoffset = var->xoffset;
+ fb_var.yoffset = var->yoffset;
+
+ base = var->yoffset * fb_fix.line_length + var->xoffset;
+
+ outw(IO_OUT16VAL((base >> 8) & 0xff, 0x0c),0x03D4);
+ outw(IO_OUT16VAL(base & 0xff, 0x0d),0x03D4);
+ outw(IO_OUT16VAL((base >> 16) & 0xf, 0x69),0x03D4);
+ return 0;
}
+
/*
* Get the Colormap
*/
@@ -238,7 +255,7 @@ static int s3trio_get_cmap(struct fb_cmap *cmap, int kspc, int con,
else if (fb_display[con].cmap.len) /* non default colormap? */
fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
else
- fb_copy_cmap(fb_default_cmap(fb_display[con].var.bits_per_pixel),
+ fb_copy_cmap(fb_default_cmap(1 << fb_display[con].var.bits_per_pixel),
cmap, kspc ? 0 : 2);
return 0;
}
@@ -273,7 +290,17 @@ static int s3trio_ioctl(struct inode *inode, struct file *file, u_int cmd,
return -EINVAL;
}
-__initfunc(int s3trio_resetaccel(void)) {
+__initfunc(void s3triofb_init(void))
+{
+#ifdef __powerpc__
+ /* We don't want to be called like this. */
+ /* We rely on Open Firmware (offb) instead. */
+#else /* !__powerpc__ */
+ /* To be merged with cybervision */
+#endif /* !__powerpc__ */
+}
+
+__initfunc(void s3trio_resetaccel(void)) {
#define EC01_ENH_ENB 0x0005
@@ -314,18 +341,15 @@ __initfunc(int s3trio_resetaccel(void)) {
outw(0xffff, 0xaae8); /* Enable all planes */
outw(0xffff, 0xaae8); /* Enable all planes */
outw( MF_PIX_CONTROL | MFA_SRC_FOREGR_MIX, 0xbee8);
-
}
-__initfunc(int s3trio_init(void)) {
+__initfunc(int s3trio_init(struct device_node *dp)) {
u_char bus, dev;
unsigned int t32;
unsigned short cmd;
- int i;
- bus=0;
- dev=(3<<3);
+ pci_device_loc(dp,&bus,&dev);
pcibios_read_config_dword(bus, dev, PCI_VENDOR_ID, &t32);
if(t32 == (PCI_DEVICE_ID_S3_TRIO << 16) + PCI_VENDOR_ID_S3) {
pcibios_read_config_dword(bus, dev, PCI_BASE_ADDRESS_0, &t32);
@@ -351,16 +375,16 @@ __initfunc(int s3trio_init(void)) {
outw(IO_OUT16VAL(0x48, 0x38),0x03D4);
outw(IO_OUT16VAL(0xA0, 0x39),0x03D4);
outb(0x33,0x3d4);
- outw(IO_OUT16VAL( inb(0x3d5) & ~(0x2 |
- 0x10 | 0x40) , 0x33),0x3d4);
+ outw(IO_OUT16VAL((inb(0x3d5) & ~(0x2 | 0x10 | 0x40)) |
+ 0x20, 0x33), 0x3d4);
- outw(IO_OUT16VAL(0x6,0x8), 0x3c4);
+ outw(IO_OUT16VAL(0x6, 0x8), 0x3c4);
/* switch to MMIO only mode */
- outb(0x58,0x3d4);
- outw(IO_OUT16VAL(inb(0x3d5) | 3 | 0x10,0x58),0x3d4);
- outw(IO_OUT16VAL(8,0x53),0x3d4);
+ outb(0x58, 0x3d4);
+ outw(IO_OUT16VAL(inb(0x3d5) | 3 | 0x10, 0x58), 0x3d4);
+ outw(IO_OUT16VAL(8, 0x53), 0x3d4);
/* switch off I/O accesses */
@@ -368,6 +392,7 @@ __initfunc(int s3trio_init(void)) {
pcibios_write_config_word(bus, dev, PCI_COMMAND,
PCI_COMMAND_IO | PCI_COMMAND_MEMORY);
#endif
+ return 1;
}
return 0;
@@ -379,18 +404,12 @@ __initfunc(int s3trio_init(void)) {
* We heavily rely on OF for the moment. This needs fixing.
*/
-__initfunc(unsigned long s3trio_fb_init(unsigned long mem_start))
+__initfunc(void s3triofb_init_of(struct device_node *dp))
{
- struct device_node *dp;
- int i, err, *pp, len;
- unsigned *up, address;
+ int i, *pp, len;
+ unsigned long address;
u_long *CursorBase;
- if (!prom_display_paths[0])
- return mem_start;
- if (!(dp = find_path_device(prom_display_paths[0])))
- return mem_start;
-
strncat(s3trio_name, dp->name, sizeof(s3trio_name));
s3trio_name[sizeof(s3trio_name)-1] = '\0';
strcpy(fb_fix.id, s3trio_name);
@@ -398,19 +417,19 @@ __initfunc(unsigned long s3trio_fb_init(unsigned long mem_start))
if((pp = (int *)get_property(dp, "vendor-id", &len)) != NULL
&& *pp!=PCI_VENDOR_ID_S3) {
printk("%s: can't find S3 Trio board\n", dp->full_name);
- return mem_start;
+ return;
}
if((pp = (int *)get_property(dp, "device-id", &len)) != NULL
&& *pp!=PCI_DEVICE_ID_S3_TRIO) {
printk("%s: can't find S3 Trio board\n", dp->full_name);
- return mem_start;
+ return;
}
if ((pp = (int *)get_property(dp, "depth", &len)) != NULL
&& len == sizeof(int) && *pp != 8) {
printk("%s: can't use depth = %d\n", dp->full_name, *pp);
- return mem_start;
+ return;
}
if ((pp = (int *)get_property(dp, "width", &len)) != NULL
&& len == sizeof(int))
@@ -425,45 +444,51 @@ __initfunc(unsigned long s3trio_fb_init(unsigned long mem_start))
fb_fix.line_length = fb_var.xres_virtual;
fb_fix.smem_len = fb_fix.line_length*fb_var.yres;
- s3trio_init();
- address=0xc6000000;
- fb_fix.smem_start = ioremap(address,64*1024*1024);
+ s3trio_init(dp);
+ address = 0xc6000000;
+ s3trio_base = ioremap(address,64*1024*1024);
+ fb_fix.smem_start = (char *)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_len = 0x1000000;
+ fb_fix.xpanstep = 1;
+ fb_fix.ypanstep = 1;
s3trio_resetaccel();
- mem_out8(0x30,fb_fix.smem_start+0x1008000 + 0x03D4);
- mem_out8(0x2d,fb_fix.smem_start+0x1008000 + 0x03D4);
- mem_out8(0x2e,fb_fix.smem_start+0x1008000 + 0x03D4);
+ mem_out8(0x30, s3trio_base+0x1008000 + 0x03D4);
+ mem_out8(0x2d, s3trio_base+0x1008000 + 0x03D4);
+ mem_out8(0x2e, s3trio_base+0x1008000 + 0x03D4);
- mem_out8(0x50,fb_fix.smem_start+0x1008000 + 0x03D4);
+ mem_out8(0x50, s3trio_base+0x1008000 + 0x03D4);
/* disable HW cursor */
- mem_out8(0x39,fb_fix.smem_start+0x1008000 + 0x03D4);
- mem_out8(0xa0,fb_fix.smem_start+0x1008000 + 0x03D5);
+ mem_out8(0x39, s3trio_base+0x1008000 + 0x03D4);
+ mem_out8(0xa0, s3trio_base+0x1008000 + 0x03D5);
- mem_out8(0x45,fb_fix.smem_start+0x1008000 + 0x03D4);
- mem_out8(0,fb_fix.smem_start+0x1008000 + 0x03D5);
+ mem_out8(0x45, s3trio_base+0x1008000 + 0x03D4);
+ mem_out8(0, s3trio_base+0x1008000 + 0x03D5);
- mem_out8(0x4e,fb_fix.smem_start+0x1008000 + 0x03D4);
- mem_out8(0,fb_fix.smem_start+0x1008000 + 0x03D5);
+ mem_out8(0x4e, s3trio_base+0x1008000 + 0x03D4);
+ mem_out8(0, s3trio_base+0x1008000 + 0x03D5);
- mem_out8(0x4f,fb_fix.smem_start+0x1008000 + 0x03D4);
- mem_out8(0,fb_fix.smem_start+0x1008000 + 0x03D5);
+ mem_out8(0x4f, s3trio_base+0x1008000 + 0x03D4);
+ mem_out8(0, s3trio_base+0x1008000 + 0x03D5);
/* init HW cursor */
- CursorBase=(u_long *)(fb_fix.smem_start + 2*1024*1024 - 0x400);
- for (i=0; i < 8; i++) {
+ CursorBase = (u_long *)(s3trio_base + 2*1024*1024 - 0x400);
+ for (i = 0; i < 8; i++) {
*(CursorBase +(i*4)) = 0xffffff00;
*(CursorBase+1+(i*4)) = 0xffff0000;
*(CursorBase+2+(i*4)) = 0xffff0000;
*(CursorBase+3+(i*4)) = 0xffff0000;
}
- for (i=8; i < 64; i++) {
+ for (i = 8; i < 64; i++) {
*(CursorBase +(i*4)) = 0xffff0000;
*(CursorBase+1+(i*4)) = 0xffff0000;
*(CursorBase+2+(i*4)) = 0xffff0000;
@@ -471,34 +496,43 @@ __initfunc(unsigned long s3trio_fb_init(unsigned long mem_start))
}
- mem_out8(0x4c,fb_fix.smem_start+0x1008000 + 0x03D4);
- mem_out8(((2*1024 - 1)&0xf00)>>8,fb_fix.smem_start+0x1008000 + 0x03D5);
+ mem_out8(0x4c, s3trio_base+0x1008000 + 0x03D4);
+ mem_out8(((2*1024 - 1)&0xf00)>>8, s3trio_base+0x1008000 + 0x03D5);
+
+ mem_out8(0x4d, s3trio_base+0x1008000 + 0x03D4);
+ mem_out8((2*1024 - 1) & 0xff, s3trio_base+0x1008000 + 0x03D5);
- mem_out8(0x4d,fb_fix.smem_start+0x1008000 + 0x03D4);
- mem_out8((2*1024 - 1) & 0xff,fb_fix.smem_start+0x1008000 + 0x03D5);
+ mem_out8(0x45, s3trio_base+0x1008000 + 0x03D4);
+ mem_in8(s3trio_base+0x1008000 + 0x03D4);
- mem_out8(0x45,fb_fix.smem_start+0x1008000 + 0x03D4);
- mem_in8(fb_fix.smem_start+0x1008000 + 0x03D4);
+ mem_out8(0x4a, s3trio_base+0x1008000 + 0x03D4);
+ mem_out8(0x80, s3trio_base+0x1008000 + 0x03D5);
+ mem_out8(0x80, s3trio_base+0x1008000 + 0x03D5);
+ mem_out8(0x80, s3trio_base+0x1008000 + 0x03D5);
- mem_out8(0x4a,fb_fix.smem_start+0x1008000 + 0x03D4);
- mem_out8(0x80,fb_fix.smem_start+0x1008000 + 0x03D5);
- mem_out8(0x80,fb_fix.smem_start+0x1008000 + 0x03D5);
- mem_out8(0x80,fb_fix.smem_start+0x1008000 + 0x03D5);
+ mem_out8(0x4b, s3trio_base+0x1008000 + 0x03D4);
+ mem_out8(0x00, s3trio_base+0x1008000 + 0x03D5);
+ mem_out8(0x00, s3trio_base+0x1008000 + 0x03D5);
+ mem_out8(0x00, s3trio_base+0x1008000 + 0x03D5);
- mem_out8(0x4b,fb_fix.smem_start+0x1008000 + 0x03D4);
- mem_out8(0x00,fb_fix.smem_start+0x1008000 + 0x03D5);
- mem_out8(0x00,fb_fix.smem_start+0x1008000 + 0x03D5);
- mem_out8(0x00,fb_fix.smem_start+0x1008000 + 0x03D5);
+ mem_out8(0x45, s3trio_base+0x1008000 + 0x03D4);
+ mem_out8(0, s3trio_base+0x1008000 + 0x03D5);
- mem_out8(0x45,fb_fix.smem_start+0x1008000 + 0x03D4);
- mem_out8(0,fb_fix.smem_start+0x1008000 + 0x03D5);
+ /* setup default color table */
+
+ for(i = 0; i < 16; i++) {
+ int j = color_table[i];
+ palette[i].red=default_red[j];
+ palette[i].green=default_grn[j];
+ palette[i].blue=default_blu[j];
+ }
s3trio_setcolreg(255, 56, 100, 160, 0, NULL /* not used */);
s3trio_setcolreg(254, 0, 0, 0, 0, NULL /* not used */);
- memset((char *)fb_fix.smem_start,0,640*480);
+ memset((char *)s3trio_base, 0, 640*480);
#if 0
- Trio_RectFill(0,0,90,90,7,1);
+ Trio_RectFill(0, 0, 90, 90, 7, 1);
#endif
fb_fix.visual = FB_VISUAL_PSEUDOCOLOR ;
@@ -512,7 +546,8 @@ __initfunc(unsigned long s3trio_fb_init(unsigned long mem_start))
fb_var.nonstd = 0;
fb_var.activate = 0;
fb_var.height = fb_var.width = -1;
- fb_var.accel = 5;
+ fb_var.accel_flags = FB_ACCELF_TEXT;
+#warning FIXME: always obey fb_var.accel_flags
fb_var.pixclock = 1;
fb_var.left_margin = fb_var.right_margin = 0;
fb_var.upper_margin = fb_var.lower_margin = 0;
@@ -524,7 +559,7 @@ __initfunc(unsigned long s3trio_fb_init(unsigned long mem_start))
disp.cmap.start = 0;
disp.cmap.len = 0;
disp.cmap.red = disp.cmap.green = disp.cmap.blue = disp.cmap.transp = NULL;
- disp.screen_base = fb_fix.smem_start;
+ disp.screen_base = s3trio_base;
disp.visual = fb_fix.visual;
disp.type = fb_fix.type;
disp.type_aux = fb_fix.type_aux;
@@ -533,11 +568,15 @@ __initfunc(unsigned long s3trio_fb_init(unsigned long mem_start))
disp.line_length = fb_fix.line_length;
disp.can_soft_blank = 1;
disp.inverse = 0;
-#ifdef CONFIG_FBCON_CFB8
- disp.dispsw = &fbcon_trio8;
+#ifdef FBCON_HAS_CFB8
+ if (fb_var.accel_flags & FB_ACCELF_TEXT)
+ disp.dispsw = &fbcon_trio8;
+ else
+ disp.dispsw = &fbcon_cfb8;
#else
disp.dispsw = NULL;
#endif
+ disp.scrollmode = fb_var.accel_flags & FB_ACCELF_TEXT ? 0 : SCROLL_YREDRAW;
strcpy(fb_info.modename, "Trio64 ");
strncat(fb_info.modename, dp->full_name, sizeof(fb_info.modename));
@@ -570,19 +609,14 @@ __initfunc(unsigned long s3trio_fb_init(unsigned long mem_start))
display_info.cmap_adr_address = address + 0x1008000 + 0x3c8;
display_info.cmap_data_address = address + 0x1008000 + 0x3c9;
console_fb_info = &fb_info;
- console_setmode_ptr = s3trio_console_setmode;
- console_set_cmap_ptr = s3trio_set_cmap;
}
#endif /* CONFIG_FB_COMPAT_XPMAC) */
- err = register_framebuffer(&fb_info);
- if (err < 0)
- return mem_start;
+ if (register_framebuffer(&fb_info) < 0)
+ return;
printk("fb%d: S3 Trio frame buffer device on %s\n",
GET_FB_IDX(fb_info.node), dp->full_name);
-
- return mem_start;
}
@@ -595,7 +629,7 @@ static int s3triofbcon_switch(int con, struct fb_info *info)
currcon = con;
/* Install new colormap */
- do_install_cmap(con);
+ do_install_cmap(con,info);
return 0;
}
@@ -615,17 +649,23 @@ static int s3triofbcon_updatevar(int con, struct fb_info *info)
static void s3triofbcon_blank(int blank, struct fb_info *info)
{
- /* Nothing */
+ unsigned char x;
+
+ mem_out8(0x1, s3trio_base+0x1008000 + 0x03c4);
+ x = mem_in8(s3trio_base+0x1008000 + 0x03c5);
+ mem_out8((x & (~0x20)) | (blank << 5), s3trio_base+0x1008000 + 0x03c5);
}
/*
* Set the colormap
*/
+#if 0
static int s3triofbcon_setcmap(struct fb_cmap *cmap, int con)
{
return(s3trio_set_cmap(cmap, 1, con, &fb_info));
}
+#endif
/*
@@ -660,16 +700,16 @@ static int s3trio_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
palette[regno].green = green;
palette[regno].blue = blue;
- mem_out8(regno,fb_fix.smem_start+0x1008000 + 0x3c8);
- mem_out8((red & 0xff) >> 2,fb_fix.smem_start+0x1008000 + 0x3c9);
- mem_out8((green & 0xff) >> 2,fb_fix.smem_start+0x1008000 + 0x3c9);
- mem_out8((blue & 0xff) >> 2,fb_fix.smem_start+0x1008000 + 0x3c9);
+ mem_out8(regno,s3trio_base+0x1008000 + 0x3c8);
+ mem_out8((red & 0xff) >> 2,s3trio_base+0x1008000 + 0x3c9);
+ mem_out8((green & 0xff) >> 2,s3trio_base+0x1008000 + 0x3c9);
+ mem_out8((blue & 0xff) >> 2,s3trio_base+0x1008000 + 0x3c9);
return 0;
}
-static void do_install_cmap(int con)
+static void do_install_cmap(int con, struct fb_info *info)
{
if (con != currcon)
return;
@@ -681,48 +721,7 @@ static void do_install_cmap(int con)
&fb_display[con].var, 1, s3trio_setcolreg, &fb_info);
}
-#ifdef CONFIG_FB_COMPAT_XPMAC
-
- /*
- * Backward compatibility mode for Xpmac
- */
-
-static int s3trio_console_setmode(struct vc_mode *mode, int doit)
-{
- int err;
- struct fb_var_screeninfo var;
- struct s3trio_par par;
-
- if (mode->mode <= 0 || mode->mode > VMODE_MAX )
- return -EINVAL;
- par.video_mode = mode->mode;
-
- switch (mode->depth) {
- case 24:
- case 32:
- par.color_mode = CMODE_32;
- break;
- case 16:
- par.color_mode = CMODE_16;
- break;
- case 8:
- case 0: /* (default) */
- par.color_mode = CMODE_8;
- break;
- default:
- return -EINVAL;
- }
- encode_var(&var, &par);
- if ((err = decode_var(&var, &par)))
- return err;
- if (doit)
- s3trio_set_var(&var, currcon, 0);
- return 0;
-}
-
-#endif /* CONFIG_FB_COMPAT_XPMAC */
-
-void s3trio_video_setup(char *options, int *ints) {
+void s3triofb_setup(char *options, int *ints) {
return;
@@ -734,7 +733,7 @@ static void Trio_WaitQueue(u_short fifo) {
do
{
- status = mem_in16(fb_fix.smem_start + 0x1000000 + 0x9AE8);
+ status = mem_in16(s3trio_base + 0x1000000 + 0x9AE8);
} while (!(status & fifo));
}
@@ -745,7 +744,7 @@ static void Trio_WaitBlit(void) {
do
{
- status = mem_in16(fb_fix.smem_start + 0x1000000 + 0x9AE8);
+ status = mem_in16(s3trio_base + 0x1000000 + 0x9AE8);
} while (status & 0x200);
}
@@ -813,18 +812,18 @@ static void Trio_RectFill(u_short x, u_short y, u_short width, u_short height,
static void Trio_MoveCursor(u_short x, u_short y) {
- mem_out8(0x39, fb_fix.smem_start + 0x1008000 + 0x3d4);
- mem_out8(0xa0, fb_fix.smem_start + 0x1008000 + 0x3d5);
+ mem_out8(0x39, s3trio_base + 0x1008000 + 0x3d4);
+ mem_out8(0xa0, s3trio_base + 0x1008000 + 0x3d5);
- mem_out8(0x46, fb_fix.smem_start + 0x1008000 + 0x3d4);
- mem_out8((x & 0x0700) >> 8, fb_fix.smem_start + 0x1008000 + 0x3d5);
- mem_out8(0x47, fb_fix.smem_start + 0x1008000 + 0x3d4);
- mem_out8(x & 0x00ff, fb_fix.smem_start + 0x1008000 + 0x3d5);
+ mem_out8(0x46, s3trio_base + 0x1008000 + 0x3d4);
+ mem_out8((x & 0x0700) >> 8, s3trio_base + 0x1008000 + 0x3d5);
+ mem_out8(0x47, s3trio_base + 0x1008000 + 0x3d4);
+ mem_out8(x & 0x00ff, s3trio_base + 0x1008000 + 0x3d5);
- mem_out8(0x48, fb_fix.smem_start + 0x1008000 + 0x3d4);
- mem_out8((y & 0x0700) >> 8, fb_fix.smem_start + 0x1008000 + 0x3d5);
- mem_out8(0x49, fb_fix.smem_start + 0x1008000 + 0x3d4);
- mem_out8(y & 0x00ff, fb_fix.smem_start + 0x1008000 + 0x3d5);
+ mem_out8(0x48, s3trio_base + 0x1008000 + 0x3d4);
+ mem_out8((y & 0x0700) >> 8, s3trio_base + 0x1008000 + 0x3d5);
+ mem_out8(0x49, s3trio_base + 0x1008000 + 0x3d4);
+ mem_out8(y & 0x00ff, s3trio_base + 0x1008000 + 0x3d5);
}
@@ -833,7 +832,7 @@ static void Trio_MoveCursor(u_short x, u_short y) {
* Text console acceleration
*/
-#ifdef CONFIG_FBCON_CFB8
+#ifdef FBCON_HAS_CFB8
static void fbcon_trio8_bmove(struct display *p, int sy, int sx, int dy,
int dx, int height, int width)
{
@@ -866,7 +865,7 @@ static void fbcon_trio8_putc(struct vc_data *conp, struct display *p, int c,
}
static void fbcon_trio8_putcs(struct vc_data *conp, struct display *p,
- const char *s, int count, int yy, int xx)
+ const unsigned short *s, int count, int yy, int xx)
{
Trio_WaitBlit();
fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
@@ -880,6 +879,7 @@ static void fbcon_trio8_revc(struct display *p, int xx, int yy)
static struct display_switch fbcon_trio8 = {
fbcon_cfb8_setup, fbcon_trio8_bmove, fbcon_trio8_clear, fbcon_trio8_putc,
- fbcon_trio8_putcs, fbcon_trio8_revc
+ fbcon_trio8_putcs, fbcon_trio8_revc, NULL, NULL, fbcon_cfb8_clear_margins,
+ FONTWIDTH(8)
};
#endif
diff --git a/drivers/video/acornfb.c b/drivers/video/acornfb.c
new file mode 100644
index 000000000..52fb4487a
--- /dev/null
+++ b/drivers/video/acornfb.c
@@ -0,0 +1,382 @@
+/*
+ * linux/drivers/video/acorn.c
+ *
+ * Copyright (C) 1998 Russell King
+ *
+ * Frame buffer code for Acorn platforms
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+
+#include <asm/hardware.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#include "fbcon-mfb.h"
+#include "fbcon-cfb2.h"
+#include "fbcon-cfb4.h"
+#include "fbcon-cfb8.h"
+
+#define MAX_VIDC20_PALETTE 256
+#define MAX_VIDC_PALETTE 16
+
+struct acornfb_par {
+ unsigned long screen_base;
+ unsigned int xres;
+ unsigned int yres;
+ unsigned char bits_per_pixel;
+ unsigned int palette_size;
+
+ union {
+ union {
+ struct {
+ unsigned long red:8;
+ unsigned long green:8;
+ unsigned long blue:8;
+ unsigned long ext:4;
+ unsigned long unused:4;
+ } d;
+ unsigned long p;
+ } vidc20[MAX_VIDC20_PALETTE];
+ union {
+ struct {
+ unsigned long red:4;
+ unsigned long green:4;
+ unsigned long blue:4;
+ unsigned long trans:1;
+ unsigned long unused:19;
+ } d;
+ unsigned long p;
+ } vidc[MAX_VIDC_PALETTE];
+ } palette;
+};
+
+static int currcon = 0;
+static struct display disp;
+static struct fb_info fb_info;
+static struct acornfb_par current_par;
+
+static int
+acornfb_open(struct fb_info *info, int user)
+{
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static int
+acornfb_release(struct fb_info *info, int user)
+{
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+static void
+acornfb_encode_var(struct fb_var_screeninfo *var, struct acornfb_par *par)
+{
+ var->xres = par->xres;
+ var->yres = par->yres;
+ var->xres_virtual = par->xres;
+ var->yres_virtual = par->yres;
+ var->xoffset = 0;
+ var->yoffset = 0;
+ var->bits_per_pixel = par->bits_per_pixel;
+ var->grayscale = 0;
+ var->red.offset = 0;
+ var->red.length = 8;
+ var->red.msb_right = 0;
+ var->green.offset = 0;
+ var->green.length = 8;
+ var->green.msb_right = 0;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->blue.msb_right = 0;
+ var->transp.offset = 0;
+ var->transp.length = 4;
+ var->transp.msb_right = 0;
+ var->nonstd = 0;
+ var->activate = FB_ACTIVATE_NOW;
+ var->height = -1;
+ var->width = -1;
+ var->vmode = FB_VMODE_NONINTERLACED;
+ var->pixclock = 1;
+ var->sync = 0;
+ var->left_margin = 0;
+ var->right_margin = 0;
+ var->upper_margin = 0;
+ var->lower_margin = 0;
+ var->hsync_len = 0;
+ var->vsync_len = 0;
+}
+
+static int
+acornfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *info)
+{
+ struct acornfb_par *par = &current_par;
+ unsigned int line_length;
+
+ memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+ strcpy(fix->id, "Acorn");
+
+ line_length = par->xres * par->bits_per_pixel / 8;
+
+ fix->smem_start = (char *)SCREEN2_BASE;
+ fix->smem_len = (((line_length * par->yres) - 1) | (PAGE_SIZE - 1)) + 1;
+ fix->type = FB_TYPE_PACKED_PIXELS;
+ fix->type_aux = 0;
+ fix->visual = FB_VISUAL_PSEUDOCOLOR;
+ fix->xpanstep = 0;
+ fix->ypanstep = 0;
+ fix->ywrapstep = 1;
+ fix->line_length = line_length;
+ fix->accel = FB_ACCEL_NONE;
+
+ return 0;
+}
+
+static int
+acornfb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+{
+ if (con == -1) {
+ acornfb_encode_var(var, &current_par);
+ } else
+ *var = fb_display[con].var;
+ return 0;
+}
+
+static int
+acornfb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *info)
+{
+ return 0;
+}
+
+static void
+acornfb_set_disp(int con)
+{
+ struct fb_fix_screeninfo fix;
+ struct display *display;
+
+ if (con >= 0)
+ display = &fb_display[con];
+ else
+ display = &disp;
+
+ current_par.xres = 8 * ORIG_VIDEO_COLS;
+ current_par.yres = 8 * ORIG_VIDEO_LINES;
+ current_par.bits_per_pixel = 8;
+ current_par.palette_size = MAX_VIDC20_PALETTE;
+
+ acornfb_get_fix(&fix, con, 0);
+
+ acornfb_get_var(&display->var, con, 0);
+
+ display->cmap.start = 0;
+ display->cmap.len = 0;
+ display->cmap.red = NULL;
+ display->cmap.green = NULL;
+ display->cmap.blue = NULL;
+ display->cmap.transp = NULL;
+ display->screen_base = fix.smem_start;
+ display->visual = fix.visual;
+ display->type = fix.type;
+ display->type_aux = fix.type_aux;
+ display->ypanstep = fix.ypanstep;
+ display->ywrapstep = fix.ywrapstep;
+ display->line_length = fix.line_length;
+ display->can_soft_blank = 0;
+ display->inverse = 0;
+
+ outl(SCREEN_START, VDMA_START);
+ outl(SCREEN_START + fix.smem_len - VDMA_XFERSIZE, VDMA_END);
+ outl(SCREEN_START, VDMA_INIT);
+
+ switch (display->var.bits_per_pixel) {
+#ifdef FBCON_HAS_MFB
+ case 1:
+ display->dispsw = &fbcon_mfb;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB2
+ case 2:
+ display->dispsw = &fbcon_cfb2;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB4
+ case 4:
+ display->dispsw = &fbcon_cfb4;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB8
+ case 8:
+ display->dispsw = &fbcon_cfb8;
+ break;
+#endif
+ default:
+ display->dispsw = NULL;
+ break;
+ }
+}
+
+static int
+acornfb_vidc20_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, u_int *trans, struct fb_info *info)
+{
+ if (regno >= current_par.palette_size)
+ return 1;
+ *red = current_par.palette.vidc20[regno].d.red;
+ *green = current_par.palette.vidc20[regno].d.green;
+ *blue = current_par.palette.vidc20[regno].d.blue;
+ *trans = current_par.palette.vidc20[regno].d.ext;
+ return 0;
+}
+
+static int
+acornfb_vidc20_setcolreg(u_int regno, u_int red, u_int green, u_int blue, u_int trans, struct fb_info *info)
+{
+ if (regno >= current_par.palette_size)
+ return 1;
+
+ current_par.palette.vidc20[regno].p = 0;
+ current_par.palette.vidc20[regno].d.red = red;
+ current_par.palette.vidc20[regno].d.green = green;
+ current_par.palette.vidc20[regno].d.blue = blue;
+
+ outl(0x10000000 | regno, VIDC_BASE);
+ outl(current_par.palette.vidc20[regno].p, VIDC_BASE);
+
+ return 0;
+}
+
+static int
+acornfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ int err = 0;
+
+ if (con == currcon)
+ err = fb_get_cmap(cmap, &fb_display[con].var,
+ kspc, acornfb_vidc20_getcolreg, info);
+ else if (fb_display[con].cmap.len)
+ fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+ else
+ fb_copy_cmap(fb_default_cmap(current_par.palette_size),
+ cmap, kspc ? 0 : 2);
+ return err;
+}
+
+static int
+acornfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ int err = 0;
+
+ if (!fb_display[con].cmap.len)
+ err = fb_alloc_cmap(&fb_display[con].cmap,
+ current_par.palette_size, 0);
+ if (!err) {
+ if (con == currcon)
+ err = fb_set_cmap(cmap, &fb_display[con].var,
+ kspc, acornfb_vidc20_setcolreg, info);
+ else
+ fb_copy_cmap(cmap, &fb_display[con].cmap,
+ kspc ? 0 : 1);
+ }
+ return err;
+}
+
+static int
+acornfb_pan_display(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ if (var->xoffset || var->yoffset)
+ return -EINVAL;
+ else
+ return 0;
+}
+
+static int
+acornfb_ioctl(struct inode *ino, struct file *file, unsigned int cmd,
+ unsigned long arg, int con, struct fb_info *info)
+{
+ return -ENOIOCTLCMD;
+}
+
+static struct fb_ops acornfb_ops = {
+ acornfb_open,
+ acornfb_release,
+ acornfb_get_fix,
+ acornfb_get_var,
+ acornfb_set_var,
+ acornfb_get_cmap,
+ acornfb_set_cmap,
+ acornfb_pan_display,
+ acornfb_ioctl
+};
+
+void
+acornfb_setup(char *options, int *ints)
+{
+}
+
+static int
+acornfb_update_var(int con, struct fb_info *info)
+{
+ if (con == currcon) {
+ int off = fb_display[con].var.yoffset *
+ fb_display[con].var.xres_virtual *
+ fb_display[con].var.bits_per_pixel >> 3;
+ unsigned long base;
+
+ base = current_par.screen_base = SCREEN_START + off;
+
+ outl (SCREEN_START + base, VDMA_INIT);
+ }
+
+ return 0;
+}
+
+static int
+acornfb_switch(int con, struct fb_info *info)
+{
+ currcon = con;
+ acornfb_update_var(con, info);
+ return 0;
+}
+
+static void
+acornfb_blank(int blank, struct fb_info *info)
+{
+}
+
+__initfunc(unsigned long
+acornfb_init(unsigned long mem_start))
+{
+ strcpy(fb_info.modename, "Acorn");
+ fb_info.node = -1;
+ fb_info.fbops = &acornfb_ops;
+ fb_info.disp = &disp;
+ fb_info.monspecs.hfmin = 0;
+ fb_info.monspecs.hfmax = 0;
+ fb_info.monspecs.vfmin = 0;
+ fb_info.monspecs.vfmax = 0;
+ fb_info.monspecs.dpms = 0;
+ strcpy(fb_info.fontname, "Acorn8x8");
+ fb_info.changevar = NULL;
+ fb_info.switch_con = acornfb_switch;
+ fb_info.updatevar = acornfb_update_var;
+ fb_info.blank = acornfb_blank;
+
+ acornfb_set_disp(-1);
+ fb_set_cmap(fb_default_cmap(current_par.palette_size), &fb_display[0].var,
+ 1, acornfb_vidc20_setcolreg, &fb_info);
+ register_framebuffer(&fb_info);
+
+ return mem_start;
+}
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 09ff067df..840d23c03 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -52,6 +52,7 @@
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/init.h>
+#include <linux/console.h>
#include <asm/uaccess.h>
#include <asm/system.h>
@@ -579,8 +580,14 @@ static u_short maxfmode, chipset;
#define modx(x,v) ((v) & ((x)-1))
/* if x1 is not a constant, this macro won't make real sense :-) */
+#ifdef __mc68000__
#define DIVUL(x1, x2) ({int res; asm("divul %1,%2,%3": "=d" (res): \
"d" (x2), "d" ((long)((x1)/0x100000000ULL)), "0" ((long)(x1))); res;})
+#else
+/* We know a bit about the numbers, so we can do it this way */
+#define DIVUL(x1, x2) ((((long)((unsigned long long)x1 >> 8) / x2) << 8) + \
+ ((((long)((unsigned long long)x1 >> 8) % x2) << 8) / x2))
+#endif
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
@@ -1153,8 +1160,8 @@ static u_short sprfetchmode[3] = {
void amifb_setup(char *options, int *ints);
-static int amifb_open(struct fb_info *info);
-static int amifb_release(struct fb_info *info);
+static int amifb_open(struct fb_info *info, int user);
+static int amifb_release(struct fb_info *info, int user);
static int amifb_get_fix(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info);
static int amifb_get_var(struct fb_var_screeninfo *var, int con,
@@ -1182,7 +1189,7 @@ static int amifb_set_cursorstate(struct fb_cursorstate *state, int con);
* Interface to the low level console driver
*/
-unsigned long amifb_init(unsigned long mem_start);
+void 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);
@@ -1245,7 +1252,7 @@ extern unsigned short ami_intena_vals[];
static struct fb_ops amifb_ops = {
amifb_open, amifb_release, amifb_get_fix, amifb_get_var,
amifb_set_var, amifb_get_cmap, amifb_set_cmap,
- amifb_pan_display, NULL, amifb_ioctl
+ amifb_pan_display, amifb_ioctl
};
@@ -1370,7 +1377,7 @@ cap_invalid:
* Open/Release the frame buffer device
*/
-static int amifb_open(struct fb_info *info)
+static int amifb_open(struct fb_info *info, int user)
{
/*
* Nothing, only a usage count for the moment
@@ -1380,7 +1387,7 @@ static int amifb_open(struct fb_info *info)
return(0);
}
-static int amifb_release(struct fb_info *info)
+static int amifb_release(struct fb_info *info, int user)
{
MOD_DEC_USE_COUNT;
return(0);
@@ -1479,17 +1486,17 @@ static int amifb_set_var(struct fb_var_screeninfo *var, int con,
display->can_soft_blank = 1;
display->inverse = amifb_inverse;
switch (fix.type) {
-#ifdef CONFIG_FBCON_ILBM
+#ifdef FBCON_HAS_ILBM
case FB_TYPE_INTERLEAVED_PLANES:
display->dispsw = &fbcon_ilbm;
break;
#endif
-#ifdef CONFIG_FBCON_AFB
+#ifdef FBCON_HAS_AFB
case FB_TYPE_PLANES:
display->dispsw = &fbcon_afb;
break;
#endif
-#ifdef CONFIG_FBCON_MFB
+#ifdef FBCON_HAS_MFB
case FB_TYPE_PACKED_PIXELS: /* depth == 1 */
display->dispsw = &fbcon_mfb;
break;
@@ -1706,13 +1713,13 @@ static int amifb_set_cursorstate(struct fb_cursorstate *state, int con)
* Initialisation
*/
-__initfunc(unsigned long amifb_init(unsigned long mem_start))
+__initfunc(void amifb_init(void))
{
- int err, tag, i;
+ int tag, i;
u_long chipptr;
if (!MACH_IS_AMIGA || !AMIGAHW_PRESENT(AMI_VIDEO))
- return mem_start;
+ return;
/*
* TODO: where should we put this? The DMI Resolver doesn't have a
@@ -1723,7 +1730,7 @@ __initfunc(unsigned long amifb_init(unsigned long mem_start))
if (amifb_resolver){
custom.dmacon = DMAF_MASTER | DMAF_RASTER | DMAF_COPPER |
DMAF_BLITTER | DMAF_SPRITE;
- return mem_start;
+ return;
}
#endif
@@ -1794,7 +1801,7 @@ default_chipset:
strcat(amifb_name, "Unknown");
goto default_chipset;
#else /* CONFIG_FB_AMIGA_OCS */
- return mem_start;
+ return;
#endif /* CONFIG_FB_AMIGA_OCS */
break;
}
@@ -1803,9 +1810,13 @@ default_chipset:
* Calculate the Pixel Clock Values for this Machine
*/
- pixclock[TAG_SHRES] = DIVUL(25E9, amiga_eclock); /* SHRES: 35 ns / 28 MHz */
- pixclock[TAG_HIRES] = DIVUL(50E9, amiga_eclock); /* HIRES: 70 ns / 14 MHz */
- pixclock[TAG_LORES] = DIVUL(100E9, amiga_eclock); /* LORES: 140 ns / 7 MHz */
+ {
+ u_long tmp = DIVUL(200E9, amiga_eclock);
+
+ pixclock[TAG_SHRES] = (tmp + 4) / 8; /* SHRES: 35 ns / 28 MHz */
+ pixclock[TAG_HIRES] = (tmp + 2) / 4; /* HIRES: 70 ns / 14 MHz */
+ pixclock[TAG_LORES] = (tmp + 1) / 2; /* LORES: 140 ns / 7 MHz */
+ }
/*
* Replace the Tag Values with the Real Pixel Clock Values
@@ -1848,10 +1859,6 @@ default_chipset:
fb_info.updatevar = &amifbcon_updatevar;
fb_info.blank = &amifbcon_blank;
- err = register_framebuffer(&fb_info);
- if (err < 0)
- return mem_start;
-
chipptr = chipalloc(videomemorysize+
SPRITEMEMSIZE+
DUMMYSPRITEMEMSIZE+
@@ -1894,14 +1901,15 @@ default_chipset:
amifb_set_var(&amifb_default, -1, &fb_info);
+ if (register_framebuffer(&fb_info) < 0)
+ return;
+
printk("fb%d: %s frame buffer device, using %ldK of video memory\n",
GET_FB_IDX(fb_info.node), fb_info.modename,
videomemorysize>>10);
/* TODO: This driver cannot be unloaded yet */
MOD_INC_USE_COUNT;
-
- return mem_start;
}
static int amifbcon_switch(int con, struct fb_info *info)
@@ -2121,7 +2129,7 @@ static int ami_encode_fix(struct fb_fix_screeninfo *fix,
fix->smem_start = (char *)videomemory;
fix->smem_len = videomemorysize;
-#ifdef CONFIG_FBCON_MFB
+#ifdef FBCON_HAS_MFB
if (par->bpp == 1) {
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
@@ -2543,7 +2551,8 @@ static int ami_encode_var(struct fb_var_screeninfo *var,
struct amifb_par *par)
{
u_short clk_shift, line_shift;
- int i;
+
+ memset(var, 0, sizeof(struct fb_var_screeninfo));
clk_shift = par->clk_shift;
line_shift = par->line_shift;
@@ -2626,9 +2635,6 @@ static int ami_encode_var(struct fb_var_screeninfo *var,
if (par->vmode & FB_VMODE_YWRAP)
var->vmode |= FB_VMODE_YWRAP;
- for (i = 0; i < arraysize(var->reserved); i++)
- var->reserved[i] = 0;
-
return 0;
}
@@ -2927,20 +2933,20 @@ static void ami_do_blank(void)
custom.dmacon = DMAF_RASTER | DMAF_SPRITE;
red = green = blue = 0;
if (!IS_OCS && do_blank > 1) {
- switch (do_blank) {
- case 2 : /* suspend vsync */
+ switch (do_blank-1) {
+ case VESA_VSYNC_SUSPEND:
custom.hsstrt = hsstrt2hw(par->hsstrt);
custom.hsstop = hsstop2hw(par->hsstop);
custom.vsstrt = vsstrt2hw(par->vtotal+4);
custom.vsstop = vsstop2hw(par->vtotal+4);
break;
- case 3 : /* suspend hsync */
+ case VESA_HSYNC_SUSPEND:
custom.hsstrt = hsstrt2hw(par->htotal+16);
custom.hsstop = hsstop2hw(par->htotal+16);
custom.vsstrt = vsstrt2hw(par->vsstrt);
custom.vsstop = vsstrt2hw(par->vsstop);
break;
- case 4 : /* powerdown */
+ case VESA_POWERDOWN:
custom.hsstrt = hsstrt2hw(par->htotal+16);
custom.hsstop = hsstop2hw(par->htotal+16);
custom.vsstrt = vsstrt2hw(par->vtotal+4);
@@ -3486,7 +3492,8 @@ static void ami_rebuild_copper(void)
#ifdef MODULE
int init_module(void)
{
- return(amifb_init(NULL));
+ amifb_init();
+ return 0;
}
void cleanup_module(void)
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index ff7aedfe7..a64eaf1fa 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -47,7 +47,6 @@
#define ATAFB_EXT
#define ATAFB_FALCON
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -71,24 +70,12 @@
#include <linux/fb.h>
#include <asm/atarikb.h>
-#ifdef CONFIG_FBCON_CFB8
#include "fbcon-cfb8.h"
-#endif
-#ifdef CONFIG_FBCON_CFB16
#include "fbcon-cfb16.h"
-#endif
-#ifdef CONFIG_FBCON_IPLAN2P2
#include "fbcon-iplan2p2.h"
-#endif
-#ifdef CONFIG_FBCON_IPLAN2P4
#include "fbcon-iplan2p4.h"
-#endif
-#ifdef CONFIG_FBCON_IPLAN2P8
#include "fbcon-iplan2p8.h"
-#endif
-#ifdef CONFIG_FBCON_MFB
#include "fbcon-mfb.h"
-#endif
#define SWITCH_ACIA 0x01 /* modes for switch on OverScan */
@@ -492,6 +479,7 @@ static int tt_encode_fix( struct fb_fix_screeninfo *fix,
fix->ypanstep=1;
fix->ywrapstep=0;
fix->line_length = 0;
+ fix->accel = FB_ACCEL_ATARIBLITT;
return 0;
}
@@ -580,7 +568,8 @@ static int tt_decode_var( struct fb_var_screeninfo *var,
static int tt_encode_var( struct fb_var_screeninfo *var,
struct atafb_par *par )
{
- int linelen, i;
+ int linelen;
+ memset(var, 0, sizeof(struct fb_var_screeninfo));
var->red.offset=0;
var->red.length=4;
var->red.msb_right=0;
@@ -668,8 +657,6 @@ static int tt_encode_var( struct fb_var_screeninfo *var,
var->nonstd=0;
var->activate=0;
var->vmode=FB_VMODE_NONINTERLACED;
- for (i=0; i<arraysize(var->reserved); i++)
- var->reserved[i]=0;
return 0;
}
@@ -816,6 +803,7 @@ static int falcon_encode_fix( struct fb_fix_screeninfo *fix,
fix->xpanstep = 2;
}
fix->line_length = 0;
+ fix->accel = FB_ACCEL_ATARIBLITT;
return 0;
}
@@ -1306,11 +1294,12 @@ static int falcon_encode_var( struct fb_var_screeninfo *var,
struct atafb_par *par )
{
/* !!! only for VGA !!! */
- int linelen, i;
+ int linelen;
int prescale, plen;
int hdb_off, hde_off, base_off;
struct falcon_hw *hw = &par->hw.falcon;
+ memset(var, 0, sizeof(struct fb_var_screeninfo));
/* possible frequencies: 25.175 or 32MHz */
var->pixclock = hw->sync & 0x1 ? fext.t :
hw->vid_control & VCO_CLOCK25 ? f25.t : f32.t;
@@ -1461,8 +1450,6 @@ static int falcon_encode_var( struct fb_var_screeninfo *var,
var->yoffset=0;
var->nonstd=0; /* what is this for? */
var->activate=0;
- for (i=0; i<arraysize(var->reserved); i++)
- var->reserved[i]=0;
return 0;
}
@@ -1654,7 +1641,7 @@ static int falcon_setcolreg( unsigned regno, unsigned red,
(((red & 0xe) >> 1) | ((red & 1) << 3) << 8) |
(((green & 0xe) >> 1) | ((green & 1) << 3) << 4) |
((blue & 0xe) >> 1) | ((blue & 1) << 3);
-#ifdef CONFIG_FBCON_CFB16
+#ifdef FBCON_HAS_CFB16
fbcon_cfb16_cmap[regno] = (red << 11) | (green << 5) | blue;
#endif
}
@@ -1773,6 +1760,7 @@ static int stste_encode_fix( struct fb_fix_screeninfo *fix,
}
fix->ywrapstep = 0;
fix->line_length = 0;
+ fix->accel = FB_ACCEL_ATARIBLITT;
return 0;
}
@@ -1838,7 +1826,8 @@ static int stste_decode_var( struct fb_var_screeninfo *var,
static int stste_encode_var( struct fb_var_screeninfo *var,
struct atafb_par *par )
{
- int linelen, i;
+ int linelen;
+ memset(var, 0, sizeof(struct fb_var_screeninfo));
var->red.offset=0;
var->red.length = ATARIHW_PRESENT(EXTD_SHIFTER) ? 4 : 3;
var->red.msb_right=0;
@@ -1908,8 +1897,6 @@ static int stste_encode_var( struct fb_var_screeninfo *var,
var->nonstd=0;
var->activate=0;
var->vmode=FB_VMODE_NONINTERLACED;
- for (i=0; i<arraysize(var->reserved); i++)
- var->reserved[i]=0;
return 0;
}
@@ -2145,8 +2132,7 @@ static int ext_decode_var( struct fb_var_screeninfo *var,
static int ext_encode_var( struct fb_var_screeninfo *var,
struct atafb_par *par )
{
- int i;
-
+ memset(var, 0, sizeof(struct fb_var_screeninfo));
var->red.offset=0;
var->red.length=(external_pmode == -1) ? external_depth/3 :
(external_vgaiobase ? external_bitspercol : 0);
@@ -2181,8 +2167,6 @@ static int ext_encode_var( struct fb_var_screeninfo *var,
var->nonstd=0;
var->activate=0;
var->vmode=FB_VMODE_NONINTERLACED;
- for (i=0; i<arraysize(var->reserved); i++)
- var->reserved[i]=0;
return 0;
}
@@ -2412,7 +2396,7 @@ do_install_cmap(int con, struct fb_info *info)
* Open/Release the frame buffer device
*/
-static int atafb_open(struct fb_info *info)
+static int atafb_open(struct fb_info *info, int user)
{
/*
* Nothing, only a usage count for the moment
@@ -2422,7 +2406,7 @@ static int atafb_open(struct fb_info *info)
return(0);
}
-static int atafb_release(struct fb_info *info)
+static int atafb_release(struct fb_info *info, int user)
{
MOD_DEC_USE_COUNT;
return(0);
@@ -2470,7 +2454,7 @@ atafb_set_disp(int con, struct fb_info *info)
atafb_get_var(&var, con, info);
if (con == -1)
con=0;
- display->screen_base = (u_char *)fix.smem_start;
+ display->screen_base = fix.smem_start;
display->visual = fix.visual;
display->type = fix.type;
display->type_aux = fix.type_aux;
@@ -2487,17 +2471,17 @@ atafb_set_disp(int con, struct fb_info *info)
switch (fix.type) {
case FB_TYPE_INTERLEAVED_PLANES:
switch (var.bits_per_pixel) {
-#ifdef CONFIG_FBCON_IPLAN2P2
+#ifdef FBCON_HAS_IPLAN2P2
case 2:
display->dispsw = &fbcon_iplan2p2;
break;
#endif
-#ifdef CONFIG_FBCON_IPLAN2P4
+#ifdef FBCON_HAS_IPLAN2P4
case 4:
display->dispsw = &fbcon_iplan2p4;
break;
#endif
-#ifdef CONFIG_FBCON_IPLAN2P8
+#ifdef FBCON_HAS_IPLAN2P8
case 8:
display->dispsw = &fbcon_iplan2p8;
break;
@@ -2506,17 +2490,17 @@ atafb_set_disp(int con, struct fb_info *info)
break;
case FB_TYPE_PACKED_PIXELS:
switch (var.bits_per_pixel) {
-#ifdef CONFIG_FBCON_MFB
+#ifdef FBCON_HAS_MFB
case 1:
display->dispsw = &fbcon_mfb;
break;
#endif
-#ifdef CONFIG_FBCON_CFB8
+#ifdef FBCON_HAS_CFB8
case 8:
display->dispsw = &fbcon_cfb8;
break;
#endif
-#ifdef CONFIG_FBCON_CFB16
+#ifdef FBCON_HAS_CFB16
case 16:
display->dispsw = &fbcon_cfb16;
break;
@@ -2642,7 +2626,7 @@ atafb_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
static struct fb_ops atafb_ops = {
atafb_open, atafb_release, atafb_get_fix, atafb_get_var,
atafb_set_var, atafb_get_cmap, atafb_set_cmap,
- atafb_pan_display, NULL, atafb_ioctl
+ atafb_pan_display, atafb_ioctl
};
static void
@@ -2674,7 +2658,7 @@ check_default_par( int detected_mode )
sprintf(default_name,"default%d",i);
default_par=get_video_mode(default_name);
if (! default_par)
- panic("can't set default video mode\n");
+ panic("can't set default video mode");
var=atafb_predefined[default_par-1];
var.activate = FB_ACTIVATE_TEST;
if (! do_fb_set_var(&var,1))
@@ -2730,15 +2714,14 @@ atafb_blank(int blank, struct fb_info *info)
do_install_cmap(currcon, info);
}
-__initfunc(unsigned long atafb_init(unsigned long mem_start))
+__initfunc(void atafb_init(void))
{
- int err;
int pad;
int detected_mode;
unsigned long mem_req;
if (!MACH_IS_ATARI)
- return mem_start;
+ return;
do {
#ifdef ATAFB_EXT
@@ -2772,7 +2755,7 @@ __initfunc(unsigned long atafb_init(unsigned long mem_start))
#else /* ATAFB_STE */
/* no default driver included */
/* Nobody will ever see this message :-) */
- panic("Cannot initialize video hardware\n");
+ panic("Cannot initialize video hardware");
#endif
} while (0);
@@ -2793,8 +2776,10 @@ __initfunc(unsigned long atafb_init(unsigned long mem_start))
mem_req = default_mem_req + ovsc_offset +
ovsc_addlen;
mem_req = ((mem_req + PAGE_SIZE - 1) & PAGE_MASK) + PAGE_SIZE;
- screen_base = (unsigned long)atari_stram_alloc(mem_req, &mem_start,
- "atafb");
+ screen_base = (unsigned long)atari_stram_alloc(mem_req, NULL,
+ "atafb");
+ if (!screen_base)
+ panic("Cannot allocate screen memory");
memset((char *) screen_base, 0, mem_req);
pad = ((screen_base + PAGE_SIZE-1) & PAGE_MASK) - screen_base;
screen_base+=pad;
@@ -2814,13 +2799,11 @@ __initfunc(unsigned long atafb_init(unsigned long mem_start))
/* Map the video memory (physical address given) to somewhere
* in the kernel address space.
*/
- mem_start = PAGE_ALIGN(mem_start);
external_addr = kernel_map(external_addr, external_len,
- KERNELMAP_NO_COPYBACK, &mem_start);
+ KERNELMAP_NO_COPYBACK, NULL);
if (external_vgaiobase)
external_vgaiobase = kernel_map(external_vgaiobase,
- 0x10000, KERNELMAP_NOCACHE_SER, &mem_start);
- mem_start += PAGE_SIZE;
+ 0x10000, KERNELMAP_NOCACHE_SER, NULL);
screen_base =
real_screen_base = external_addr;
screen_len = external_len & PAGE_MASK;
@@ -2839,26 +2822,24 @@ __initfunc(unsigned long atafb_init(unsigned long mem_start))
do_fb_set_var(&atafb_predefined[default_par-1], 1);
strcat(fb_info.modename, fb_var_names[default_par-1][0]);
- err=register_framebuffer(&fb_info);
- if (err < 0)
- return(err);
-
atafb_get_var(&disp.var, -1, &fb_info);
atafb_set_disp(-1, &fb_info);
+ do_install_cmap(0, &fb_info);
+
+ if (register_framebuffer(&fb_info) < 0)
+ return;
+
printk("Determined %dx%d, depth %d\n",
disp.var.xres, disp.var.yres, disp.var.bits_per_pixel);
if ((disp.var.xres != disp.var.xres_virtual) ||
(disp.var.yres != disp.var.yres_virtual))
printk(" virtual %dx%d\n",
disp.var.xres_virtual, disp.var.yres_virtual);
- do_install_cmap(0, &fb_info);
printk("fb%d: %s frame buffer device, using %dK of video memory\n",
GET_FB_IDX(fb_info.node), fb_info.modename, screen_len>>10);
/* TODO: This driver cannot be unloaded yet */
MOD_INC_USE_COUNT;
-
- return mem_start;
}
/* a strtok which returns empty strings, too */
@@ -3139,7 +3120,8 @@ __initfunc(void atafb_setup( char *options, int *ints ))
#ifdef MODULE
int init_module(void)
{
- return(atafb_init(NULL));
+ atafb_init();
+ return 0;
}
void cleanup_module(void)
diff --git a/drivers/video/aty.h b/drivers/video/aty.h
index 7c9b00ad7..517b500c5 100644
--- a/drivers/video/aty.h
+++ b/drivers/video/aty.h
@@ -223,8 +223,8 @@
#define DP_BKGD_CLR 0x02C0 /* Dword offset 0_B0 */
#define DP_FOG_CLR 0x02C4 /* Dword offset 0_B1 */
#define DP_FRGD_CLR 0x02C4 /* Dword offset 0_B1 */
-#define DP_WRITE_MSK 0x02C8 /* Dword offset 0_B2 */
-#define DP_CHAIN_MSK 0x02CC /* Dword offset 0_B3 */
+#define DP_WRITE_MASK 0x02C8 /* Dword offset 0_B2 */
+#define DP_CHAIN_MASK 0x02CC /* Dword offset 0_B3 */
#define DP_PIX_WIDTH 0x02D0 /* Dword offset 0_B4 */
#define DP_MIX 0x02D4 /* Dword offset 0_B5 */
#define DP_SRC 0x02D8 /* Dword offset 0_B6 */
@@ -238,7 +238,7 @@
#define DP_SET_GUI_ENGINE 0x02FC /* Dword offset 0_BF */
#define CLR_CMP_CLR 0x0300 /* Dword offset 0_C0 */
-#define CLR_CMP_MSK 0x0304 /* Dword offset 0_C1 */
+#define CLR_CMP_MASK 0x0304 /* Dword offset 0_C1 */
#define CLR_CMP_CNTL 0x0308 /* Dword offset 0_C2 */
#define FIFO_STAT 0x0310 /* Dword offset 0_C4 */
@@ -569,7 +569,8 @@
#define PLL_WR_EN 0x02
/* PLL registers */
-#define PLL_MACRO_CNTL 0x01
+#define MPLL_CNTL 0x00
+#define VPLL_CNTL 0x01
#define PLL_REF_DIV 0x02
#define PLL_GEN_CNTL 0x03
#define MCLK_FB_DIV 0x04
@@ -579,7 +580,9 @@
#define VCLK1_FB_DIV 0x08
#define VCLK2_FB_DIV 0x09
#define VCLK3_FB_DIV 0x0A
-#define PLL_XCLK_CNTL 0x0B
+#define PLL_EXT_CNTL 0x0B
+#define DLL_CNTL 0x0C
+#define VFC_CNTL 0x0D
#define PLL_TEST_CTRL 0x0E
#define PLL_TEST_COUNT 0x0F
@@ -688,28 +691,66 @@
/* ATI PCI constants */
#define PCI_ATI_VENDOR_ID 0x1002
-#define PCI_MACH64_GX 0x4758
-#define PCI_MACH64_CX 0x4358
-#define PCI_MACH64_CT 0x4354
-#define PCI_MACH64_ET 0x4554
-#define PCI_MACH64_VT 0x5654
-#define PCI_MACH64_GT 0x4754
+
/* CONFIG_CHIP_ID register constants */
#define CFG_CHIP_TYPE 0x0000FFFF
#define CFG_CHIP_CLASS 0x00FF0000
#define CFG_CHIP_REV 0xFF000000
-#define CFG_CHIP_VERSION 0x07000000
-#define CFG_CHIP_FOUNDRY 0x38000000
-#define CFG_CHIP_REVISION 0xC0000000
+#define CFG_CHIP_MAJOR 0x07000000
+#define CFG_CHIP_FND_ID 0x38000000
+#define CFG_CHIP_MINOR 0xC0000000
+
/* Chip IDs read from CONFIG_CHIP_ID */
-#define MACH64_GX_ID 0xD7
-#define MACH64_CX_ID 0x57
-#define MACH64_CT_ID 0x4354
-#define MACH64_ET_ID 0x4554
-#define MACH64_VT_ID 0x5654
-#define MACH64_GT_ID 0x4754
+
+/* mach64GX family */
+#define GX_CHIP_ID 0xD7 /* mach64GX (ATI888GX00) */
+#define CX_CHIP_ID 0x57 /* mach64CX (ATI888CX00) */
+
+#define GX_PCI_ID 0x4758 /* mach64GX (ATI888GX00) */
+#define CX_PCI_ID 0x4358 /* mach64CX (ATI888CX00) */
+
+/* mach64CT family */
+#define CT_CHIP_ID 0x4354 /* mach64CT (ATI264CT) */
+#define ET_CHIP_ID 0x4554 /* mach64ET (ATI264ET) */
+
+/* mach64CT family / mach64VT class */
+#define VT_CHIP_ID 0x5654 /* mach64VT (ATI264VT) */
+#define VU_CHIP_ID 0x5655 /* mach64VTB (ATI264VTB) */
+
+/* mach64CT family / mach64GT (3D RAGE) class */
+#define LT_CHIP_ID 0x4c54 /* 3D RAGE LT */
+#define LG_CHIP_ID 0x4c47 /* 3D RAGE LG */
+#define GT_CHIP_ID 0x4754 /* 3D RAGE (GT) */
+#define GU_CHIP_ID 0x4755 /* 3D RAGE II/II+ (GTB) */
+#define GB_CHIP_ID 0x4742 /* RAGE PRO, BGA, AGP 1x and 2x */
+#define GD_CHIP_ID 0x4744 /* RAGE PRO, BGA, AGP 1x only */
+#define GI_CHIP_ID 0x4749 /* RAGE PRO, BGA, PCI33 only */
+#define GP_CHIP_ID 0x4750 /* RAGE PRO, PQFP, PCI33, full 3D */
+#define GQ_CHIP_ID 0x4751 /* RAGE PRO, PQFP, PCI33, limited 3D */
+
+
+/* Mach64 major ASIC revisions */
+#define MACH64_ASIC_NEC_VT_A3 0x08
+#define MACH64_ASIC_NEC_VT_A4 0x48
+#define MACH64_ASIC_SGS_VT_A4 0x40
+#define MACH64_ASIC_SGS_VT_B1S1 0x01
+#define MACH64_ASIC_SGS_GT_B1S1 0x01
+#define MACH64_ASIC_SGS_GT_B1S2 0x41
+#define MACH64_ASIC_UMC_GT_B2U1 0x1a
+#define MACH64_ASIC_UMC_GT_B2U2 0x5a
+#define MACH64_ASIC_UMC_VT_B2U3 0x9a
+#define MACH64_ASIC_UMC_GT_B2U3 0x9a
+#define MACH64_ASIC_UMC_R3B_D_P_A1 0x1b
+#define MACH64_ASIC_UMC_R3B_D_P_A2 0x5b
+#define MACH64_ASIC_UMC_R3B_D_P_A3 0x1c
+#define MACH64_ASIC_UMC_R3B_D_P_A4 0x5c
+
+/* Mach64 foundries */
+#define MACH64_FND_SGS 0
+#define MACH64_FND_NEC 1
+#define MACH64_FND_UMC 3
/* Mach64 chip types */
#define MACH64_UNKNOWN 0
@@ -900,24 +941,4 @@
#define MACH64_NUM_CLOCKS 16
#define MACH64_NUM_FREQS 50
-/* Wait until "v" queue entries are free */
-#define aty_WaitQueue(v) { while ((aty_ld_le32(FIFO_STAT) & 0xffff) > \
- ((unsigned short)(0x8000 >> (v)))); }
-
-/* Wait until GP is idle and queue is empty */
-#define aty_WaitIdleEmpty() { aty_WaitQueue(16); \
- while ((aty_ld_le32(GUI_STAT) & 1) != 0); }
-
-#define SKIP_2(_v) ((((_v)<<1)&0xfff8)|((_v)&0x3)|(((_v)&0x80)>>5))
-
-#define MACH64_BIT_BLT(_srcx, _srcy, _dstx, _dsty, _w, _h, _dir) \
-{ \
- aty_WaitQueue(5); \
- aty_st_le32(SRC_Y_X, (((_srcx) << 16) | ((_srcy) & 0x0000ffff))); \
- aty_st_le32(SRC_WIDTH1, (_w)); \
- aty_st_le32(DST_CNTL, (_dir)); \
- aty_st_le32(DST_Y_X, (((_dstx) << 16) | ((_dsty) & 0x0000ffff))); \
- aty_st_le32(DST_HEIGHT_WIDTH, (((_w) << 16) | ((_h) & 0x0000ffff))); \
-}
#endif /* REGMACH64_H */
-
diff --git a/drivers/video/atyfb.c b/drivers/video/atyfb.c
index e1f8b3ef4..7d271bc29 100644
--- a/drivers/video/atyfb.c
+++ b/drivers/video/atyfb.c
@@ -1,7 +1,9 @@
/*
- * linux/drivers/video/atyfb.c -- Frame buffer device for ATI/Open Firmware
+ * linux/drivers/video/atyfb.c -- Frame buffer device for ATI Mach64
*
- * Copyright (C) 1997 Geert Uytterhoeven
+ * Copyright (C) 1997-1998 Geert Uytterhoeven
+ * Copyright (C) 1998 Bernd Harries
+ * Copyright (C) 1998 Eddie C. Dost
*
* This driver is partly based on the PowerMac console driver:
*
@@ -20,6 +22,23 @@
* more details.
*/
+/******************************************************************************
+
+ TODO:
+
+ (ecd):
+
+ - fix initialization of cursor timer.
+
+ - add code to support cursor on all cards and all ramdacs.
+
+ - make cursor parameters controllable via ioctl()s.
+
+ (Anyone to help with all this?)
+
+******************************************************************************/
+
+
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -33,314 +52,245 @@
#include <linux/interrupt.h>
#include <linux/fb.h>
#include <linux/selection.h>
+#include <linux/console.h>
#include <linux/init.h>
#include <linux/pci.h>
#include <linux/nvram.h>
-#include <linux/vc_ioctl.h>
+#include <linux/kd.h>
+#include <linux/vt_kern.h>
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+#include <asm/vc_ioctl.h>
+#endif
+
#include <asm/io.h>
+
+#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP)
#include <asm/prom.h>
#include <asm/pci-bridge.h>
+#include "macmodes.h"
+#endif
+#ifdef __sparc__
+#include <asm/pbm.h>
+#endif
#include "aty.h"
#include "fbcon.h"
#include "fbcon-cfb8.h"
#include "fbcon-cfb16.h"
+#include "fbcon-cfb24.h"
#include "fbcon-cfb32.h"
-static int currcon = 0;
-static struct display fb_disp;
-static struct fb_info fb_info;
-static struct { u_char red, green, blue, pad; } palette[256];
-
-static char atyfb_name[16] = "ATY Mach64";
-
-struct atyfb_par {
- int vmode;
- int cmode;
- u_int vxres; /* virtual screen size */
- u_int vyres;
- int xoffset; /* virtual screen position */
- int yoffset;
-};
-
-
-/*
- * Video mode values.
- * These are supposed to be the same as the values that
- * Apple uses in MacOS.
- */
-#define VMODE_NVRAM 0 /* use value stored in nvram */
-#define VMODE_512_384_60I 1 /* 512x384, 60Hz interlaced (NTSC) */
-#define VMODE_512_384_60 2 /* 512x384, 60Hz */
-#define VMODE_640_480_50I 3 /* 640x480, 50Hz interlaced (PAL) */
-#define VMODE_640_480_60I 4 /* 640x480, 60Hz interlaced (NTSC) */
-#define VMODE_640_480_60 5 /* 640x480, 60Hz (VGA) */
-#define VMODE_640_480_67 6 /* 640x480, 67Hz */
-#define VMODE_640_870_75P 7 /* 640x870, 75Hz (portrait) */
-#define VMODE_768_576_50I 8 /* 768x576, 50Hz (PAL full frame) */
-#define VMODE_800_600_56 9 /* 800x600, 56Hz */
-#define VMODE_800_600_60 10 /* 800x600, 60Hz */
-#define VMODE_800_600_72 11 /* 800x600, 72Hz */
-#define VMODE_800_600_75 12 /* 800x600, 75Hz */
-#define VMODE_832_624_75 13 /* 832x624, 75Hz */
-#define VMODE_1024_768_60 14 /* 1024x768, 60Hz */
-#define VMODE_1024_768_70 15 /* 1024x768, 70Hz (or 72Hz?) */
-#define VMODE_1024_768_75V 16 /* 1024x768, 75Hz (VESA) */
-#define VMODE_1024_768_75 17 /* 1024x768, 75Hz */
-#define VMODE_1152_870_75 18 /* 1152x870, 75Hz */
-#define VMODE_1280_960_75 19 /* 1280x960, 75Hz */
-#define VMODE_1280_1024_75 20 /* 1280x1024, 75Hz */
-#define VMODE_MAX 20
-#define VMODE_CHOOSE 99 /* choose based on monitor sense */
-
-/*
- * Color mode values, used to select number of bits/pixel.
- */
-#define CMODE_NVRAM -1 /* use value stored in nvram */
-#define CMODE_8 0 /* 8 bits/pixel */
-#define CMODE_16 1 /* 16 (actually 15) bits/pixel */
-#define CMODE_32 2 /* 32 (actually 24) bits/pixel */
-
+#define GUI_RESERVE 0x00001000
-static int default_video_mode = VMODE_NVRAM;
-static int default_color_mode = CMODE_NVRAM;
+#define CLASS_GX 1
+#define CLASS_CT 2
+#define CLASS_VT 3
+#define CLASS_GT 4
-static struct atyfb_par default_par;
-static struct atyfb_par current_par;
+#ifndef __powerpc__
+#define eieio() /* Enforce In-order Execution of I/O */
+#endif
-/*
- * Addresses in NVRAM where video mode and pixel size are stored.
- */
-#define NV_VMODE 0x140f
-#define NV_CMODE 0x1410
+/* FIXME: remove the FAIL definition */
+#define FAIL(x) do { printk(x "\n"); return -EINVAL; } while (0)
-/*
- * Horizontal and vertical resolution information.
- */
-extern struct vmode_attr {
- int hres;
- int vres;
- int vfreq;
- int interlaced;
-} vmode_attrs[VMODE_MAX];
+ /*
+ * Elements of the Hardware specific atyfb_par structure
+ */
-/*
- * Horizontal and vertical resolution for each mode.
- */
-static struct vmode_attr vmode_attrs[VMODE_MAX] = {
- {512, 384, 60, 1},
- {512, 384, 60},
- {640, 480, 50, 1},
- {640, 480, 60, 1},
- {640, 480, 60},
- {640, 480, 67},
- {640, 870, 75},
- {768, 576, 50, 1},
- {800, 600, 56},
- {800, 600, 60},
- {800, 600, 72},
- {800, 600, 75},
- {832, 624, 75},
- {1024, 768, 60},
- {1024, 768, 72},
- {1024, 768, 75},
- {1024, 768, 75},
- {1152, 870, 75},
- {1280, 960, 75},
- {1280, 1024, 75}
+struct crtc {
+ u32 vxres;
+ u32 vyres;
+ u32 xoffset;
+ u32 yoffset;
+ u32 bpp;
+ u32 h_tot_disp;
+ u32 h_sync_strt_wid;
+ u32 v_tot_disp;
+ u32 v_sync_strt_wid;
+ u32 off_pitch;
+ u32 gen_cntl;
+ u32 dp_pix_width; /* acceleration */
+ u32 dp_chain_mask; /* acceleration */
};
-
-/*
- * We get a sense value from the monitor and use it to choose
- * what resolution to use. This structure maps sense values
- * to display mode values (which determine the resolution and
- * frequencies).
- */
-static struct mon_map {
- int sense;
- int vmode;
-} monitor_map [] = {
- {0x000, VMODE_1280_1024_75}, /* 21" RGB */
- {0x114, VMODE_640_870_75P}, /* Portrait Monochrome */
- {0x221, VMODE_512_384_60}, /* 12" RGB*/
- {0x331, VMODE_1280_1024_75}, /* 21" RGB (Radius) */
- {0x334, VMODE_1280_1024_75}, /* 21" mono (Radius) */
- {0x335, VMODE_1280_1024_75}, /* 21" mono */
- {0x40A, VMODE_640_480_60I}, /* NTSC */
- {0x51E, VMODE_640_870_75P}, /* Portrait RGB */
- {0x603, VMODE_832_624_75}, /* 12"-16" multiscan */
- {0x60b, VMODE_1024_768_70}, /* 13"-19" multiscan */
- {0x623, VMODE_1152_870_75}, /* 13"-21" multiscan */
- {0x62b, VMODE_640_480_67}, /* 13"/14" RGB */
- {0x700, VMODE_640_480_50I}, /* PAL */
- {0x714, VMODE_640_480_60I}, /* NTSC */
- {0x717, VMODE_800_600_75}, /* VGA */
- {0x72d, VMODE_832_624_75}, /* 16" RGB (Goldfish) */
- {0x730, VMODE_768_576_50I}, /* PAL (Alternate) */
- {0x73a, VMODE_1152_870_75}, /* 3rd party 19" */
- {-1, VMODE_640_480_60}, /* catch-all, must be last */
+struct pll_gx {
+ u8 m;
+ u8 n;
};
-static int map_monitor_sense(int sense)
-{
- struct mon_map *map;
-
- for (map = monitor_map; map->sense >= 0; ++map)
- if (map->sense == sense)
- break;
- return map->vmode;
-}
-
-struct aty_cmap_regs {
- unsigned char windex;
- unsigned char lut;
- unsigned char mask;
- unsigned char rindex;
- unsigned char cntl;
+struct pll_ct {
+ u8 pll_ref_div;
+ u8 pll_gen_cntl;
+ u8 mclk_fb_div;
+ u8 pll_vclk_cntl;
+ u8 vclk_post_div;
+ u8 vclk_fb_div;
+ u8 pll_ext_cntl;
+ u32 dsp_config; /* Mach64 GTB DSP */
+ u32 dsp_on_off; /* Mach64 GTB DSP */
};
-typedef struct aty_regvals {
- int offset[3]; /* first pixel address */
- int crtc_h_sync_strt_wid[3]; /* depth dependant */
- int crtc_gen_cntl[3];
- int mem_cntl[3];
-
- int crtc_h_tot_disp; /* mode dependant */
- int crtc_v_tot_disp;
- int crtc_v_sync_strt_wid;
- int crtc_off_pitch;
+ /*
+ * The Hardware parameters for each card
+ */
- unsigned char clock_val[2]; /* vals for 20 and 21 */
-} aty_regvals;
+struct atyfb_par {
+ struct crtc crtc;
+ union {
+ struct pll_gx gx;
+ struct pll_ct ct;
+ } pll;
+ u32 accel_flags;
+};
-struct rage_regvals {
- int h_total, h_sync_start, h_sync_width;
- int v_total, v_sync_start, v_sync_width;
- int h_sync_neg, v_sync_neg;
+struct aty_cmap_regs {
+ u8 windex;
+ u8 lut;
+ u8 mask;
+ u8 rindex;
+ u8 cntl;
};
-static int aty_vram_reqd(const struct atyfb_par *par);
-static struct aty_regvals *get_aty_struct(int vmode);
-
-static unsigned long frame_buffer;
-
-static int total_vram; /* total amount of video memory, bytes */
-static int chip_type; /* what chip type was detected */
-
-static unsigned long ati_regbase;
-static struct aty_cmap_regs *aty_cmap_regs;
-
-#include "ati-gx.h"
-#include "ati-gt.h"
-#include "ati-vt.h"
-
-static struct aty_regvals *aty_gt_reg_init[20] = {
- NULL, NULL, NULL, NULL,
- &aty_gt_reg_init_5,
- &aty_gt_reg_init_6,
- NULL, NULL,
- &aty_gt_reg_init_9,
- &aty_gt_reg_init_10,
- &aty_gt_reg_init_11,
- &aty_gt_reg_init_12,
- &aty_gt_reg_init_13,
- &aty_gt_reg_init_14,
- &aty_gt_reg_init_15,
- NULL,
- &aty_gt_reg_init_17,
- &aty_gt_reg_init_18,
- NULL,
- &aty_gt_reg_init_20
+struct pci_mmap_map {
+ unsigned long voff;
+ unsigned long poff;
+ unsigned long size;
+ unsigned long prot_flag;
+ unsigned long prot_mask;
};
-static struct aty_regvals *aty_gx_reg_init[20] = {
- NULL, NULL, NULL, NULL,
- &aty_gx_reg_init_6,
- &aty_gx_reg_init_6,
- NULL, NULL, NULL, NULL, NULL, NULL,
- &aty_gx_reg_init_13,
- &aty_gx_reg_init_14,
- &aty_gx_reg_init_15,
- NULL,
- &aty_gx_reg_init_17,
- &aty_gx_reg_init_18,
- NULL,
- &aty_gx_reg_init_20
+#define DEFAULT_CURSOR_BLINK_RATE (20)
+
+struct aty_cursor {
+ int enable;
+ int on;
+ int vbl_cnt;
+ int blink_rate;
+ u32 offset;
+ struct {
+ u16 x, y;
+ } pos, hot, size;
+ u32 color[2];
+ u8 bits[8][64];
+ u8 mask[8][64];
+ struct timer_list *timer;
};
-static struct aty_regvals *aty_vt_reg_init[21] = {
- NULL, NULL, NULL, NULL,
- &aty_vt_reg_init_5,
- &aty_vt_reg_init_6,
- NULL, NULL, NULL,
- &aty_vt_reg_init_10,
- &aty_vt_reg_init_11,
- &aty_vt_reg_init_12,
- &aty_vt_reg_init_13,
- &aty_vt_reg_init_14,
- &aty_vt_reg_init_15,
- NULL,
- &aty_vt_reg_init_17,
- &aty_vt_reg_init_18,
- &aty_vt_reg_init_19,
- &aty_vt_reg_init_20
+struct fb_info_aty {
+ struct fb_info fb_info;
+ unsigned long ati_regbase_phys;
+ unsigned long ati_regbase;
+ unsigned long frame_buffer_phys;
+ unsigned long frame_buffer;
+ struct display disp;
+ struct display_switch dispsw;
+ struct pci_mmap_map *mmap_map;
+ struct aty_cursor *cursor;
+ struct aty_cmap_regs *aty_cmap_regs;
+ struct { u8 red, green, blue, pad; } palette[256];
+ struct atyfb_par default_par;
+ struct atyfb_par current_par;
+ u32 total_vram;
+ u32 pll_per;
+ u32 mclk_per;
+ u16 chip_type;
+#define Gx info->chip_type
+ u8 chip_rev;
+#define Rev info->chip_rev
+ u8 bus_type;
+ u8 ram_type;
+ u8 dac_type;
+ u8 clk_type;
+ u8 mem_refresh_rate;
+#ifdef __sparc__
+ u8 open;
+ u8 mmaped;
+ int vtconsole;
+ int consolecnt;
+#endif
};
+
/*
- * Interface used by the world
+ * Frame buffer device API
*/
-unsigned long atyfb_init(unsigned long mem_start);
-void atyfb_setup(char *options, int *ints);
-
-static int atyfb_open(struct fb_info *info);
-static int atyfb_release(struct fb_info *info);
+static int atyfb_open(struct fb_info *info, int user);
+static int atyfb_release(struct fb_info *info, int user);
static int atyfb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info);
+ struct fb_info *fb);
static int atyfb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
+ struct fb_info *fb);
static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
+ struct fb_info *fb);
static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
+ struct fb_info *fb);
static int atyfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info);
static int atyfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
struct fb_info *info);
static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
u_long arg, int con, struct fb_info *info);
+#ifdef __sparc__
+static int atyfb_mmap(struct fb_info *info, struct file *file,
+ struct vm_area_struct *vma);
+#endif
/*
* Interface to the low level console driver
*/
-static int atyfbcon_switch(int con, struct fb_info *info);
-static int atyfbcon_updatevar(int con, struct fb_info *info);
-static void atyfbcon_blank(int blank, struct fb_info *info);
+static int atyfbcon_switch(int con, struct fb_info *fb);
+static int atyfbcon_updatevar(int con, struct fb_info *fb);
+static void atyfbcon_blank(int blank, struct fb_info *fb);
/*
* Text console acceleration
*/
-#ifdef CONFIG_FBCON_CFB8
+static void fbcon_aty_bmove(struct display *p, int sy, int sx, int dy, int dx,
+ int height, int width);
+static void fbcon_aty_clear(struct vc_data *conp, struct display *p, int sy,
+ int sx, int height, int width);
+#ifdef FBCON_HAS_CFB8
static struct display_switch fbcon_aty8;
+static void fbcon_aty8_putc(struct vc_data *conp, struct display *p, int c,
+ int yy, int xx);
+static void fbcon_aty8_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int yy,
+ int xx);
#endif
-
-
-#ifdef CONFIG_FB_COMPAT_XPMAC
-extern struct vc_mode display_info;
-extern struct fb_info *console_fb_info;
-extern int (*console_setmode_ptr)(struct vc_mode *, int);
-extern int (*console_set_cmap_ptr)(struct fb_cmap *, int, int,
- struct fb_info *);
-static int atyfb_console_setmode(struct vc_mode *, int);
+#ifdef FBCON_HAS_CFB16
+static struct display_switch fbcon_aty16;
+static void fbcon_aty16_putc(struct vc_data *conp, struct display *p, int c,
+ int yy, int xx);
+static void fbcon_aty16_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int yy,
+ int xx);
+#endif
+#ifdef FBCON_HAS_CFB24
+static struct display_switch fbcon_aty24;
+static void fbcon_aty24_putc(struct vc_data *conp, struct display *p, int c,
+ int yy, int xx);
+static void fbcon_aty24_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int yy,
+ int xx);
+#endif
+#ifdef FBCON_HAS_CFB32
+static struct display_switch fbcon_aty32;
+static void fbcon_aty32_putc(struct vc_data *conp, struct display *p, int c,
+ int yy, int xx);
+static void fbcon_aty32_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int yy,
+ int xx);
#endif
@@ -348,521 +298,1446 @@ static int atyfb_console_setmode(struct vc_mode *, int);
* Internal routines
*/
+static int aty_init(struct fb_info_aty *info, const char *name);
+#ifdef CONFIG_ATARI
+static int store_video_par(char *videopar, unsigned char m64_num);
+static char *strtoke(char *s, const char *ct);
+#endif
+
+static void reset_engine(const struct fb_info_aty *info);
+static void init_engine(const struct atyfb_par *par,
+ const 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 void aty_set_crtc(const struct fb_info_aty *info,
+ const struct crtc *crtc);
+static int aty_var_to_crtc(const struct fb_info_aty *info,
+ const struct fb_var_screeninfo *var,
+ struct crtc *crtc);
+static void aty_set_dac_514(const struct fb_info_aty *info, u32 bpp);
+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(const struct fb_var_screeninfo *var,
+ struct pll_gx *pll);
+static int aty_var_to_pll_514(const struct fb_var_screeninfo *var,
+ struct pll_gx *pll);
+static int aty_pll_gx_to_var(const struct pll_gx *pll,
+ struct fb_var_screeninfo *var);
+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_var_to_pll_ct(const struct fb_info_aty *info,
+ const struct fb_var_screeninfo *var,
+ struct pll_ct *pll);
+static int aty_pll_ct_to_var(const struct pll_ct *pll,
+ struct fb_var_screeninfo *var);
+static void atyfb_set_par(const struct atyfb_par *par,
+ struct fb_info_aty *info);
+static int atyfb_decode_var(const struct fb_var_screeninfo *var,
+ struct atyfb_par *par,
+ const struct fb_info_aty *info);
+static int atyfb_encode_var(struct fb_var_screeninfo *var,
+ const struct atyfb_par *par,
+ const struct fb_info_aty *info);
+static void set_off_pitch(struct atyfb_par *par,
+ const struct fb_info_aty *info);
+static int encode_fix(struct fb_fix_screeninfo *fix,
+ const struct atyfb_par *par,
+ const struct fb_info_aty *info);
static int atyfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
- u_int *transp, struct fb_info *info);
+ u_int *transp, struct fb_info *fb);
static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *info);
+ u_int transp, struct fb_info *fb);
static void do_install_cmap(int con, struct fb_info *info);
+#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP)
+static int read_aty_sense(const struct fb_info_aty *info);
+#endif
+ /*
+ * Interface used by the world
+ */
+
+void atyfb_init(void);
+#ifdef CONFIG_FB_OF
+void atyfb_of_init(struct device_node *dp);
+#endif
+void atyfb_setup(char *options, int *ints);
+
+
+static int currcon = 0;
+
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, NULL, atyfb_ioctl
+ atyfb_get_cmap, atyfb_set_cmap, atyfb_pan_display, atyfb_ioctl,
+#ifdef __sparc__
+ atyfb_mmap
+#else
+ NULL
+#endif
};
+static char atyfb_name[16] = "ATY Mach64";
+static char fontname[40] __initdata = { 0 };
+
+static const u32 ref_clk_per = 1000000000000ULL/14318180;
+
+#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP)
+static int default_vmode = VMODE_NVRAM;
+static int default_cmode = CMODE_NVRAM;
+#endif
+
+#ifdef CONFIG_ATARI
+static unsigned int mach64_count __initdata = 0;
+static unsigned long phys_vmembase[FB_MAX] __initdata = { 0, };
+static unsigned long phys_size[FB_MAX] __initdata = { 0, };
+static unsigned long phys_guiregbase[FB_MAX] __initdata = { 0, };
+#endif
+
+
+static struct aty_features {
+ u16 pci_id;
+ u16 chip_type;
+ const char *name;
+} aty_features[] __initdata = {
+ /* mach64GX family */
+ { 0x4758, 0x00d7, "mach64GX (ATI888GX00)" },
+ { 0x4358, 0x0057, "mach64CX (ATI888CX00)" },
+
+ /* mach64CT family */
+ { 0x4354, 0x4354, "mach64CT (ATI264CT)" },
+ { 0x4554, 0x4554, "mach64ET (ATI264ET)" },
+
+ /* mach64CT family / mach64VT class */
+ { 0x5654, 0x5654, "mach64VT (ATI264VT)" },
+ { 0x5655, 0x5655, "mach64VTB (ATI264VTB)" },
+/* { 0x5656, 0x5656, "mach64VT4 (ATI264VT4)" }, */
+
+ /* mach64CT family / mach64GT (3D RAGE) class */
+ { 0x4c54, 0x4c54, "3D RAGE LT" },
+ { 0x4c47, 0x4c47, "3D RAGE LG" },
+ { 0x4754, 0x4754, "3D RAGE (GT)" },
+ { 0x4755, 0x4755, "3D RAGE II+ (GTB)" },
+/* { 0x4756, 0x4756, "3D RAGE IIC" }, */
+ { 0x4742, 0x4742, "3D RAGE PRO (BGA, AGP)" },
+ { 0x4744, 0x4744, "3D RAGE PRO (BGA, AGP, 1x only)" },
+ { 0x4749, 0x4749, "3D RAGE PRO (BGA, PCI)" },
+ { 0x4750, 0x4750, "3D RAGE PRO (PQFP, PCI)" },
+ { 0x4751, 0x4751, "3D RAGE PRO (PQFP, PCI, limited 3D)" },
+};
+
+
+static inline u32 aty_ld_le32(volatile unsigned int regindex,
+ const struct fb_info_aty *info)
+{
+ unsigned long temp;
+ u32 val;
+
+#if defined(__powerpc__)
+ temp = info->ati_regbase;
+ asm("lwbrx %0,%1,%2" : "=r"(val) : "r" (regindex), "r" (temp));
+#elif defined(__sparc_v9__)
+ temp = info->ati_regbase + regindex;
+ asm("lduwa [%1] %2, %0" : "=r" (val) : "r" (temp), "i" (ASI_PL));
+#else
+ temp = info->ati_regbase+regindex;
+ val = le32_to_cpu(*((volatile u32 *)(temp)));
+#endif
+ return val;
+}
-static inline int aty_vram_reqd(const struct atyfb_par *par)
+static inline void aty_st_le32(volatile unsigned int regindex, u32 val,
+ const struct fb_info_aty *info)
{
- return (par->vxres*par->vyres) << par->cmode;
+ unsigned long temp;
+
+#if defined(__powerpc__)
+ temp = info->ati_regbase;
+ asm("stwbrx %0,%1,%2" : : "r" (val), "r" (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");
+#else
+ temp = info->ati_regbase+regindex;
+ *((volatile u32 *)(temp)) = cpu_to_le32(val);
+#endif
}
-extern inline unsigned aty_ld_le32(volatile unsigned long addr)
+static inline u8 aty_ld_8(volatile unsigned int regindex,
+ const struct fb_info_aty *info)
{
- register unsigned long temp = ati_regbase,val;
+ return *(volatile u8 *)(info->ati_regbase+regindex);
+}
- asm("lwbrx %0,%1,%2": "=r"(val):"r"(addr), "r"(temp));
- return val;
+static inline void aty_st_8(volatile unsigned int regindex, u8 val,
+ const struct fb_info_aty *info)
+{
+ *(volatile u8 *)(info->ati_regbase+regindex) = val;
}
-extern inline void aty_st_le32(volatile unsigned long addr, unsigned val)
+
+ /*
+ * Generic Mach64 routines
+ */
+
+ /*
+ * All writes to draw engine registers are automatically routed through a
+ * 32-bit-wide, 16-entry-deep command FIFO ...
+ * Register writes to registers with DWORD offsets less than 40h are not
+ * FIFOed.
+ * (from Chapter 5 of the Mach64 Programmer's Guide)
+ */
+
+static inline void wait_for_fifo(u16 entries, const struct fb_info_aty *info)
{
- register unsigned long temp = ati_regbase;
+ while ((aty_ld_le32(FIFO_STAT, info) & 0xffff) >
+ ((u32)(0x8000 >> entries)));
+}
- asm("stwbrx %0,%1,%2": : "r"(val), "r"(addr), "r"(temp):"memory");
+static inline void wait_for_idle(const struct fb_info_aty *info)
+{
+ wait_for_fifo(16, info);
+ while ((aty_ld_le32(GUI_STAT, info) & 1)!= 0);
}
-extern inline unsigned char aty_ld_8(volatile unsigned long addr)
+static void reset_engine(const struct fb_info_aty *info)
{
- return *(char *) ((long) addr + (long) ati_regbase);
+ /* reset engine */
+ aty_st_le32(GEN_TEST_CNTL,
+ aty_ld_le32(GEN_TEST_CNTL, info) & ~GUI_ENGINE_ENABLE, info);
+ /* enable engine */
+ aty_st_le32(GEN_TEST_CNTL,
+ aty_ld_le32(GEN_TEST_CNTL, info) | GUI_ENGINE_ENABLE, info);
+ /* ensure engine is not locked up by clearing any FIFO or */
+ /* HOST errors */
+ aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL, info) | BUS_HOST_ERR_ACK |
+ BUS_FIFO_ERR_ACK, info);
}
-extern inline void aty_st_8(volatile unsigned long addr, unsigned char val)
+static void init_engine(const struct atyfb_par *par,
+ const struct fb_info_aty *info)
{
- *(unsigned char *) (addr + (unsigned long) ati_regbase) = val;
+ u32 pitch_value;
+
+ /* determine modal information from global mode structure */
+ pitch_value = par->crtc.vxres;
+
+ if (par->crtc.bpp == 24) {
+ /* In 24 bpp, the engine is in 8 bpp - this requires that all */
+ /* horizontal coordinates and widths must be adjusted */
+ pitch_value = pitch_value * 3;
+ }
+
+ /* Reset engine, enable, and clear any engine errors */
+ reset_engine(info);
+ /* Ensure that vga page pointers are set to zero - the upper */
+ /* page pointers are set to 1 to handle overflows in the */
+ /* lower page */
+ aty_st_le32(MEM_VGA_WP_SEL, 0x00010000, info);
+ aty_st_le32(MEM_VGA_RP_SEL, 0x00010000, info);
+
+ /* ---- Setup standard engine context ---- */
+
+ /* All GUI registers here are FIFOed - therefore, wait for */
+ /* the appropriate number of empty FIFO entries */
+ wait_for_fifo(14, info);
+
+ /* enable all registers to be loaded for context loads */
+ aty_st_le32(CONTEXT_MASK, 0xFFFFFFFF, info);
+
+ /* set destination pitch to modal pitch, set offset to zero */
+ aty_st_le32(DST_OFF_PITCH, (pitch_value / 8) << 22, info);
+
+ /* zero these registers (set them to a known state) */
+ aty_st_le32(DST_Y_X, 0, info);
+ aty_st_le32(DST_HEIGHT, 0, info);
+ aty_st_le32(DST_BRES_ERR, 0, info);
+ aty_st_le32(DST_BRES_INC, 0, info);
+ aty_st_le32(DST_BRES_DEC, 0, info);
+
+ /* set destination drawing attributes */
+ aty_st_le32(DST_CNTL, DST_LAST_PEL | DST_Y_TOP_TO_BOTTOM |
+ DST_X_LEFT_TO_RIGHT, info);
+
+ /* set source pitch to modal pitch, set offset to zero */
+ aty_st_le32(SRC_OFF_PITCH, (pitch_value / 8) << 22, info);
+
+ /* set these registers to a known state */
+ aty_st_le32(SRC_Y_X, 0, info);
+ aty_st_le32(SRC_HEIGHT1_WIDTH1, 1, info);
+ aty_st_le32(SRC_Y_X_START, 0, info);
+ aty_st_le32(SRC_HEIGHT2_WIDTH2, 1, info);
+
+ /* set source pixel retrieving attributes */
+ aty_st_le32(SRC_CNTL, SRC_LINE_X_LEFT_TO_RIGHT, info);
+
+ /* set host attributes */
+ wait_for_fifo(13, info);
+ aty_st_le32(HOST_CNTL, 0, info);
+
+ /* set pattern attributes */
+ aty_st_le32(PAT_REG0, 0, info);
+ aty_st_le32(PAT_REG1, 0, info);
+ aty_st_le32(PAT_CNTL, 0, info);
+
+ /* set scissors to modal size */
+ aty_st_le32(SC_LEFT, 0, info);
+ aty_st_le32(SC_TOP, 0, info);
+ aty_st_le32(SC_BOTTOM, par->crtc.vyres-1, info);
+ aty_st_le32(SC_RIGHT, pitch_value-1, info);
+
+ /* set background color to minimum value (usually BLACK) */
+ aty_st_le32(DP_BKGD_CLR, 0, info);
+
+ /* set foreground color to maximum value (usually WHITE) */
+ aty_st_le32(DP_FRGD_CLR, 0xFFFFFFFF, info);
+
+ /* set write mask to effect all pixel bits */
+ aty_st_le32(DP_WRITE_MASK, 0xFFFFFFFF, info);
+
+ /* set foreground mix to overpaint and background mix to */
+ /* no-effect */
+ aty_st_le32(DP_MIX, FRGD_MIX_S | BKGD_MIX_D, info);
+
+ /* set primary source pixel channel to foreground color */
+ /* register */
+ aty_st_le32(DP_SRC, FRGD_SRC_FRGD_CLR, info);
+
+ /* set compare functionality to false (no-effect on */
+ /* destination) */
+ wait_for_fifo(3, info);
+ aty_st_le32(CLR_CMP_CLR, 0, info);
+ aty_st_le32(CLR_CMP_MASK, 0xFFFFFFFF, info);
+ aty_st_le32(CLR_CMP_CNTL, 0, info);
+
+ /* set pixel depth */
+ wait_for_fifo(2, info);
+ aty_st_le32(DP_PIX_WIDTH, par->crtc.dp_pix_width, info);
+ aty_st_le32(DP_CHAIN_MASK, par->crtc.dp_chain_mask, info);
+
+ /* insure engine is idle before leaving */
+ wait_for_idle(info);
}
-static void aty_st_514(int offset, char val)
+static void aty_st_514(int offset, u8 val, const struct fb_info_aty *info)
{
- aty_WaitQueue(5);
- aty_st_8(DAC_CNTL, 1);
- aty_st_8(DAC_W_INDEX, offset & 0xff); /* right addr byte */
- aty_st_8(DAC_DATA, (offset >> 8) & 0xff); /* left addr byte */
+ aty_st_8(DAC_CNTL, 1, info);
+ /* right addr byte */
+ aty_st_8(DAC_W_INDEX, offset & 0xff, info);
+ /* left addr byte */
+ aty_st_8(DAC_DATA, (offset >> 8) & 0xff, info);
eieio();
- aty_st_8(DAC_MASK, val);
+ aty_st_8(DAC_MASK, val, info);
eieio();
- aty_st_8(DAC_CNTL, 0);
+ aty_st_8(DAC_CNTL, 0, info);
}
-static void aty_st_pll(int offset, char val)
+static void aty_st_pll(int offset, u8 val, const struct fb_info_aty *info)
{
- aty_WaitQueue(3);
- aty_st_8(CLOCK_CNTL + 1, (offset << 2) | PLL_WR_EN); /* write addr byte */
+ /* write addr byte */
+ aty_st_8(CLOCK_CNTL + 1, (offset << 2) | PLL_WR_EN, info);
eieio();
- aty_st_8(CLOCK_CNTL + 2, val); /* write the register value */
+ /* write the register value */
+ aty_st_8(CLOCK_CNTL + 2, val, info);
eieio();
- aty_st_8(CLOCK_CNTL + 1, (offset << 2) & ~PLL_WR_EN);
+ aty_st_8(CLOCK_CNTL + 1, (offset << 2) & ~PLL_WR_EN, info);
}
-static struct aty_regvals *get_aty_struct(int vmode)
+#if 0 /* ecd debug */
+static u8 aty_ld_pll(int offset, const struct fb_info_aty *info)
{
- int v = vmode - 1;
+ u8 val;
- switch (chip_type) {
- case MACH64_GT_ID:
- return aty_gt_reg_init[v];
- break;
- case MACH64_VT_ID:
- return aty_vt_reg_init[v];
- break;
- default: /* default to MACH64_GX_ID */
- return aty_gx_reg_init[v];
- break;
- }
+ /* write addr byte */
+ aty_st_8(CLOCK_CNTL + 1, (offset << 2), info);
+ eieio();
+ /* read the register value */
+ val = aty_ld_8(CLOCK_CNTL + 2, info);
+ eieio();
+ return val;
}
+#endif /* ecd debug */
+
+#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP)
-static int read_aty_sense(void)
+ /*
+ * Apple monitor sense
+ */
+
+static int read_aty_sense(const struct fb_info_aty *info)
{
int sense, i;
- aty_st_le32(GP_IO, 0x31003100); /* drive outputs high */
+ aty_st_le32(GP_IO, 0x31003100, info); /* drive outputs high */
__delay(200);
- aty_st_le32(GP_IO, 0); /* turn off outputs */
+ aty_st_le32(GP_IO, 0, info); /* turn off outputs */
__delay(2000);
- i = aty_ld_le32(GP_IO); /* get primary sense value */
+ i = aty_ld_le32(GP_IO, info); /* get primary sense value */
sense = ((i & 0x3000) >> 3) | (i & 0x100);
/* drive each sense line low in turn and collect the other 2 */
- aty_st_le32(GP_IO, 0x20000000); /* drive A low */
+ aty_st_le32(GP_IO, 0x20000000, info); /* drive A low */
__delay(2000);
- i = aty_ld_le32(GP_IO);
+ i = aty_ld_le32(GP_IO, info);
sense |= ((i & 0x1000) >> 7) | ((i & 0x100) >> 4);
- aty_st_le32(GP_IO, 0x20002000); /* drive A high again */
+ aty_st_le32(GP_IO, 0x20002000, info); /* drive A high again */
__delay(200);
- aty_st_le32(GP_IO, 0x10000000); /* drive B low */
+ aty_st_le32(GP_IO, 0x10000000, info); /* drive B low */
__delay(2000);
- i = aty_ld_le32(GP_IO);
+ i = aty_ld_le32(GP_IO, info);
sense |= ((i & 0x2000) >> 10) | ((i & 0x100) >> 6);
- aty_st_le32(GP_IO, 0x10001000); /* drive B high again */
+ aty_st_le32(GP_IO, 0x10001000, info); /* drive B high again */
__delay(200);
- aty_st_le32(GP_IO, 0x01000000); /* drive C low */
+ aty_st_le32(GP_IO, 0x01000000, info); /* drive C low */
__delay(2000);
- sense |= (aty_ld_le32(GP_IO) & 0x3000) >> 12;
- aty_st_le32(GP_IO, 0); /* turn off outputs */
+ sense |= (aty_ld_le32(GP_IO, info) & 0x3000) >> 12;
+ aty_st_le32(GP_IO, 0, info); /* turn off outputs */
return sense;
}
-static void RGB514_Program(int cmode)
+#endif /* defined(CONFIG_PMAC) || defined(CONFIG_CHRP) */
+
+/* ------------------------------------------------------------------------- */
+
+ /*
+ * Hardware Cursor support.
+ */
+
+static u8 cursor_pixel_map[2] = { 0, 15 };
+static u8 cursor_color_map[2] = { 0, 0xff };
+
+static u8 cursor_bits_lookup[16] =
{
- typedef struct {
- char pixel_dly;
- char misc2_cntl;
- char pixel_rep;
- char pixel_cntl_index;
- char pixel_cntl_v1;
- } RGB514_DAC_Table;
+ 0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
+ 0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55
+};
- static RGB514_DAC_Table RGB514DAC_Tab[8] = {
- {0, 0x41, 0x03, 0x71, 0x45}, // 8bpp
- {0, 0x45, 0x04, 0x0c, 0x01}, // 555
- {0, 0x45, 0x06, 0x0e, 0x00}, // XRGB
- };
- RGB514_DAC_Table *pDacProgTab;
+static u8 cursor_mask_lookup[16] =
+{
+ 0xaa, 0x2a, 0x8a, 0x0a, 0xa2, 0x22, 0x82, 0x02,
+ 0xa8, 0x28, 0x88, 0x08, 0xa0, 0x20, 0x80, 0x00
+};
+
+static void
+aty_set_cursor_color(struct fb_info_aty *fb, u8 *pixel,
+ u8 *red, u8 *green, u8 *blue)
+{
+ struct aty_cursor *c = fb->cursor;
+ int i;
- pDacProgTab = &RGB514DAC_Tab[cmode];
+ if (!c)
+ return;
- aty_st_514(0x90, 0x00);
- aty_st_514(0x04, pDacProgTab->pixel_dly);
- aty_st_514(0x05, 0x00);
+#ifdef __sparc__
+ if (fb->mmaped && currcon == fb->vtconsole)
+ return;
+#endif
- aty_st_514(0x2, 0x1);
- aty_st_514(0x71, pDacProgTab->misc2_cntl);
- aty_st_514(0x0a, pDacProgTab->pixel_rep);
+ for (i = 0; i < 2; i++) {
+ c->color[i] = (u32)red[i] << 24;
+ c->color[i] |= (u32)green[i] << 16;
+ c->color[i] |= (u32)blue[i] << 8;
+ c->color[i] |= (u32)pixel[i];
+ }
- aty_st_514(pDacProgTab->pixel_cntl_index, pDacProgTab->pixel_cntl_v1);
+ wait_for_fifo(2, fb);
+ aty_st_le32(CUR_CLR0, c->color[0], fb);
+ aty_st_le32(CUR_CLR1, c->color[1], fb);
}
-static void set_off_pitch(const struct atyfb_par *par)
+static void
+aty_set_cursor_shape(struct fb_info_aty *fb)
{
- u32 pitch, offset;
+ struct aty_cursor *c = fb->cursor;
+ u8 *ram, m, b;
+ int x, y;
- pitch = par->vxres>>3;
- offset = ((par->yoffset*par->vxres+par->xoffset)>>3)<<par->cmode;
- aty_st_le32(CRTC_OFF_PITCH, pitch<<22 | offset);
- if (chip_type == MACH64_GT_ID) {
- /* Is this OK for other chips? */
- aty_st_le32(DST_OFF_PITCH, pitch<<22 | offset);
- aty_st_le32(SRC_OFF_PITCH, pitch<<22 | offset);
- }
+ if (!c)
+ return;
+
+#ifdef __sparc__
+ if (fb->mmaped && currcon == fb->vtconsole)
+ return;
+#endif
+
+ ram = (u8 *)(fb->frame_buffer + c->offset);
+
+ for (y = 0; y < c->size.y; y++) {
+ for (x = 0; x < c->size.x >> 2; x++) {
+ m = c->mask[x][y];
+ b = c->bits[x][y];
+ *ram++ = cursor_mask_lookup[m >> 4] |
+ cursor_bits_lookup[(b & m) >> 4];
+ *ram++ = cursor_mask_lookup[m & 0x0f] |
+ cursor_bits_lookup[(b & m) & 0x0f];
+ }
+ for ( ; x < 8; x++) {
+ *ram++ = 0xaa;
+ *ram++ = 0xaa;
+ }
+ }
+ memset(ram, 0xaa, (64 - c->size.y) * 16);
}
-static void atyfb_set_par(struct atyfb_par *par)
+static void
+aty_set_cursor(struct fb_info_aty *fb)
{
- int i, hres;
- struct aty_regvals *init = get_aty_struct(par->vmode);
- int vram_type = aty_ld_le32(CONFIG_STAT0) & 7;
+ struct aty_cursor *c = fb->cursor;
+ u16 xoff, yoff;
+ int x, y;
- if (init == 0) /* paranoia, shouldn't get here */
- panic("aty: display mode %d not supported", par->vmode);
+ if (!c)
+ return;
- current_par = *par;
- hres = vmode_attrs[par->vmode-1].hres;
+#ifdef __sparc__
+ if (fb->mmaped && currcon == fb->vtconsole)
+ return;
+#endif
- /* clear FIFO errors */
- aty_st_le32(BUS_CNTL, aty_ld_le32(BUS_CNTL) | BUS_HOST_ERR_ACK
- | BUS_FIFO_ERR_ACK);
+ if (c->on) {
+ x = c->pos.x - c->hot.x;
+ if (x < 0) {
+ xoff = -x;
+ x = 0;
+ } else {
+ xoff = 0;
+ }
+
+ y = c->pos.y - c->hot.y;
+ if (y < 0) {
+ yoff = -y;
+ y = 0;
+ } else {
+ yoff = 0;
+ }
+
+ wait_for_fifo(4, fb);
+ aty_st_le32(CUR_OFFSET, (c->offset >> 3) + (yoff << 1), fb);
+ aty_st_le32(CUR_HORZ_VERT_OFF,
+ ((u32)(64 - c->size.y + yoff) << 16) | xoff, fb);
+ aty_st_le32(CUR_HORZ_VERT_POSN, ((u32)y << 16) | x, fb);
+ aty_st_le32(GEN_TEST_CNTL, aty_ld_le32(GEN_TEST_CNTL, fb)
+ | HWCURSOR_ENABLE, fb);
+ } else {
+ wait_for_fifo(4, fb);
+ aty_st_le32(GEN_TEST_CNTL,
+ aty_ld_le32(GEN_TEST_CNTL, fb) & ~HWCURSOR_ENABLE,
+ fb);
+ }
+}
- /* Reset engine */
- i = aty_ld_le32(GEN_TEST_CNTL);
- aty_st_le32(GEN_TEST_CNTL, i & ~GUI_ENGINE_ENABLE);
- eieio();
- aty_WaitIdleEmpty();
- aty_st_le32(GEN_TEST_CNTL, i | GUI_ENGINE_ENABLE);
- aty_WaitIdleEmpty();
+static void
+aty_cursor_timer_handler(unsigned long dev_addr)
+{
+ struct fb_info_aty *fb = (struct fb_info_aty *)dev_addr;
- if ( chip_type != MACH64_GT_ID ) {
- i = aty_ld_le32(CRTC_GEN_CNTL);
- aty_st_le32(CRTC_GEN_CNTL, i | CRTC_EXT_DISP_EN);
- }
+ if (!fb->cursor)
+ return;
- if ( chip_type == MACH64_GX_ID ) {
- i = aty_ld_le32(GEN_TEST_CNTL);
- aty_st_le32(GEN_TEST_CNTL, i | GEN_OVR_OUTPUT_EN );
- }
+ if (!fb->cursor->enable)
+ goto out;
- switch (chip_type) {
- case MACH64_VT_ID:
- aty_st_pll(PLL_MACRO_CNTL, 0xb5);
- aty_st_pll(PLL_REF_DIV, 0x2d);
- aty_st_pll(PLL_GEN_CNTL, 0x14);
- aty_st_pll(MCLK_FB_DIV, 0xbd);
- aty_st_pll(PLL_VCLK_CNTL, 0x0b);
- aty_st_pll(VCLK_POST_DIV, init->clock_val[0]);
- aty_st_pll(VCLK0_FB_DIV, init->clock_val[1]);
- aty_st_pll(VCLK1_FB_DIV, 0xd6);
- aty_st_pll(VCLK2_FB_DIV, 0xee);
- aty_st_pll(VCLK3_FB_DIV, 0xf8);
- aty_st_pll(PLL_XCLK_CNTL, 0x0);
- aty_st_pll(PLL_TEST_CTRL, 0x0);
- aty_st_pll(PLL_TEST_COUNT, 0x0);
- break;
- case MACH64_GT_ID:
- if (vram_type == 5) {
- aty_st_pll(0, 0xcd);
- aty_st_pll(PLL_MACRO_CNTL,
- par->vmode >= VMODE_1024_768_60 ? 0xd3: 0xd5);
- aty_st_pll(PLL_REF_DIV, 0x21);
- aty_st_pll(PLL_GEN_CNTL, 0x44);
- aty_st_pll(MCLK_FB_DIV, 0xe8);
- aty_st_pll(PLL_VCLK_CNTL, 0x03);
- aty_st_pll(VCLK_POST_DIV, init->offset[0]);
- aty_st_pll(VCLK0_FB_DIV, init->offset[1]);
- aty_st_pll(VCLK1_FB_DIV, 0x8e);
- aty_st_pll(VCLK2_FB_DIV, 0x9e);
- aty_st_pll(VCLK3_FB_DIV, 0xc6);
- aty_st_pll(PLL_XCLK_CNTL, init->offset[2]);
- aty_st_pll(12, 0xa6);
- aty_st_pll(13, 0x1b);
- } else {
- aty_st_pll(PLL_MACRO_CNTL, 0xd5);
- aty_st_pll(PLL_REF_DIV, 0x21);
- aty_st_pll(PLL_GEN_CNTL, 0xc4);
- aty_st_pll(MCLK_FB_DIV, 0xda);
- aty_st_pll(PLL_VCLK_CNTL, 0x03);
- /* offset actually holds clock values */
- aty_st_pll(VCLK_POST_DIV, init->offset[0]);
- aty_st_pll(VCLK0_FB_DIV, init->offset[1]);
- aty_st_pll(VCLK1_FB_DIV, 0x8e);
- aty_st_pll(VCLK2_FB_DIV, 0x9e);
- aty_st_pll(VCLK3_FB_DIV, 0xc6);
- aty_st_pll(PLL_TEST_CTRL, 0x0);
- aty_st_pll(PLL_XCLK_CNTL, init->offset[2]);
- aty_st_pll(12, 0xa0);
- aty_st_pll(13, 0x1b);
- }
- break;
- default:
- RGB514_Program(par->cmode);
- aty_WaitIdleEmpty();
- aty_st_514(0x06, 0x02);
- aty_st_514(0x10, 0x01);
- aty_st_514(0x70, 0x01);
- aty_st_514(0x8f, 0x1f);
- aty_st_514(0x03, 0x00);
- aty_st_514(0x05, 0x00);
- aty_st_514(0x20, init->clock_val[0]);
- aty_st_514(0x21, init->clock_val[1]);
- break;
- }
+ if (fb->cursor->vbl_cnt && --fb->cursor->vbl_cnt == 0) {
+ fb->cursor->on ^= 1;
+ aty_set_cursor(fb);
+ fb->cursor->vbl_cnt = fb->cursor->blink_rate;
+ }
- aty_ld_8(DAC_REGS); /* clear counter */
- aty_WaitIdleEmpty();
+out:
+ fb->cursor->timer->expires = jiffies + (HZ / 50);
+ add_timer(fb->cursor->timer);
+}
- aty_st_le32(CRTC_H_TOTAL_DISP, init->crtc_h_tot_disp);
- aty_st_le32(CRTC_H_SYNC_STRT_WID, init->crtc_h_sync_strt_wid[par->cmode]);
- aty_st_le32(CRTC_V_TOTAL_DISP, init->crtc_v_tot_disp);
- aty_st_le32(CRTC_V_SYNC_STRT_WID, init->crtc_v_sync_strt_wid);
+static void
+atyfb_cursor(struct display *d, int mode, int x, int y)
+{
+ struct fb_info_aty *fb = (struct fb_info_aty *)d->fb_info;
+ struct aty_cursor *c = fb->cursor;
- aty_st_8(CLOCK_CNTL, 0);
- aty_st_8(CLOCK_CNTL, CLOCK_STROBE);
+ if (!c)
+ return;
- aty_st_le32(CRTC_VLINE_CRNT_VLINE, 0);
+#ifdef __sparc__
+ if (fb->mmaped && currcon == fb->vtconsole)
+ return;
+#endif
- set_off_pitch(par);
+ x *= d->fontwidth;
+ y *= d->fontheight;
+ if (c->pos.x == x && c->pos.y == y && (mode == CM_ERASE) == !c->on)
+ return;
- if (chip_type == MACH64_GT_ID) {
- aty_st_le32(BUS_CNTL, 0x7b23a040);
+ c->enable = 0;
+ c->pos.x = x;
+ c->pos.y = y;
- /* need to set DSP values !! assume sdram */
- i = init->crtc_gen_cntl[0] - (0x100000 * par->cmode);
- if ( vram_type == 5 )
- i = init->crtc_gen_cntl[1] - (0x100000 * par->cmode);
- aty_st_le32(DSP_CONFIG, i);
+ switch (mode) {
+ case CM_ERASE:
+ c->on = 0;
+ aty_set_cursor(fb);
+ break;
- i = aty_ld_le32(MEM_CNTL) & MEM_SIZE_ALIAS;
- if ( vram_type == 5 ) {
- i |= ((1 * par->cmode) << 26) | 0x4215b0;
- aty_st_le32(DSP_ON_OFF,sgram_dsp[par->vmode-1][par->cmode]);
+ case CM_DRAW:
+ case CM_MOVE:
+ c->on = 1;
+ aty_set_cursor(fb);
- //aty_st_le32(CLOCK_CNTL,8192);
- } else {
- i |= ((1 * par->cmode) << 26) | 0x300090;
- aty_st_le32(DSP_ON_OFF, init->mem_cntl[par->cmode]);
+ if (!c->timer) {
+ c->timer = kmalloc(sizeof(*c->timer), GFP_KERNEL);
+ if (!c->timer)
+ return;
+
+ c->blink_rate = DEFAULT_CURSOR_BLINK_RATE;
+
+ init_timer(c->timer);
+ c->timer->expires = jiffies + (HZ / 50);
+ c->timer->data = (unsigned long)fb;
+ c->timer->function = aty_cursor_timer_handler;
+ add_timer(c->timer);
+ }
+
+ c->vbl_cnt = c->blink_rate;
+ c->enable = 1;
+ break;
}
+}
- aty_st_le32(MEM_CNTL, i);
- aty_st_le32(EXT_MEM_CNTL, 0x5000001);
+static int
+atyfb_set_font(struct display *d, int width, int height)
+{
+ struct fb_info_aty *fb = (struct fb_info_aty *)d->fb_info;
+ struct aty_cursor *c = fb->cursor;
+ int i, j;
+
+ if (c) {
+ if (!width || !height) {
+ width = 8;
+ height = 16;
+ }
- /* if (total_vram > 0x400000)
- i |= 0x538; this not been verified on > 4Megs!! */
- } else {
+ c->offset = fb->total_vram - 0x1000;
+ c->hot.x = 0;
+ c->hot.y = 0;
+ c->size.x = width;
+ c->size.y = height;
-/* The magic constant below translates into:
-* 5 = No RDY delay, 1 wait st for mem write, increment during burst transfer
-* 9 = DAC access delayed, 1 wait state for DAC
-* 0 = Disables interupts for FIFO errors
-* e = Allows FIFO to generate 14 wait states before generating error
-* 1 = DAC snooping disabled, ROM disabled
-* 0 = ROM page at 0 (disabled so doesn't matter)
-* f = 15 ROM wait states (disabled so doesn't matter)
-* f = 15 BUS wait states (I'm not sure this applies to PCI bus types)
-* at some point it would be good to experiment with bench marks to see if
-* we can gain some speed by fooling with the wait states etc.
-*/
- if (chip_type == MACH64_VT_ID)
- aty_st_le32(BUS_CNTL, 0x680000f9);
- else
- aty_st_le32(BUS_CNTL, 0x590e10ff);
+ memset(c->bits, 0xff, sizeof(c->bits));
+ memset(c->mask, 0, sizeof(c->mask));
- switch (total_vram) {
- case 0x00100000:
- aty_st_le32(MEM_CNTL, vt_mem_cntl[0][par->cmode]);
- break;
- case 0x00200000:
- aty_st_le32(MEM_CNTL, vt_mem_cntl[1][par->cmode]);
- break;
- case 0x00400000:
- aty_st_le32(MEM_CNTL, vt_mem_cntl[2][par->cmode]);
- break;
- default:
- i = aty_ld_le32(MEM_CNTL) & 0x000F;
- aty_st_le32(MEM_CNTL,
- (init->mem_cntl[par->cmode] & 0xFFFFFFF0) | i);
+ for (i = 0, j = width; j >= 0; j -= 8, i++) {
+ c->mask[i][height-2] = (j >= 8) ? 0xff : (0xff << (8 - j));
+ c->mask[i][height-1] = (j >= 8) ? 0xff : (0xff << (8 - j));
}
+
+ aty_set_cursor_color(fb, cursor_pixel_map, cursor_color_map,
+ cursor_color_map, cursor_color_map);
+ aty_set_cursor_shape(fb);
+ }
+ return 1;
+}
+
+
+
+
+/* ------------------------------------------------------------------------- */
+
+ /*
+ * CRTC programming
+ */
+
+static void aty_set_crtc(const struct fb_info_aty *info,
+ const struct crtc *crtc)
+{
+ aty_st_le32(CRTC_H_TOTAL_DISP, crtc->h_tot_disp, info);
+ aty_st_le32(CRTC_H_SYNC_STRT_WID, crtc->h_sync_strt_wid, info);
+ aty_st_le32(CRTC_V_TOTAL_DISP, crtc->v_tot_disp, info);
+ aty_st_le32(CRTC_V_SYNC_STRT_WID, crtc->v_sync_strt_wid, info);
+ aty_st_le32(CRTC_VLINE_CRNT_VLINE, 0, info);
+ aty_st_le32(CRTC_OFF_PITCH, crtc->off_pitch, info);
+ aty_st_le32(CRTC_GEN_CNTL, crtc->gen_cntl, info);
+}
+
+static int aty_var_to_crtc(const struct fb_info_aty *info,
+ const struct fb_var_screeninfo *var,
+ struct crtc *crtc)
+{
+ u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp;
+ u32 left, right, upper, lower, hslen, vslen, sync, vmode;
+ u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;
+ u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol;
+ u32 pix_width, dp_pix_width, dp_chain_mask;
+
+ /* input */
+ xres = var->xres;
+ yres = var->yres;
+ vxres = var->xres_virtual;
+ vyres = var->yres_virtual;
+ xoffset = var->xoffset;
+ yoffset = var->yoffset;
+ bpp = var->bits_per_pixel;
+ left = var->left_margin;
+ right = var->right_margin;
+ upper = var->upper_margin;
+ lower = var->lower_margin;
+ hslen = var->hsync_len;
+ vslen = var->vsync_len;
+ sync = var->sync;
+ vmode = var->vmode;
+
+ /* convert (and round up) and validate */
+ xres = (xres+7) & ~7;
+ xoffset = (xoffset+7) & ~7;
+ vxres = (vxres+7) & ~7;
+ if (vxres < xres+xoffset)
+ vxres = xres+xoffset;
+ h_disp = xres/8-1;
+ if (h_disp > 0xff)
+ FAIL("h_disp too large");
+ h_sync_strt = h_disp+(right/8);
+ if (h_sync_strt > 0x1ff)
+ FAIL("h_sync_start too large");
+ h_sync_dly = right & 7;
+ h_sync_wid = (hslen+7)/8;
+ if (h_sync_wid > 0x1f)
+ FAIL("h_sync_wid too large");
+ h_total = h_sync_strt+h_sync_wid+(h_sync_dly+left+7)/8;
+ if (h_total > 0x1ff)
+ FAIL("h_total too large");
+ h_sync_pol = sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
+
+ if (vyres < yres+yoffset)
+ vyres = yres+yoffset;
+ v_disp = yres-1;
+ if (v_disp > 0x7ff)
+ FAIL("v_disp too large");
+ v_sync_strt = v_disp+lower;
+ if (v_sync_strt > 0x7ff)
+ FAIL("v_sync_strt too large");
+ v_sync_wid = vslen;
+ if (v_sync_wid > 0x1f)
+ FAIL("v_sync_wid too large");
+ v_total = v_sync_strt+v_sync_wid+upper;
+ if (v_total > 0x7ff)
+ FAIL("v_total too large");
+ v_sync_pol = sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
+
+ if (bpp <= 8) {
+ bpp = 8;
+ pix_width = CRTC_PIX_WIDTH_8BPP;
+ dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP | BYTE_ORDER_LSB_TO_MSB;
+ dp_chain_mask = 0x8080;
+ } else if (bpp <= 16) {
+ bpp = 16;
+ pix_width = CRTC_PIX_WIDTH_15BPP;
+ dp_pix_width = HOST_15BPP | SRC_15BPP | DST_15BPP |
+ BYTE_ORDER_LSB_TO_MSB;
+ dp_chain_mask = 0x4210;
+ } else if ((bpp <= 24) && (Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID)) {
+ bpp = 24;
+ pix_width = CRTC_PIX_WIDTH_24BPP;
+ dp_pix_width = HOST_8BPP | SRC_8BPP | DST_8BPP | BYTE_ORDER_LSB_TO_MSB;
+ dp_chain_mask = 0x8080;
+ } else if (bpp <= 32) {
+ bpp = 32;
+ pix_width = CRTC_PIX_WIDTH_32BPP;
+ dp_pix_width = HOST_32BPP | SRC_32BPP | DST_32BPP |
+ BYTE_ORDER_LSB_TO_MSB;
+ dp_chain_mask = 0x8080;
+ } else
+ FAIL("invalid bpp");
+
+ if (vxres*vyres*bpp/8 > info->total_vram)
+ FAIL("not enough video RAM");
+
+ if ((vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+ FAIL("invalid vmode");
+
+ /* output */
+ crtc->vxres = vxres;
+ crtc->vyres = vyres;
+ crtc->xoffset = xoffset;
+ crtc->yoffset = yoffset;
+ crtc->bpp = bpp;
+ crtc->h_tot_disp = h_total | (h_disp<<16);
+ crtc->h_sync_strt_wid = (h_sync_strt & 0xff) | (h_sync_dly<<8) |
+ ((h_sync_strt & 0x100)<<4) | (h_sync_wid<<16) |
+ (h_sync_pol<<21);
+ crtc->v_tot_disp = v_total | (v_disp<<16);
+ crtc->v_sync_strt_wid = v_sync_strt | (v_sync_wid<<16) | (v_sync_pol<<21);
+ crtc->off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19);
+ crtc->gen_cntl = pix_width | CRTC_EXT_DISP_EN | CRTC_ENABLE;
+ if ((Gx == CT_CHIP_ID) || (Gx == ET_CHIP_ID) ||
+ ((Gx == VT_CHIP_ID) && !(Rev & 0x03)) ||
+ ((Gx == GT_CHIP_ID) && !(Rev & 0x03))) {
+ /* Not VTB/GTB */
+ /* FIXME: magic FIFO values */
+ crtc->gen_cntl |= aty_ld_le32(CRTC_GEN_CNTL, info) & 0x000e0000;
}
-/* These magic constants are harder to figure out
-* on the vt chipset bit 2 set makes the screen brighter
-* and bit 15 makes the screen black! But nothing else
-* seems to matter for the vt DAC_CNTL
-*/
- switch (chip_type) {
- case MACH64_GT_ID:
- i = 0x86010102;
+ crtc->dp_pix_width = dp_pix_width;
+ crtc->dp_chain_mask = dp_chain_mask;
+
+ return 0;
+}
+
+static void aty_set_dac_514(const struct fb_info_aty *info, u32 bpp)
+{
+ static struct {
+ u8 pixel_dly;
+ u8 misc2_cntl;
+ u8 pixel_rep;
+ u8 pixel_cntl_index;
+ u8 pixel_cntl_v1;
+ } tab[3] = {
+ { 0, 0x41, 0x03, 0x71, 0x45 }, /* 8 bpp */
+ { 0, 0x45, 0x04, 0x0c, 0x01 }, /* 555 */
+ { 0, 0x45, 0x06, 0x0e, 0x00 }, /* XRGB */
+ };
+ int i;
+
+ switch (bpp) {
+ case 8:
+ default:
+ i = 0;
break;
- case MACH64_VT_ID:
- i = 0x87010184;
+ case 16:
+ i = 1;
break;
- default:
- i = 0x47012100;
+ case 32:
+ i = 2;
break;
}
+ aty_st_514(0x90, 0x00, info); /* VRAM Mask Low */
+ aty_st_514(0x04, tab[i].pixel_dly, info); /* Horizontal Sync Control */
+ aty_st_514(0x05, 0x00, info); /* Power Management */
+ aty_st_514(0x02, 0x01, info); /* Misc Clock Control */
+ aty_st_514(0x71, tab[i].misc2_cntl, info); /* Misc Control 2 */
+ aty_st_514(0x0a, tab[i].pixel_rep, info); /* Pixel Format */
+ aty_st_514(tab[i].pixel_cntl_index, tab[i].pixel_cntl_v1, info);
+ /* Misc Control 2 / 16 BPP Control / 32 BPP Control */
+}
- aty_st_le32(DAC_CNTL, i);
- aty_st_8(DAC_MASK, 0xff);
-
- switch (par->cmode) {
- case CMODE_16:
- i = CRTC_PIX_WIDTH_15BPP; break;
- /*case CMODE_24: */
- case CMODE_32:
- i = CRTC_PIX_WIDTH_32BPP; break;
- case CMODE_8:
+static int aty_crtc_to_var(const struct crtc *crtc,
+ struct fb_var_screeninfo *var)
+{
+ u32 xres, yres, bpp, left, right, upper, lower, hslen, vslen, sync;
+ u32 h_total, h_disp, h_sync_strt, h_sync_dly, h_sync_wid, h_sync_pol;
+ u32 v_total, v_disp, v_sync_strt, v_sync_wid, v_sync_pol;
+ u32 pix_width;
+
+ /* input */
+ h_total = crtc->h_tot_disp & 0x1ff;
+ h_disp = (crtc->h_tot_disp>>16) & 0xff;
+ h_sync_strt = (crtc->h_sync_strt_wid & 0xff) |
+ ((crtc->h_sync_strt_wid>>4) & 0x100);
+ h_sync_dly = (crtc->h_sync_strt_wid>>8) & 0x7;
+ h_sync_wid = (crtc->h_sync_strt_wid>>16) & 0x1f;
+ h_sync_pol = (crtc->h_sync_strt_wid>>21) & 0x1;
+ v_total = crtc->v_tot_disp & 0x7ff;
+ v_disp = (crtc->v_tot_disp>>16) & 0x7ff;
+ v_sync_strt = crtc->v_sync_strt_wid & 0x7ff;
+ v_sync_wid = (crtc->v_sync_strt_wid>>16) & 0x1f;
+ v_sync_pol = (crtc->v_sync_strt_wid>>21) & 0x1;
+ pix_width = crtc->gen_cntl & CRTC_PIX_WIDTH_MASK;
+
+ /* convert */
+ xres = (h_disp+1)*8;
+ yres = v_disp+1;
+ left = (h_total-h_sync_strt-h_sync_wid)*8-h_sync_dly;
+ right = (h_sync_strt-h_disp)*8;
+ hslen = h_sync_wid*8;
+ upper = v_total-v_sync_strt-v_sync_wid;
+ lower = v_sync_strt-v_disp;
+ vslen = v_sync_wid;
+ sync = (h_sync_pol ? 0 : FB_SYNC_HOR_HIGH_ACT) |
+ (v_sync_pol ? 0 : FB_SYNC_VERT_HIGH_ACT);
+
+ switch (pix_width) {
+#if 0
+ case CRTC_PIX_WIDTH_4BPP:
+ bpp = 4;
+ var->red.offset = 0;
+ var->red.length = 8;
+ var->green.offset = 0;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ break;
+#endif
+ case CRTC_PIX_WIDTH_8BPP:
+ bpp = 8;
+ var->red.offset = 0;
+ var->red.length = 8;
+ var->green.offset = 0;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ break;
+ case CRTC_PIX_WIDTH_15BPP: /* RGB 555 */
+ bpp = 16;
+ var->red.offset = 10;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 5;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ break;
+#if 0
+ case CRTC_PIX_WIDTH_16BPP: /* RGB 565 */
+ bpp = 16;
+ var->red.offset = 11;
+ var->red.length = 5;
+ var->green.offset = 6;
+ var->green.length = 6;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ break;
+#endif
+ case CRTC_PIX_WIDTH_24BPP: /* RGB 888 */
+ bpp = 24;
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ break;
+ case CRTC_PIX_WIDTH_32BPP: /* ARGB 8888 */
+ bpp = 32;
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->transp.offset = 24;
+ var->transp.length = 8;
+ break;
default:
- i = CRTC_PIX_WIDTH_8BPP; break;
+ FAIL("Invalid pixel width");
}
- if (chip_type != MACH64_GT_ID) {
- aty_st_le32(CRTC_INT_CNTL, 0x00000002);
- aty_st_le32(GEN_TEST_CNTL, GUI_ENGINE_ENABLE | BLOCK_WRITE_ENABLE); /* gui_en block_en */
- i |= init->crtc_gen_cntl[par->cmode];
- }
- /* Gentlemen, start your crtc engine */
- aty_st_le32(CRTC_GEN_CNTL, CRTC_EXT_DISP_EN | CRTC_ENABLE | i);
+ /* output */
+ var->xres = xres;
+ var->yres = yres;
+ var->xres_virtual = crtc->vxres;
+ var->yres_virtual = crtc->vyres;
+ var->bits_per_pixel = bpp;
+ var->xoffset = crtc->xoffset;
+ var->yoffset = crtc->yoffset;
+ var->left_margin = left;
+ var->right_margin = right;
+ var->upper_margin = upper;
+ var->lower_margin = lower;
+ var->hsync_len = hslen;
+ var->vsync_len = vslen;
+ var->sync = sync;
+ var->vmode = FB_VMODE_NONINTERLACED;
-#ifdef CONFIG_FB_COMPAT_XPMAC
- display_info.height = vmode_attrs[par->vmode-1].vres;
- display_info.width = vmode_attrs[par->vmode-1].hres;
- display_info.depth = 8<<par->cmode;
- display_info.pitch = par->vxres<<par->cmode;
- display_info.mode = par->vmode;
- strcpy(display_info.name, atyfb_name);
- display_info.fb_address =
- iopa(((chip_type != MACH64_GT_ID) ?
- frame_buffer + init->offset[par->cmode] : frame_buffer));
- display_info.cmap_adr_address = iopa((unsigned long)&aty_cmap_regs->windex);
- display_info.cmap_data_address = iopa((unsigned long)&aty_cmap_regs->lut);
- display_info.disp_reg_address = iopa(ati_regbase);
-#endif /* CONFIG_FB_COMPAT_XPMAC) */
+ return 0;
}
+/* ------------------------------------------------------------------------- */
/*
- * Open/Release the frame buffer device
+ * PLL programming (Mach64 GX family)
+ *
+ * FIXME: use function pointer tables instead of switch statements
*/
-static int atyfb_open(struct fb_info *info)
+static void aty_set_pll_gx(const struct fb_info_aty *info,
+ const struct pll_gx *pll)
+{
+ switch (info->clk_type) {
+ case CLK_ATI18818_1:
+ aty_st_8(CLOCK_CNTL, pll->m, info);
+ break;
+ case CLK_IBMRGB514:
+ aty_st_514(0x06, 0x02, info); /* DAC Operation */
+ aty_st_514(0x10, 0x01, info); /* PLL Control 1 */
+ aty_st_514(0x70, 0x01, info); /* Misc Control 1 */
+ aty_st_514(0x8f, 0x1f, info); /* PLL Ref. Divider Input */
+ aty_st_514(0x03, 0x00, info); /* Sync Control */
+ aty_st_514(0x05, 0x00, info); /* Power Management */
+ aty_st_514(0x20, pll->m, info); /* F0 / M0 */
+ aty_st_514(0x21, pll->m, info); /* F1 / N0 */
+ break;
+ }
+}
+static int aty_var_to_pll_18818(const struct fb_var_screeninfo *var,
+ struct pll_gx *pll)
{
/*
- * Nothing, only a usage count for the moment
+ * FIXME: use real calculations instead of using fixed values from the old
+ * driver
*/
-
- MOD_INC_USE_COUNT;
- return(0);
+ 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;
+
+ for (set = 0; set < sizeof(ATI18818_clocks)/sizeof(*ATI18818_clocks);
+ set++)
+ if (var->pixclock <= ATI18818_clocks[set].ps_lim) {
+ pll->m = ATI18818_clocks[set].mode;
+ pll->n = ATI18818_clocks[set].prog;
+ return 0;
+ }
+ return -EINVAL;
}
-static int atyfb_release(struct fb_info *info)
+static int aty_var_to_pll_514(const struct fb_var_screeninfo *var,
+ struct pll_gx *pll)
{
- MOD_DEC_USE_COUNT;
- return(0);
+ /*
+ * FIXME: use real calculations instead of using fixed values from the old
+ * driver
+ */
+ static struct {
+ u32 limit; /* pixlock rounding limit (arbitrary) */
+ u8 m; /* (df<<6) | vco_div_count */
+ u8 n; /* ref_div_count */
+ } RGB514_clocks[7] = {
+ { 8000, (3<<6) | 20, 9 }, /* 7395 ps / 135.2273 MHz */
+ { 10000, (1<<6) | 19, 3 }, /* 9977 ps / 100.2273 MHz */
+ { 13000, (1<<6) | 2, 3 }, /* 12509 ps / 79.9432 MHz */
+ { 14000, (2<<6) | 8, 7 }, /* 13394 ps / 74.6591 MHz */
+ { 16000, (1<<6) | 44, 6 }, /* 15378 ps / 65.0284 MHz */
+ { 25000, (1<<6) | 15, 5 }, /* 17460 ps / 57.2727 MHz */
+ { 50000, (0<<6) | 53, 7 }, /* 33145 ps / 30.1705 MHz */
+ };
+ int i;
+
+ for (i = 0; i < sizeof(RGB514_clocks)/sizeof(*RGB514_clocks); i++)
+ if (var->pixclock <= RGB514_clocks[i].limit) {
+ pll->m = RGB514_clocks[i].m;
+ pll->n = RGB514_clocks[i].n;
+ return 0;
+ }
+ return -EINVAL;
}
+ /* FIXME: ATI18818?? */
-static int encode_fix(struct fb_fix_screeninfo *fix,
- const struct atyfb_par *par)
+static int aty_pll_gx_to_var(const struct pll_gx *pll,
+ struct fb_var_screeninfo *var)
{
- struct aty_regvals *init;
+ u8 df, vco_div_count, ref_div_count;
+
+ df = pll->m >> 6;
+ vco_div_count = pll->m & 0x3f;
+ ref_div_count = pll->n;
+
+ var->pixclock = (ref_clk_per*(vco_div_count+65)/ref_div_count)>>(3-df);
+
+ return 0;
+}
- memset(fix, 0, sizeof(struct fb_fix_screeninfo));
- strcpy(fix->id, atyfb_name);
- init = get_aty_struct(par->vmode);
/*
- * FIXME: This will cause problems on non-GT chips, because the frame
- * buffer must be aligned to a page
+ * PLL programming (Mach64 CT family)
*/
- fix->smem_start = (char *)((chip_type != MACH64_GT_ID)
- ? frame_buffer + init->offset[par->cmode] : frame_buffer);
- fix->smem_len = (u32)total_vram;
- if (fix->smem_len > 0x7ff000)
- fix->smem_len = 0x7ff000; /* last page is MMIO */
- fix->mmio_start = (char *)(ati_regbase & ~0xfff);
- fix->mmio_len = 4096;
- fix->type = FB_TYPE_PACKED_PIXELS;
- fix->type_aux = 0;
- fix->line_length = par->vxres<<par->cmode;
- fix->visual = par->cmode == CMODE_8 ? FB_VISUAL_PSEUDOCOLOR
- : FB_VISUAL_TRUECOLOR;
- fix->ywrapstep = 0;
- fix->xpanstep = 8;
- fix->ypanstep = 1;
+static void aty_set_pll_ct(const struct fb_info_aty *info,
+ const struct pll_ct *pll)
+{
+#if 0 /* ecd debug */
+printk("PLL_REF_DIV: %02x (%02x)\n",
+ pll->pll_ref_div, aty_ld_pll(PLL_REF_DIV, info));
+printk("PLL_GEN_CNTL: %02x (%02x)\n",
+ pll->pll_gen_cntl, aty_ld_pll(PLL_GEN_CNTL, info));
+printk("MCLK_FB_DIV: %02x (%02x)\n",
+ pll->mclk_fb_div, aty_ld_pll(MCLK_FB_DIV, info));
+printk("PLL_VCLK_CNTL: %02x (%02x)\n",
+ pll->pll_vclk_cntl, aty_ld_pll(PLL_VCLK_CNTL, info));
+printk("VCLK_POST_DIV: %02x (%02x)\n",
+ pll->vclk_post_div, aty_ld_pll(VCLK_POST_DIV, info));
+printk("VCLK0_FB_DIV: %02x (%02x)\n",
+ pll->vclk_fb_div, aty_ld_pll(VCLK0_FB_DIV, info));
+printk("PLL_EXT_CNTL: %02x (%02x)\n",
+ pll->pll_ext_cntl, aty_ld_pll(PLL_EXT_CNTL, info));
+#endif /* ecd debug */
+ aty_st_pll(PLL_REF_DIV, pll->pll_ref_div, info);
+ aty_st_pll(PLL_GEN_CNTL, pll->pll_gen_cntl, info);
+ aty_st_pll(MCLK_FB_DIV, pll->mclk_fb_div, info);
+ aty_st_pll(PLL_VCLK_CNTL, pll->pll_vclk_cntl, info);
+ aty_st_pll(VCLK_POST_DIV, pll->vclk_post_div, info);
+ aty_st_pll(VCLK0_FB_DIV, pll->vclk_fb_div, info);
+ aty_st_pll(PLL_EXT_CNTL, pll->pll_ext_cntl, info);
+
+ if (((Gx == GT_CHIP_ID) && (Rev & 0x03)) || (Gx == GU_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)) {
+ if (info->ram_type >= SDRAM)
+ aty_st_pll(DLL_CNTL, 0xa6, info);
+ else
+ aty_st_pll(DLL_CNTL, 0xa0, info);
+ aty_st_pll(VFC_CNTL, 0x1b, info);
+ aty_st_le32(DSP_CONFIG, pll->dsp_config, info);
+ aty_st_le32(DSP_ON_OFF, pll->dsp_on_off, 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)
+{
+ 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);
+ if (xclks_per_row < (1<<11))
+ FAIL("Dotclock to high");
+ fifo_size = 24;
+ dsp_precision = 0;
+ y = (xclks_per_row*fifo_size)>>11;
+ while (y) {
+ y >>= 1;
+ dsp_precision++;
+ }
+ dsp_precision -= 5;
+ /* fifo_off<<6 */
+ fifo_off = ((xclks_per_row*(fifo_size-1))>>5)+(1<<6);
+
+ if (info->total_vram > 1*1024*1024) {
+ if (info->ram_type >= SDRAM) {
+ /* >1 MB SDRAM */
+ dsp_loop_latency = 8;
+ page_size = 8;
+ } else {
+ /* >1 MB DRAM */
+ dsp_loop_latency = 6;
+ page_size = 9;
+ }
+ } else {
+ if (info->ram_type >= SDRAM) {
+ /* <2 MB SDRAM */
+ dsp_loop_latency = 9;
+ page_size = 10;
+ } else {
+ /* <2 MB DRAM */
+ dsp_loop_latency = 8;
+ page_size = 10;
+ }
+ }
+ /* fifo_on<<6 */
+ if (xclks_per_row >= (page_size<<11))
+ fifo_on = ((2*page_size+1)<<6)+(xclks_per_row>>5);
+ else
+ fifo_on = (3*page_size)<<6;
+
+ dsp_xclks_per_row = xclks_per_row>>dsp_precision;
+ dsp_on = fifo_on>>dsp_precision;
+ dsp_off = fifo_off>>dsp_precision;
+
+ pll->dsp_config = (dsp_xclks_per_row & 0x3fff) |
+ ((dsp_loop_latency & 0xf)<<16) |
+ ((dsp_precision & 7)<<20);
+ pll->dsp_on_off = (dsp_on & 0x7ff) | ((dsp_off & 0x7ff)<<16);
return 0;
}
+static int aty_var_to_pll_ct(const struct fb_info_aty *info,
+ const struct fb_var_screeninfo *var,
+ struct pll_ct *pll)
+{
+ u32 vclk_per, 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 */
-static int decode_var(struct fb_var_screeninfo *var,
- struct atyfb_par *par)
-{
- int xres = var->xres;
- int yres = var->yres;
- int bpp = var->bits_per_pixel;
- struct aty_regvals *init;
-
- /* This should support more video modes */
-
- if (xres <= 512 && yres <= 384)
- par->vmode = VMODE_512_384_60; /* 512x384, 60Hz */
- else if (xres <= 640 && yres <= 480)
- par->vmode = VMODE_640_480_67; /* 640x480, 67Hz */
- else if (xres <= 640 && yres <= 870)
- par->vmode = VMODE_640_870_75P; /* 640x870, 75Hz (portrait) */
- else if (xres <= 768 && yres <= 576)
- par->vmode = VMODE_768_576_50I; /* 768x576, 50Hz (PAL full frame) */
- else if (xres <= 800 && yres <= 600)
- par->vmode = VMODE_800_600_75; /* 800x600, 75Hz */
- else if (xres <= 832 && yres <= 624)
- par->vmode = VMODE_832_624_75; /* 832x624, 75Hz */
- else if (xres <= 1024 && yres <= 768)
- par->vmode = VMODE_1024_768_75; /* 1024x768, 75Hz */
- else if (xres <= 1152 && yres <= 870)
- par->vmode = VMODE_1152_870_75; /* 1152x870, 75Hz */
- else if (xres <= 1280 && yres <= 960)
- par->vmode = VMODE_1280_960_75; /* 1280x960, 75Hz */
- else if (xres <= 1280 && yres <= 1024)
- par->vmode = VMODE_1280_1024_75; /* 1280x1024, 75Hz */
- else
- return -EINVAL;
+ pll->pll_vclk_cntl = 0x03; /* VCLK = PLL_VCLK/VCLKx_POST */
- xres = vmode_attrs[par->vmode-1].hres;
- yres = vmode_attrs[par->vmode-1].vres;
+ vclk_per = var->pixclock;
+ pll_ref_div = info->pll_per*2*255/ref_clk_per;
- if (var->xres_virtual <= xres)
- par->vxres = xres;
+ /* FIXME: use the VTB/GTB /3 post divider if it's better suited */
+ q = ref_clk_per*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;
+ else if (q < 64*8)
+ mclk_post_div = 4;
+ else if (q < 128*8)
+ mclk_post_div = 2;
else
- par->vxres = (var->xres_virtual+7) & ~7;
- if (var->yres_virtual <= yres)
- par->vyres = yres;
+ mclk_post_div = 1;
+ mclk_fb_div = q*mclk_post_div/8;
+
+ /* FIXME: use the VTB/GTB /{3,6,12} post dividers if they're better suited */
+ q = ref_clk_per*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;
+ else if (q < 64*8)
+ vclk_post_div = 4;
+ else if (q < 128*8)
+ vclk_post_div = 2;
else
- par->vyres = var->yres_virtual;
+ vclk_post_div = 1;
+ vclk_fb_div = q*vclk_post_div/8;
- par->xoffset = (var->xoffset+7) & ~7;
- par->yoffset = var->yoffset;
- if (par->xoffset+xres > par->vxres || par->yoffset+yres > par->vyres)
- return -EINVAL;
+ if ((err = aty_dsp_gt(info, mclk_fb_div, mclk_post_div, vclk_fb_div,
+ vclk_post_div, var->bits_per_pixel, pll)))
+ return err;
- if (bpp <= 8)
- par->cmode = CMODE_8;
- else if (bpp <= 16)
- par->cmode = CMODE_16;
- else if (bpp <= 32)
- par->cmode = CMODE_32;
+ if ((((Gx == GT_CHIP_ID) && (Rev & 0x03)) || (Gx == GU_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;
else
- return -EINVAL;
+ pll_gen_cntl = 0x84;
- if (aty_vram_reqd(par) > total_vram)
- return -EINVAL;
+ switch (mclk_post_div) {
+ case 1:
+ mpostdiv = 0;
+ break;
+ case 2:
+ mpostdiv = 1;
+ break;
+ case 3:
+ mpostdiv = 4;
+ break;
+ case 4:
+ mpostdiv = 2;
+ break;
+ case 8:
+ mpostdiv = 3;
+ break;
+ }
+ pll_gen_cntl |= mpostdiv<<4; /* mclk */
+
+ if (Gx == VT_CHIP_ID && (Rev == 0x40 || Rev == 0x48))
+ pll_ext_cntl = 0;
+ else
+ pll_ext_cntl = mpostdiv; /* xclk == mclk */
+
+ switch (vclk_post_div) {
+ case 1:
+ vpostdiv = 0;
+ break;
+ case 2:
+ vpostdiv = 1;
+ break;
+ case 3:
+ vpostdiv = 0;
+ pll_ext_cntl |= 0x10;
+ break;
+ case 4:
+ vpostdiv = 2;
+ break;
+ case 6:
+ vpostdiv = 2;
+ pll_ext_cntl |= 0x10;
+ break;
+ case 8:
+ vpostdiv = 3;
+ break;
+ case 12:
+ vpostdiv = 3;
+ pll_ext_cntl |= 0x10;
+ 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;
+ return 0;
+}
- /* Check if we know about the wanted video mode */
- init = get_aty_struct(par->vmode);
- if (init == NULL || init->crtc_h_sync_strt_wid[par->cmode] == 0 ||
- (chip_type != MACH64_GT_ID &&
- init->crtc_gen_cntl[par->cmode] == 0) ||
- (chip_type == MACH64_GT_ID && (aty_ld_le32(CONFIG_STAT0) & 7) == 5 &&
- init->crtc_gen_cntl[1] == 0))
+static int aty_pll_ct_to_var(const struct pll_ct *pll,
+ struct fb_var_screeninfo *var)
+{
+ 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) >> 1) |
+ (vclk_post_div & 3)];
+ if (vpostdiv == 0)
return -EINVAL;
+ var->pixclock = pll_ref_div*vpostdiv*ref_clk_per/vclk_fb_div/2;
+ return 0;
+}
+
+/* ------------------------------------------------------------------------- */
+
+static void atyfb_set_par(const struct atyfb_par *par,
+ struct fb_info_aty *info)
+{
+ u32 i;
+
+ info->current_par = *par;
+
+ aty_set_crtc(info, &par->crtc);
+ aty_st_8(CLOCK_CNTL, 0, info);
+ aty_st_8(CLOCK_CNTL, CLOCK_STROBE, info);
+
+ if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID)) {
+ switch (info->dac_type) {
+ case DAC_IBMRGB514:
+ aty_set_dac_514(info, par->crtc.bpp);
+ break;
+ case DAC_ATI68860_B:
+ /* FIXME */
+ break;
+ }
+ aty_set_pll_gx(info, &par->pll.gx);
+ aty_st_le32(BUS_CNTL, 0x890e20f1, info);
+ aty_st_le32(DAC_CNTL, 0x47052100, info);
+ } else {
+ aty_set_pll_ct(info, &par->pll.ct);
+ i = aty_ld_le32(MEM_CNTL, info) & 0xf30fffff;
+ if (!(Gx == VT_CHIP_ID && (Rev == 0x40 || Rev == 0x48)))
+ i |= info->mem_refresh_rate << 20;
+ switch (par->crtc.bpp) {
+ case 8:
+ case 24:
+ i |= 0x00000000;
+ break;
+ case 16:
+ i |= 0x04000000;
+ break;
+ case 32:
+ i |= 0x08000000;
+ break;
+ }
+ if ((Gx == CT_CHIP_ID) || (Gx == ET_CHIP_ID)) {
+ aty_st_le32(DAC_CNTL, 0x87010184, info);
+ aty_st_le32(BUS_CNTL, 0x680000f9, info);
+ } else if ((Gx == VT_CHIP_ID) || (Gx == VU_CHIP_ID)) {
+ aty_st_le32(DAC_CNTL, 0x87010184, info);
+ aty_st_le32(BUS_CNTL, 0x680000f9, info);
+ } else {
+ /* GT */
+ aty_st_le32(DAC_CNTL, 0x86010102, info);
+ aty_st_le32(BUS_CNTL, 0x7b23a040, info);
+ aty_st_le32(EXT_MEM_CNTL, 0x5000001, info);
+ }
+ aty_st_le32(MEM_CNTL, i, info);
+ }
+ aty_st_8(DAC_MASK, 0xff, info);
+
+ /* Initialize the graphics engine */
+ if (par->accel_flags & FB_ACCELF_TEXT)
+ init_engine(par, info);
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+ if (console_fb_info == &info->fb_info) {
+ struct fb_var_screeninfo var;
+ int vmode, cmode;
+ display_info.height = ((par->crtc.v_tot_disp>>16) & 0x7ff)+1;
+ display_info.width = (((par->crtc.h_tot_disp>>16) & 0xff)+1)*8;
+ display_info.depth = par->crtc.bpp;
+ display_info.pitch = par->crtc.vxres*par->crtc.bpp/8;
+ atyfb_encode_var(&var, par, info);
+ if (mac_var_to_vmode(&var, &vmode, &cmode))
+ display_info.mode = 0;
+ else
+ display_info.mode = vmode;
+ strcpy(display_info.name, atyfb_name);
+ display_info.fb_address = info->frame_buffer_phys;
+ display_info.cmap_adr_address = info->ati_regbase_phys+0xc0;
+ display_info.cmap_data_address = info->ati_regbase_phys+0xc1;
+ display_info.disp_reg_address = info->ati_regbase_phys;
+ }
+#endif /* CONFIG_FB_COMPAT_XPMAC */
+}
+
+static int atyfb_decode_var(const struct fb_var_screeninfo *var,
+ struct atyfb_par *par,
+ const struct fb_info_aty *info)
+{
+ int err;
+
+ if ((err = aty_var_to_crtc(info, var, &par->crtc)))
+ return err;
+ if ((Gx == GX_PCI_ID) || (Gx == CX_PCI_ID))
+ switch (info->clk_type) {
+ case CLK_ATI18818_1:
+ err = aty_var_to_pll_18818(var, &par->pll.gx);
+ break;
+ case CLK_IBMRGB514:
+ err = aty_var_to_pll_514(var, &par->pll.gx);
+ break;
+ }
+ else
+ err = aty_var_to_pll_ct(info, var, &par->pll.ct);
+ if (err)
+ return err;
+
+ if (var->accel_flags & FB_ACCELF_TEXT)
+ par->accel_flags = FB_ACCELF_TEXT;
+ else
+ par->accel_flags = 0;
#if 0
if (!fbmon_valid_timings(pixclock, htotal, vtotal, info))
@@ -872,106 +1747,192 @@ static int decode_var(struct fb_var_screeninfo *var,
return 0;
}
-static int encode_var(struct fb_var_screeninfo *var,
- const struct atyfb_par *par)
+static int atyfb_encode_var(struct fb_var_screeninfo *var,
+ const struct atyfb_par *par,
+ const struct fb_info_aty *info)
{
+ int err;
+
memset(var, 0, sizeof(struct fb_var_screeninfo));
- var->xres = vmode_attrs[par->vmode-1].hres;
- var->yres = vmode_attrs[par->vmode-1].vres;
- var->xres_virtual = par->vxres;
- var->yres_virtual = par->vyres;
- var->xoffset = par->xoffset;
- var->yoffset = par->yoffset;
- var->grayscale = 0;
- switch (par->cmode) {
- case CMODE_8:
- var->bits_per_pixel = 8;
- var->red.offset = 0;
- var->red.length = 8;
- var->green.offset = 0;
- var->green.length = 8;
- var->blue.offset = 0;
- var->blue.length = 8;
- var->transp.offset = 0;
- var->transp.length = 0;
- break;
- case CMODE_16: /* RGB 555 */
- var->bits_per_pixel = 16;
- var->red.offset = 10;
- var->red.length = 5;
- var->green.offset = 5;
- var->green.length = 5;
- var->blue.offset = 0;
- var->blue.length = 5;
- var->transp.offset = 0;
- var->transp.length = 0;
- break;
- case CMODE_32: /* RGB 888 */
- var->bits_per_pixel = 32;
- var->red.offset = 16;
- var->red.length = 8;
- var->green.offset = 8;
- var->green.length = 8;
- var->blue.offset = 0;
- var->blue.length = 8;
- var->transp.offset = 24;
- var->transp.length = 8;
- break;
- }
- var->red.msb_right = 0;
- var->green.msb_right = 0;
- var->blue.msb_right = 0;
- var->transp.msb_right = 0;
- var->nonstd = 0;
- var->activate = 0;
+ if ((err = aty_crtc_to_var(&par->crtc, var)))
+ return err;
+ if ((Gx == GX_PCI_ID) || (Gx == CX_PCI_ID))
+ err = aty_pll_gx_to_var(&par->pll.gx, var);
+ else
+ err = aty_pll_ct_to_var(&par->pll.ct, var);
+ if (err)
+ return err;
+
var->height = -1;
var->width = -1;
- var->accel = /* FB_ACCEL_ATY */ 0;
- var->vmode = FB_VMODE_NONINTERLACED;
- var->left_margin = var->right_margin = 64; /* guesses */
- var->upper_margin = var->lower_margin = 32;
- var->hsync_len = 64;
- var->vsync_len = 2;
-
- /* no long long support in the kernel :-( */
- /* this splittig trick will work if xres > 232 */
- var->pixclock = 1000000000/
- (var->left_margin+var->xres+var->right_margin+var->hsync_len);
- var->pixclock *= 1000;
- var->pixclock /= vmode_attrs[par->vmode-1].vfreq*
- (var->upper_margin+var->yres+var->lower_margin+var->vsync_len);
- var->sync = 0;
+ var->accel_flags = par->accel_flags;
return 0;
}
-static void init_par(struct atyfb_par *par, int vmode, int cmode)
+
+static void set_off_pitch(struct atyfb_par *par,
+ const struct fb_info_aty *info)
{
- par->vmode = vmode;
- par->cmode = cmode;
- par->vxres = vmode_attrs[vmode-1].hres;
- par->vyres = vmode_attrs[vmode-1].vres;
- par->xoffset = 0;
- par->yoffset = 0;
+ u32 xoffset = par->crtc.xoffset;
+ u32 yoffset = par->crtc.yoffset;
+ u32 vxres = par->crtc.vxres;
+ u32 bpp = par->crtc.bpp;
+
+ par->crtc.off_pitch = ((yoffset*vxres+xoffset)*bpp/64) | (vxres<<19);
+ aty_st_le32(CRTC_OFF_PITCH, par->crtc.off_pitch, info);
+}
+
+
+ /*
+ * Open/Release the frame buffer device
+ */
+
+static int atyfb_open(struct fb_info *info, int user)
+
+{
+#ifdef __sparc__
+ struct fb_info_aty *fb = (struct fb_info_aty *)info;
+
+ if (user) {
+ if (fb->open)
+ return -EBUSY;
+ fb->mmaped = 0;
+ fb->open = 1;
+ fb->vtconsole = -1;
+ } else {
+ fb->consolecnt++;
+ }
+#endif
+ MOD_INC_USE_COUNT;
+ return(0);
+}
+
+static int atyfb_release(struct fb_info *info, int user)
+{
+#ifdef __sparc__
+ struct fb_info_aty *fb = (struct fb_info_aty *)info;
+
+ if (user) {
+ if (fb->vtconsole != -1)
+ vt_cons[fb->vtconsole]->vc_mode = KD_TEXT;
+ fb->open = 0;
+ fb->mmaped = 0;
+ fb->vtconsole = -1;
+ } else {
+ fb->consolecnt--;
+ }
+#endif
+ MOD_DEC_USE_COUNT;
+ return(0);
}
+static int encode_fix(struct fb_fix_screeninfo *fix,
+ const struct atyfb_par *par,
+ const struct fb_info_aty *info)
+{
+ memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+
+ strcpy(fix->id, atyfb_name);
+ fix->smem_start = (char *)info->frame_buffer_phys;
+ fix->smem_len = (u32)info->total_vram;
+
+#ifdef __LITTLE_ENDIAN
+ /*
+ * Last page of 8 MB little-endian aperture is MMIO
+ * FIXME: we should use the auxiliary aperture instead so we can acces the
+ * full 8 MB of video RAM on 8 MB boards
+ */
+ if (fix->smem_len > 0x800000-GUI_RESERVE)
+ fix->smem_len = 0x800000-GUI_RESERVE;
+#endif
+ /*
+ * Reg Block 0 (CT-compatible block) is at ati_regbase_phys
+ * 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_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_len = 0x400;
+ fix->accel = FB_ACCEL_ATI_MACH64CT;
+ } else if ((Gx == VT_CHIP_ID) || (Gx == VU_CHIP_ID)) {
+ fix->mmio_start = (char *)(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_len = 0x800;
+ fix->accel = FB_ACCEL_ATI_MACH64GT;
+ }
+ fix->type = FB_TYPE_PACKED_PIXELS;
+ fix->type_aux = 0;
+ fix->line_length = par->crtc.vxres*par->crtc.bpp/8;
+ fix->visual = par->crtc.bpp <= 8 ? FB_VISUAL_PSEUDOCOLOR
+ : FB_VISUAL_DIRECTCOLOR;
+ fix->ywrapstep = 0;
+ fix->xpanstep = 8;
+ fix->ypanstep = 1;
+
+ return 0;
+}
+
+
+struct fb_var_screeninfo default_var = {
+ /* 640x480, 60 Hz, Non-Interlaced (25.175 MHz dotclock) */
+ 640, 480, 640, 480, 0, 0, 8, 0,
+ {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+ 0, 0, -1, -1, 0, 39722, 48, 16, 33, 10, 96, 2,
+ 0, FB_VMODE_NONINTERLACED
+};
+
+#ifdef __sparc__
+struct fb_var_screeninfo default_var_1024x768 __initdata = {
+ /* 1024x768, 75 Hz, Non-Interlaced (78.75 MHz dotclock) */
+ 1024, 768, 1024, 768, 0, 0, 8, 0,
+ {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+ 0, 0, -1, -1, 0, 12699, 176, 16, 28, 1, 96, 3,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+};
+
+struct fb_var_screeninfo default_var_1152x900 __initdata = {
+ /* 1152x900, 76 Hz, Non-Interlaced (110.0 MHz dotclock) */
+ 1152, 900, 1152, 900, 0, 0, 8, 0,
+ {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+ 0, 0, -1, -1, 0, 9091, 234, 24, 34, 3, 100, 3,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+};
+
+struct fb_var_screeninfo default_var_1280x1024 __initdata = {
+ /* 1280x1024, 75 Hz, Non-Interlaced (135.00 MHz dotclock) */
+ 1280, 1024, 1280, 1024, 0, 0, 8, 0,
+ {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+ 0, 0, -1, -1, 0, 7408, 248, 16, 38, 1, 144, 3,
+ FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+};
+#endif
+
+
/*
* Get the Fixed Part of the Display
*/
static int atyfb_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info)
+ struct fb_info *fb)
{
+ const struct fb_info_aty *info = (struct fb_info_aty *)fb;
struct atyfb_par par;
if (con == -1)
- par = default_par;
+ par = info->default_par;
else
- decode_var(&fb_display[con].var, &par);
- encode_fix(fix, &par);
+ atyfb_decode_var(&fb_display[con].var, &par, info);
+ encode_fix(fix, &par, info);
return 0;
}
@@ -981,12 +1942,14 @@ static int atyfb_get_fix(struct fb_fix_screeninfo *fix, int con,
*/
static int atyfb_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
+ struct fb_info *fb)
{
+ const struct fb_info_aty *info = (struct fb_info_aty *)fb;
+
if (con == -1)
- encode_var(var, &default_par);
+ atyfb_encode_var(var, &info->default_par, info);
else
- *var=fb_display[con].var;
+ *var = fb_display[con].var;
return 0;
}
@@ -996,23 +1959,23 @@ static int atyfb_get_var(struct fb_var_screeninfo *var, int con,
*/
static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
+ struct fb_info *fb)
{
+ struct fb_info_aty *info = (struct fb_info_aty *)fb;
struct atyfb_par par;
struct display *display;
- int oldxres, oldyres, oldvxres, oldvyres, oldbpp;
- int err;
+ int oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel, accel, err;
int activate = var->activate;
if (con >= 0)
display = &fb_display[con];
else
- display = &fb_disp; /* used during initialization */
+ display = fb->disp; /* used during initialization */
- if ((err = decode_var(var, &par)))
+ if ((err = atyfb_decode_var(var, &par, info)))
return err;
- encode_var(var, &par);
+ atyfb_encode_var(var, &par, (struct fb_info_aty *)info);
if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
oldxres = display->var.xres;
@@ -1020,14 +1983,15 @@ static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
oldvxres = display->var.xres_virtual;
oldvyres = display->var.yres_virtual;
oldbpp = display->var.bits_per_pixel;
+ oldaccel = display->var.accel_flags;
display->var = *var;
if (oldxres != var->xres || oldyres != var->yres ||
oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
- oldbpp != var->bits_per_pixel) {
+ oldbpp != var->bits_per_pixel || oldaccel != var->accel_flags) {
struct fb_fix_screeninfo fix;
- encode_fix(&fix, &par);
- display->screen_base = (u_char *)fix.smem_start;
+ encode_fix(&fix, &par, info);
+ display->screen_base = (char *)info->frame_buffer;
display->visual = fix.visual;
display->type = fix.type;
display->type_aux = fix.type_aux;
@@ -1036,33 +2000,46 @@ static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
display->line_length = fix.line_length;
display->can_soft_blank = 1;
display->inverse = 0;
- switch (par.cmode) {
- case CMODE_8:
-#if 1
- display->dispsw = &fbcon_cfb8;
-#else
- display->dispsw = &fbcon_aty8;
+ accel = var->accel_flags & FB_ACCELF_TEXT;
+ switch (par.crtc.bpp) {
+#ifdef FBCON_HAS_CFB8
+ case 8:
+ *display->dispsw = accel ? fbcon_aty8 : fbcon_cfb8;
+ break;
#endif
+#ifdef FBCON_HAS_CFB16
+ case 16:
+ *display->dispsw = accel ? fbcon_aty16 : fbcon_cfb16;
break;
- case CMODE_16:
- display->dispsw = &fbcon_cfb16;
+#endif
+#ifdef FBCON_HAS_CFB24
+ case 24:
+ *display->dispsw = accel ? fbcon_aty24 : fbcon_cfb24;
break;
- case CMODE_32:
- display->dispsw = &fbcon_cfb32;
+#endif
+#ifdef FBCON_HAS_CFB32
+ case 32:
+ *display->dispsw = accel ? fbcon_aty32 : fbcon_cfb32;
break;
+#endif
default:
display->dispsw = NULL;
break;
}
- if (fb_info.changevar)
- (*fb_info.changevar)(con);
+ display->scrollmode = accel ? 0 : SCROLL_YREDRAW;
+ if (info->fb_info.changevar)
+ (*info->fb_info.changevar)(con);
+ if (info->cursor) {
+ display->dispsw->cursor = atyfb_cursor;
+ display->dispsw->set_font = atyfb_set_font;
+ }
}
if (con == currcon)
- atyfb_set_par(&par);
+ atyfb_set_par(&par, info);
if (oldbpp != var->bits_per_pixel) {
if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
return err;
- do_install_cmap(con, info);
+ do_install_cmap(con, &info->fb_info);
}
}
@@ -1077,20 +2054,21 @@ static int atyfb_set_var(struct fb_var_screeninfo *var, int con,
*/
static int atyfb_pan_display(struct fb_var_screeninfo *var, int con,
- struct fb_info *info)
+ struct fb_info *fb)
{
+ struct fb_info_aty *info = (struct fb_info_aty *)fb;
u32 xres, yres, xoffset, yoffset;
- struct atyfb_par *par = &current_par;
+ struct atyfb_par *par = &info->current_par;
- xres = vmode_attrs[par->vmode-1].hres;
- yres = vmode_attrs[par->vmode-1].vres;
+ xres = (((par->crtc.h_tot_disp>>16) & 0xff)+1)*8;
+ yres = ((par->crtc.v_tot_disp>>16) & 0x7ff)+1;
xoffset = (var->xoffset+7) & ~7;
yoffset = var->yoffset;
- if (xoffset+xres > par->vxres || yoffset+yres > par->vyres)
+ if (xoffset+xres > par->crtc.vxres || yoffset+yres > par->crtc.vyres)
return -EINVAL;
- par->xoffset = xoffset;
- par->yoffset = yoffset;
- set_off_pitch(par);
+ par->crtc.xoffset = xoffset;
+ par->crtc.yoffset = yoffset;
+ set_off_pitch(par, info);
return 0;
}
@@ -1106,9 +2084,10 @@ static int atyfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
info);
else if (fb_display[con].cmap.len) /* non default colormap? */
fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
- else
- fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
- cmap, kspc ? 0 : 2);
+ else {
+ int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
+ fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
+ }
return 0;
}
@@ -1122,8 +2101,8 @@ static int atyfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
int err;
if (!fb_display[con].cmap.len) { /* no colormap allocated? */
- if ((err = fb_alloc_cmap(&fb_display[con].cmap,
- 1<<fb_display[con].var.bits_per_pixel, 0)))
+ int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
+ if ((err = fb_alloc_cmap(&fb_display[con].cmap, size, 0)))
return err;
}
if (con == currcon) /* current console? */
@@ -1141,283 +2120,835 @@ static int atyfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
return -EINVAL;
}
+#ifdef __sparc__
+static int atyfb_mmap(struct fb_info *info, struct file *file,
+ struct vm_area_struct *vma)
+{
+ struct fb_info_aty *fb = (struct fb_info_aty *)info;
+ unsigned int size, page, map_size = 0;
+ unsigned long map_offset = 0;
+ int i;
+
+ if (!fb->mmap_map)
+ return -ENXIO;
+
+ size = vma->vm_end - vma->vm_start;
+ if (vma->vm_offset & ~PAGE_MASK)
+ return -ENXIO;
+
+ /* To stop the swapper from even considering these pages. */
+ vma->vm_flags |= (VM_SHM | VM_LOCKED);
+
+#ifdef __sparc_v9__
+ /* Align it as much as desirable */
+ {
+ int j, max = -1, align;
+
+ map_offset = vma->vm_offset+size;
+ for (i = 0; fb->mmap_map[i].size; i++) {
+ if (fb->mmap_map[i].voff < vma->vm_offset)
+ continue;
+ if (fb->mmap_map[i].voff >= map_offset)
+ break;
+ if (max < 0 ||
+ fb->mmap_map[i].size > fb->mmap_map[max].size)
+ max = i;
+ }
+ if (max >= 0) {
+ j = fb->mmap_map[max].size;
+ if (fb->mmap_map[max].voff + j > map_offset)
+ j = map_offset - fb->mmap_map[max].voff;
+ for (align = 0x400000; align > PAGE_SIZE; align >>= 3)
+ if (j >= align &&
+ !(fb->mmap_map[max].poff & (align - 1)))
+ break;
+ if (align > PAGE_SIZE) {
+ j = align;
+ align = j - ((vma->vm_start
+ + fb->mmap_map[max].voff
+ - vma->vm_offset) & (j - 1));
+ if (align != j) {
+ struct vm_area_struct *vmm;
+
+ vmm = find_vma(current->mm,
+ vma->vm_start);
+ if (!vmm || vmm->vm_start
+ >= vma->vm_end + align) {
+ vma->vm_start += align;
+ vma->vm_end += align;
+ }
+ }
+ }
+ }
+ }
+#endif
+
+ /* Each page, see which map applies */
+ for (page = 0; page < size; ) {
+ map_size = 0;
+ for (i = 0; fb->mmap_map[i].size; i++) {
+ unsigned long start = fb->mmap_map[i].voff;
+ unsigned long end = start + fb->mmap_map[i].size;
+ unsigned long offset = vma->vm_offset + page;
+
+ if (start > offset)
+ continue;
+ if (offset > end)
+ continue;
+
+ map_size = fb->mmap_map[i].size - (offset - start);
+ map_offset = fb->mmap_map[i].poff + (offset - start);
+ break;
+ }
+ if (!map_size) {
+ page += PAGE_SIZE;
+ continue;
+ }
+ if (page + map_size > size)
+ map_size = size - page;
+
+ pgprot_val(vma->vm_page_prot) &= ~(fb->mmap_map[i].prot_mask);
+ pgprot_val(vma->vm_page_prot) |= fb->mmap_map[i].prot_flag;
+
+ if (remap_page_range(vma->vm_start + page, map_offset,
+ map_size, vma->vm_page_prot))
+ return -EAGAIN;
+
+ page += map_size;
+ }
+
+ if (!map_size)
+ return -EINVAL;
- /*
- * Initialisation
- */
+ vma->vm_file = file;
+ file->f_count++;
+ vma->vm_flags |= VM_IO;
-__initfunc(unsigned long atyfb_init(unsigned long mem_start))
-{
-#ifdef __powerpc__
- /* We don't want to be called like this. */
- /* We rely on Open Firmware (offb) instead. */
- return mem_start;
-#else /* !__powerpc__ */
- /* To be merged with Bernd's mach64fb */
- return mem_start;
-#endif /* !__powerpc__ */
+ if (!fb->mmaped) {
+ int lastconsole = 0;
+
+ if (info->display_fg)
+ lastconsole = info->display_fg->vc_num;
+ fb->mmaped = 1;
+ if (fb->consolecnt && fb_display[lastconsole].fb_info == info) {
+ fb->vtconsole = lastconsole;
+ vt_cons[lastconsole]->vc_mode = KD_GRAPHICS;
+ }
+ }
+ return 0;
}
+#endif /* __sparc__ */
+ /*
+ * Initialisation
+ */
-unsigned long atyfb_of_init(unsigned long mem_start, struct device_node *dp)
+__initfunc(static int aty_init(struct fb_info_aty *info, const char *name))
{
- int i, err, sense;
+ u32 chip_id;
+ u32 i;
+ int j, k;
struct fb_var_screeninfo var;
- struct aty_regvals *init;
- unsigned long addr;
- unsigned char bus, devfn;
- unsigned short cmd;
-
- if (dp->next)
- printk("Warning: only using first ATI card detected\n");
- if (dp->n_addrs != 1 && dp->n_addrs != 3)
- printk("Warning: expecting 1 or 3 addresses for ATY (got %d)",
- dp->n_addrs);
-
- ati_regbase = (int)ioremap((0x7ffc00 + dp->addrs[0].address), 0x1000);
- aty_cmap_regs = (struct aty_cmap_regs *)(ati_regbase + 0xC0);
-
- /* enable memory-space accesses using config-space command register */
- if (pci_device_loc(dp, &bus, &devfn) == 0) {
- pcibios_read_config_word(bus, devfn, PCI_COMMAND, &cmd);
- if (cmd != 0xffff) {
- cmd |= PCI_COMMAND_MEMORY;
- pcibios_write_config_word(bus, devfn, PCI_COMMAND, cmd);
+ struct display *disp;
+ const char *chipname = NULL;
+ int pll, mclk;
+#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP)
+ int sense;
+#endif
+
+ info->aty_cmap_regs = (struct aty_cmap_regs *)(info->ati_regbase+0xc0);
+ 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;
+ break;
+ }
+ if (!chipname) {
+ printk("atyfb: Unknown mach64 0x%04x\n", Gx);
+ return 0;
+ } else
+ printk("atyfb: %s [0x%04x rev 0x%2x] ", chipname, Gx, Rev);
+ if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID)) {
+ info->bus_type = (aty_ld_le32(CONFIG_STAT0, info) >> 0) & 0x07;
+ info->ram_type = (aty_ld_le32(CONFIG_STAT0, info) >> 3) & 0x07;
+ /* FIXME: clockchip/RAMDAC probing? */
+#ifdef CONFIG_ATARI
+ info->dac_type = DAC_ATI68860_B;
+ info->clk_type = CLK_ATI18818_1;
+#else
+ info->dac_type = DAC_IBMRGB514;
+ info->clk_type = CLK_IBMRGB514;
+#endif
+ /* FIXME */
+ pll = 135;
+ mclk = 50;
+ } else {
+ info->bus_type = PCI;
+ info->ram_type = (aty_ld_le32(CONFIG_STAT0, info) & 0x07);
+ info->dac_type = DAC_INTERNAL;
+ info->clk_type = CLK_INTERNAL;
+ if ((Gx == CT_CHIP_ID) || (Gx == ET_CHIP_ID)) {
+ pll = 135;
+ mclk = 60;
+ } else {
+ mclk = info->ram_type >= SDRAM ? 67 : 63;
+ if ((Gx == VT_CHIP_ID) && (Rev == 0x08)) {
+ /* VTA3 */
+ pll = 170;
+ } else if (((Gx == VT_CHIP_ID) && ((Rev == 0x40) ||
+ (Rev == 0x48))) ||
+ ((Gx == VT_CHIP_ID) && ((Rev == 0x01) ||
+ (Rev == 0x9a))) ||
+ (Gx == VU_CHIP_ID)) {
+ /* VTA4 or VTB */
+ pll = 200;
+ } else if (Gx == VT_CHIP_ID) {
+ /* other VT */
+ pll = 135;
+ mclk = 63;
+ } else if ((Gx == GT_CHIP_ID) && (Rev & 0x01)) {
+ /* RAGE II */
+ pll = 170;
+ } else if (((Gx == GT_CHIP_ID) && (Rev & 0x02)) ||
+ (Gx == GU_CHIP_ID)) {
+ /* RAGE II+ */
+ pll = 200;
+ } else if ((Gx == GB_CHIP_ID) || (Gx == GD_CHIP_ID) ||
+ (Gx == GI_CHIP_ID) || (Gx == GP_CHIP_ID) ||
+ (Gx == GQ_CHIP_ID)) {
+ /* RAGE PRO */
+ pll = 230;
+ } else {
+ /* other RAGE */
+ pll = 135;
+ mclk = 63;
+ }
}
}
- chip_type = (aty_ld_le32(CONFIG_CHIP_ID) & CFG_CHIP_TYPE);
-
- i = aty_ld_le32(MEM_CNTL);
- if (chip_type != MACH64_GT_ID)
- switch (i & MEM_SIZE_ALIAS) {
+ if (mclk < 44)
+ info->mem_refresh_rate = 0; /* 000 = 10 Mhz - 43 Mhz */
+ else if (mclk < 50)
+ info->mem_refresh_rate = 1; /* 001 = 44 Mhz - 49 Mhz */
+ else if (mclk < 55)
+ info->mem_refresh_rate = 2; /* 010 = 50 Mhz - 54 Mhz */
+ else if (mclk < 66)
+ info->mem_refresh_rate = 3; /* 011 = 55 Mhz - 65 Mhz */
+ else if (mclk < 75)
+ info->mem_refresh_rate = 4; /* 100 = 66 Mhz - 74 Mhz */
+ else if (mclk < 80)
+ info->mem_refresh_rate = 5; /* 101 = 75 Mhz - 79 Mhz */
+ else if (mclk < 100)
+ info->mem_refresh_rate = 6; /* 110 = 80 Mhz - 100 Mhz */
+ else
+ info->mem_refresh_rate = 7; /* 111 = 100 Mhz and above */
+ printk("%d MHz PLL, %d Mhz MCLK\n", pll, mclk);
+ info->pll_per = 1000000/pll;
+ info->mclk_per = 1000000/mclk;
+
+ i = aty_ld_le32(MEM_CNTL, info);
+ if (((Gx == GT_CHIP_ID) && (Rev & 0x03)) || (Gx == GU_CHIP_ID) ||
+ ((Gx == VT_CHIP_ID) && (Rev & 0x01)) || (Gx == VU_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))
+ switch (i & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */
case MEM_SIZE_512K:
- total_vram = 0x80000;
+ info->total_vram = 0x80000;
break;
case MEM_SIZE_1M:
- total_vram = 0x100000;
+ info->total_vram = 0x100000;
break;
- case MEM_SIZE_2M:
- total_vram = 0x200000;
+ case MEM_SIZE_2M_GTB:
+ info->total_vram = 0x200000;
break;
- case MEM_SIZE_4M:
- total_vram = 0x400000;
+ case MEM_SIZE_4M_GTB:
+ info->total_vram = 0x400000;
break;
- case MEM_SIZE_6M:
- total_vram = 0x600000;
+ case MEM_SIZE_6M_GTB:
+ info->total_vram = 0x600000;
break;
- case MEM_SIZE_8M:
- total_vram = 0x800000;
+ case MEM_SIZE_8M_GTB:
+ info->total_vram = 0x800000;
break;
default:
- total_vram = 0x80000;
+ info->total_vram = 0x80000;
}
else
- switch (i & 0xF) { /* 0xF used instead of MEM_SIZE_ALIAS */
+ switch (i & MEM_SIZE_ALIAS) {
case MEM_SIZE_512K:
- total_vram = 0x80000;
+ info->total_vram = 0x80000;
break;
case MEM_SIZE_1M:
- total_vram = 0x100000;
+ info->total_vram = 0x100000;
break;
- case MEM_SIZE_2M_GTB:
- total_vram = 0x200000;
+ case MEM_SIZE_2M:
+ info->total_vram = 0x200000;
break;
- case MEM_SIZE_4M_GTB:
- total_vram = 0x400000;
+ case MEM_SIZE_4M:
+ info->total_vram = 0x400000;
break;
- case MEM_SIZE_6M_GTB:
- total_vram = 0x600000;
+ case MEM_SIZE_6M:
+ info->total_vram = 0x600000;
break;
- case MEM_SIZE_8M_GTB:
- total_vram = 0x800000;
+ case MEM_SIZE_8M:
+ info->total_vram = 0x800000;
break;
default:
- total_vram = 0x80000;
+ info->total_vram = 0x80000;
}
-#if 1
- printk("aty_display_init: node = %p, addrs = ", dp->node);
- printk(" %x(%x)", dp->addrs[0].address, dp->addrs[0].size);
- printk(", intrs =");
- for (i = 0; i < dp->n_intrs; ++i)
- printk(" %x", dp->intrs[i].line);
- printk("\nregbase: %x pci loc: %x:%x total_vram: %x cregs: %p\n",
- (int)ati_regbase, bus, devfn, total_vram, aty_cmap_regs);
-#endif
-
- /* Map in frame buffer */
- addr = dp->addrs[0].address;
-
- /* use the big-endian aperture (??) */
- addr += 0x800000;
- frame_buffer = (unsigned long)__ioremap(addr, 0x800000, _PAGE_WRITETHRU);
-
- if (default_video_mode != -1) {
- sense = read_aty_sense();
- printk("monitor sense = %x\n", sense);
- if (default_video_mode == VMODE_NVRAM) {
- default_video_mode = nvram_read_byte(NV_VMODE);
- init = get_aty_struct(default_video_mode);
- if (default_video_mode <= 0 ||
- default_video_mode > VMODE_MAX || init == 0)
- default_video_mode = VMODE_CHOOSE;
+ if (info->bus_type == ISA)
+ if ((info->total_vram == 0x400000) || (info->total_vram == 0x800000)) {
+ /* protect GUI-regs if complete Aperture is VRAM */
+ info->total_vram -= GUI_RESERVE;
}
- if (default_video_mode == VMODE_CHOOSE)
- default_video_mode = map_monitor_sense(sense);
- init = get_aty_struct(default_video_mode);
- if (!init)
- default_video_mode = VMODE_640_480_60;
+#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP)
+ 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) {
+ 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;
+#else /* !CONFIG_PMAC && !CONFIG_CHRP */
+ var = default_var;
+#endif /* !CONFIG_PMAC && !CONFIG_CHRP */
+ var.accel_flags |= FB_ACCELF_TEXT;
+ if (atyfb_decode_var(&var, &info->default_par, info)) {
+ printk("atyfb: can't set default video mode\n");
+ return 0;
}
- /*
- * Reduce the pixel size if we don't have enough VRAM.
- */
+ if ((Gx == GX_CHIP_ID) || (Gx == CX_CHIP_ID))
+ strcat(atyfb_name, "GX");
+ else if ((Gx == CT_CHIP_ID) || (Gx == ET_CHIP_ID))
+ strcat(atyfb_name, "CT");
+ else if ((Gx == VT_CHIP_ID) || (Gx == VU_CHIP_ID))
+ strcat(atyfb_name, "VT");
+ else
+ strcat(atyfb_name, "GT");
+
+ 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;
+
+ for (j = 0; j < 16; j++) {
+ k = color_table[j];
+ info->palette[j].red = default_red[k];
+ info->palette[j].green = default_grn[k];
+ info->palette[j].blue = default_blu[k];
+ }
+
+ if ((Gx == VT_CHIP_ID) || (Gx == GT_CHIP_ID) || (Gx == GU_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->cursor = kmalloc(sizeof(struct aty_cursor), GFP_ATOMIC);
+ if (info->cursor)
+ memset(info->cursor, 0, sizeof(*info->cursor));
+ }
+
+ disp->dispsw = &info->dispsw;
+ atyfb_set_var(&var, -1, &info->fb_info);
- if (default_color_mode == CMODE_NVRAM)
- default_color_mode = nvram_read_byte(NV_CMODE);
- if (default_color_mode < CMODE_8 ||
- default_color_mode > CMODE_32)
- default_color_mode = CMODE_8;
-
- init_par(&default_par, default_video_mode, default_color_mode);
- while (aty_vram_reqd(&default_par) > total_vram) {
- while (default_color_mode > CMODE_8 &&
- aty_vram_reqd(&default_par) > total_vram) {
- --default_color_mode;
- init_par(&default_par, default_video_mode, default_color_mode);
+ if (register_framebuffer(&info->fb_info) < 0)
+ return 0;
+
+ 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))
+{
+#if defined(CONFIG_FB_OF)
+ /* We don't want to be called like this. */
+ /* We rely on Open Firmware (offb) instead. */
+#elif defined(CONFIG_PCI)
+ struct pci_dev *pdev;
+ struct fb_info_aty *info;
+ unsigned long addr;
+#ifdef __sparc__
+ extern int con_is_present(void);
+ u32 chip_id;
+ int i, j;
+
+ /* Do not attach when we have a serial console. */
+ if (!con_is_present())
+ return;
+#else
+ u16 tmp;
+#endif
+
+ for (pdev = pci_devices; pdev; pdev = pdev->next) {
+ if (((pdev->class >> 16) == PCI_BASE_CLASS_DISPLAY) &&
+ (pdev->vendor == PCI_VENDOR_ID_ATI)) {
+
+ info = kmalloc(sizeof(struct fb_info_aty), GFP_ATOMIC);
+ if (!info) {
+ printk("atyfb_init: can't alloc fb_info_aty\n");
+ return;
+ }
+ 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];
+ if (!addr)
+ continue;
+
+#ifdef __sparc__
+ /*
+ * Map memory-mapped registers.
+ */
+ info->ati_regbase = addr + 0x7ffc00;
+ info->ati_regbase_phys = __pa(addr + 0x7ffc00);
+
+ /*
+ * Map in big-endian aperture.
+ */
+ info->frame_buffer = (unsigned long)(addr + 0x800000);
+ info->frame_buffer_phys = __pa(addr + 0x800000);
+
+ /*
+ * 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++)
+ /* nothing */;
+ j = i + 1;
+
+ info->mmap_map = kmalloc(j * sizeof(*info->mmap_map), GFP_ATOMIC);
+ if (!info->mmap_map) {
+ printk("atyfb_init: can't alloc mmap_map\n");
+ kfree(info);
+ }
+
+ memset(info->mmap_map, 0, j * sizeof(*info->mmap_map));
+ for (i = j = 0; i < 6 && pdev->base_address[i]; i++) {
+ int io, breg = PCI_BASE_ADDRESS_0 + (i << 2);
+ unsigned long base;
+ u32 size, pbase;
+
+ base = pdev->base_address[i];
+
+ io = (base & PCI_BASE_ADDRESS_SPACE)==PCI_BASE_ADDRESS_SPACE_IO;
+
+ 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;
+
+ 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].size = 0x800000;
+ info->mmap_map[j].prot_mask = _PAGE_CACHE;
+ info->mmap_map[j].prot_flag = _PAGE_E|_PAGE_IE;
+ size -= 0x800000;
+ j++;
+ }
+
+ info->mmap_map[j].voff = pbase & PAGE_MASK;
+ info->mmap_map[j].poff = __pa(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;
+ j++;
+ }
+
+ /*
+ * Fix PROMs idea of MEM_CNTL settings...
+ */
+ chip_id = aty_ld_le32(CONFIG_CHIP_ID, info) & CFG_CHIP_TYPE;
+ if ((chip_id & 0xffff) == VT_CHIP_ID && !((chip_id >> 24) & 1)) {
+ u32 mem = aty_ld_le32(MEM_CNTL, info);
+ switch (mem & 0x0f) {
+ case 3:
+ mem = (mem & ~(0x0f)) | 2;
+ break;
+ case 7:
+ mem = (mem & ~(0x0f)) | 3;
+ break;
+ case 9:
+ mem = (mem & ~(0x0f)) | 4;
+ break;
+ case 11:
+ mem = (mem & ~(0x0f)) | 5;
+ break;
+ default:
+ break;
+ }
+ if ((aty_ld_le32(CONFIG_STAT0, info) & 7) >= SDRAM)
+ mem &= ~(0x00f00000);
+ aty_st_le32(MEM_CNTL, mem, info);
+ }
+
+ /*
+ * Set default vmode and cmode from PROM properties.
+ */
+ {
+ struct pcidev_cookie *cookie = pdev->sysdata;
+ int node = cookie->prom_node;
+ int width = prom_getintdefault(node, "width", 1024);
+ int height = prom_getintdefault(node, "height", 768);
+ int depth = prom_getintdefault(node, "depth", 8);
+
+ switch (width) {
+ case 1024:
+ if (height == 768)
+ default_var = default_var_1024x768;
+ break;
+ case 1152:
+ if (height == 900)
+ default_var = default_var_1152x900;
+ break;
+ case 1280:
+ if (height == 1024)
+ default_var = default_var_1280x1024;
+ break;
+ default:
+ break;
+ }
+
+ switch (depth) {
+ case 8:
+ default_var.bits_per_pixel = 8;
+ break;
+ case 16:
+ default_var.bits_per_pixel = 16;
+ break;
+ case 24:
+ default_var.bits_per_pixel = 24;
+ break;
+ case 32:
+ default_var.bits_per_pixel = 32;
+ break;
+ default:
+ break;
+ }
+ }
+
+#else /* __sparc__ */
+
+ info->ati_regbase_phys = 0x7ff000 + addr;
+ info->ati_regbase = (unsigned long)
+ ioremap(info->ati_regbase_phys, 0x1000);
+
+ info->ati_regbase_phys += 0xc00;
+ info->ati_regbase += 0xc00;
+
+ /*
+ * Enable memory-space accesses using config-space
+ * command register.
+ */
+ pci_read_config_word(pdev, PCI_COMMAND, &tmp);
+ if (!(tmp & PCI_COMMAND_MEMORY)) {
+ tmp |= PCI_COMMAND_MEMORY;
+ pci_write_config_word(pdev, PCI_COMMAND, tmp);
+ }
+
+#ifdef __BIG_ENDIAN
+ /* Use the big-endian aperture */
+ addr += 0x800000;
+#endif
+
+ /* Map in frame buffer */
+ info->frame_buffer_phys = addr;
+ info->frame_buffer = (unsigned long)ioremap(addr, 0x800000);
+
+#endif /* __sparc__ */
+
+ if (!aty_init(info, "PCI")) {
+ if (info->mmap_map)
+ kfree(info->mmap_map);
+ kfree(info);
+ }
}
+ }
+#elif defined(CONFIG_ATARI)
+ int m64_num;
+ struct fb_info_aty *info;
+
+ for (m64_num = 0; m64_num < mach64_count; m64_num++) {
+ if (!phys_vmembase[m64_num] || !phys_size[m64_num] ||
+ !phys_guiregbase[m64_num]) {
+ printk(" phys_*[%d] parameters not set => returning early. \n",
+ m64_num);
+ continue;
+ }
+
+ info = kmalloc(sizeof(struct fb_info_aty), GFP_ATOMIC);
+
/*
- * adjust the video mode smaller if there still is not enough VRAM
+ * Map the video memory (physical address given) to somewhere in the
+ * kernel address space.
*/
- if (aty_vram_reqd(&default_par) > total_vram)
- do {
- default_video_mode--;
- init_par(&default_par, default_video_mode, default_color_mode);
- init = get_aty_struct(default_video_mode);
- } while ((init == 0) &&
- (default_video_mode > VMODE_640_480_60));
+ info->frame_buffer = kernel_map(phys_vmembase[m64_num],
+ phys_size[m64_num],
+ KERNELMAP_NOCACHE_SER, NULL);
+ info->frame_buffer_phys = info->frame_buffer;
+ info->ati_regbase = kernel_map(phys_guiregbase[m64_num], 0x10000,
+ KERNELMAP_NOCACHE_SER, NULL)+0xFC00ul;
+ info->ati_regbase_phys = info->ati_regbase;
+
+ if (!aty_init(info, "ISA bus")) {
+ kfree(info);
+ /* This is insufficient! kernel_map has added two large chunks!! */
+ return;
+ }
}
+#endif
+}
- if (chip_type == MACH64_GT_ID && (aty_ld_le32(CONFIG_STAT0) & 7) == 5
- && init->crtc_gen_cntl[1] == 0) {
- default_video_mode = VMODE_640_480_67;
- default_color_mode = CMODE_8;
- init_par(&default_par, default_video_mode, default_color_mode);
- }
+#ifdef CONFIG_FB_OF
+__initfunc(void atyfb_of_init(struct device_node *dp))
+{
+ unsigned long addr;
+ u8 bus, devfn;
+ u16 cmd;
+ struct fb_info_aty *info;
+ int i;
+
+ for (; dp; dp = dp->next) {
+ switch (dp->n_addrs) {
+ case 1:
+ case 3:
+ addr = dp->addrs[0].address;
+ break;
+ case 4:
+ addr = dp->addrs[1].address;
+ break;
+ default:
+ printk("Warning: got %d adresses for ATY:\n", dp->n_addrs);
+ for (i = 0; i < dp->n_addrs; i++)
+ printk(" %08x-%08x", dp->addrs[i].address,
+ dp->addrs[i].address+dp->addrs[i].size-1);
+ if (dp->n_addrs)
+ printk("\n");
+ continue;
+ }
- switch (chip_type) {
- case MACH64_GX_ID:
- strcat(atyfb_name, "GX");
- break;
- case MACH64_VT_ID:
- strcat(atyfb_name, "VT");
- break;
- case MACH64_GT_ID:
- strcat(atyfb_name, "GT");
- break;
- default:
- break;
- }
- strcpy(fb_info.modename, atyfb_name);
- fb_info.node = -1;
- fb_info.fbops = &atyfb_ops;
- fb_info.disp = &fb_disp;
- fb_info.fontname[0] = '\0';
- fb_info.changevar = NULL;
- fb_info.switch_con = &atyfbcon_switch;
- fb_info.updatevar = &atyfbcon_updatevar;
- fb_info.blank = &atyfbcon_blank;
-
- err = register_framebuffer(&fb_info);
- if (err < 0)
- return mem_start;
-
- for (i = 0; i < 16; i++) {
- int j = color_table[i];
- palette[i].red = default_red[j];
- palette[i].green = default_grn[j];
- palette[i].blue = default_blu[j];
- }
- atyfb_set_par(&default_par);
- encode_var(&var, &default_par);
- atyfb_set_var(&var, -1, &fb_info);
+ info = kmalloc(sizeof(struct fb_info_aty), GFP_ATOMIC);
+
+ info->ati_regbase = (unsigned long)ioremap(0x7ff000+addr,
+ 0x1000)+0xc00;
+ info->ati_regbase_phys = 0x7ff000+addr;
+ info->ati_regbase = (unsigned long)ioremap(info->ati_regbase_phys,
+ 0x1000);
+ info->ati_regbase_phys += 0xc00;
+ info->ati_regbase += 0xc00;
+
+ /* enable memory-space accesses using config-space command register */
+ if (pci_device_loc(dp, &bus, &devfn) == 0) {
+ pcibios_read_config_word(bus, devfn, PCI_COMMAND, &cmd);
+ if (cmd != 0xffff) {
+ cmd |= PCI_COMMAND_MEMORY;
+ pcibios_write_config_word(bus, devfn, PCI_COMMAND, cmd);
+ }
+ }
+
+#ifdef __BIG_ENDIAN
+ /* Use the big-endian aperture */
+ addr += 0x800000;
+#endif
+
+ /* Map in frame buffer */
+ info->frame_buffer_phys = addr;
+ info->frame_buffer = (unsigned long)ioremap(addr, 0x800000);
- printk("fb%d: %s frame buffer device on %s\n", GET_FB_IDX(fb_info.node),
- atyfb_name, dp->full_name);
+ if (!aty_init(info, dp->full_name)) {
+ kfree(info);
+ return;
+ }
#ifdef CONFIG_FB_COMPAT_XPMAC
- if (!console_fb_info) {
- console_fb_info = &fb_info;
- console_setmode_ptr = atyfb_console_setmode;
- console_set_cmap_ptr = atyfb_set_cmap;
+ if (!console_fb_info)
+ console_fb_info = &info->fb_info;
+#endif /* CONFIG_FB_COMPAT_XPMAC */
}
-#endif /* CONFIG_FB_COMPAT_XPMAC) */
-
- return mem_start;
}
+#endif /* CONFIG_FB_OF */
-/* XXX: doesn't work yet */
-void atyfb_setup(char *options, int *ints)
+__initfunc(void atyfb_setup(char *options, int *ints))
{
char *this_opt;
- int vmode;
- int depth;
if (!options || !*options)
return;
for (this_opt = strtok(options, ","); this_opt;
this_opt = strtok(NULL, ",")) {
+ if (!strncmp(this_opt, "font:", 5)) {
+ char *p;
+ int i;
+
+ p = this_opt + 5;
+ for (i = 0; i < sizeof(fontname) - 1; i++)
+ if (!*p || *p == ' ' || *p == ',')
+ break;
+ memcpy(fontname, this_opt + 5, i);
+ fontname[i] = 0;
+ }
+#if defined(CONFIG_PMAC) || defined(CONFIG_CHRP)
if (!strncmp(this_opt, "vmode:", 6)) {
- vmode = simple_strtoul(this_opt+6, NULL, 0);
+ int vmode = simple_strtoul(this_opt+6, NULL, 0);
if (vmode > 0 && vmode <= VMODE_MAX)
- default_video_mode = vmode;
+ default_vmode = vmode;
} else if (!strncmp(this_opt, "cmode:", 6)) {
- depth = simple_strtoul(this_opt+6, NULL, 0);
+ int depth = simple_strtoul(this_opt+6, NULL, 0);
switch (depth) {
case 8:
- default_color_mode = CMODE_8;
+ default_cmode = 0;
break;
case 15:
case 16:
- default_color_mode = CMODE_16;
+ default_cmode = 1;
break;
case 24:
case 32:
- default_color_mode = CMODE_32;
+ default_cmode = 2;
break;
- };
+ }
+ }
+#endif
+#ifdef CONFIG_ATARI
+ /*
+ * Why do we need this silly Mach64 argument?
+ * We are already here because of mach64= so its redundant.
+ */
+ if (MACH_IS_ATARI && (!strncmp(this_opt, "Mach64:", 7))) {
+ static unsigned char m64_num;
+ static char mach64_str[80];
+ strncpy(mach64_str, this_opt+7, 80);
+ if (!store_video_par(mach64_str, m64_num)) {
+ m64_num++;
+ mach64_count = m64_num;
+ }
}
+#endif
}
}
+#ifdef CONFIG_ATARI
+__initfunc(static int store_video_par(char *video_str, unsigned char m64_num))
+{
+ char *p;
+ unsigned long vmembase, size, guiregbase;
+
+ printk("store_video_par() '%s' \n", video_str);
+
+ if (!(p = strtoke(video_str, ";")) || !*p)
+ goto mach64_invalid;
+ vmembase = simple_strtoul(p, NULL, 0);
+ if (!(p = strtoke(NULL, ";")) || !*p)
+ goto mach64_invalid;
+ size = simple_strtoul(p, NULL, 0);
+ if (!(p = strtoke(NULL, ";")) || !*p)
+ goto mach64_invalid;
+ guiregbase = simple_strtoul(p, NULL, 0);
+
+ phys_vmembase[m64_num] = vmembase;
+ phys_size[m64_num] = size;
+ phys_guiregbase[m64_num] = guiregbase;
+ printk(" stored them all: $%08lX $%08lX $%08lX \n", vmembase, size,
+ guiregbase);
+ return 0;
+
+mach64_invalid:
+ phys_vmembase[m64_num] = 0;
+ return -1;
+}
+
+__initfunc(static char *strtoke(char *s, const char *ct))
+{
+ static char *ssave = NULL;
+ char *sbegin, *send;
+
+ 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;
+}
+#endif /* CONFIG_ATARI */
-static int atyfbcon_switch(int con, struct fb_info *info)
+static int atyfbcon_switch(int con, struct fb_info *fb)
{
+ struct fb_info_aty *info = (struct fb_info_aty *)fb;
struct atyfb_par par;
/* Do we have to save the colormap? */
if (fb_display[currcon].cmap.len)
fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1,
- atyfb_getcolreg, info);
+ atyfb_getcolreg, fb);
+
+ /* Erase HW Cursor */
+ if (info->cursor)
+ atyfb_cursor(&fb_display[currcon], CM_ERASE,
+ info->cursor->pos.x, info->cursor->pos.y);
+
currcon = con;
- decode_var(&fb_display[con].var, &par);
- atyfb_set_par(&par);
+
+ atyfb_decode_var(&fb_display[con].var, &par, info);
+ atyfb_set_par(&par, info);
+
/* Install new colormap */
- do_install_cmap(con, info);
- return 0;
+ do_install_cmap(con, fb);
+
+ /* Install hw cursor */
+ if (info->cursor) {
+ aty_set_cursor_color(info, cursor_pixel_map, cursor_color_map,
+ cursor_color_map, cursor_color_map);
+ aty_set_cursor_shape(info);
+ }
+ return 1;
}
/*
* Update the `var' structure (called by fbcon.c)
*/
-static int atyfbcon_updatevar(int con, struct fb_info *info)
+static int atyfbcon_updatevar(int con, struct fb_info *fb)
{
- current_par.yoffset = fb_display[con].var.yoffset;
- set_off_pitch(&current_par);
+ struct fb_info_aty *info = (struct fb_info_aty *)fb;
+
+ info->current_par.crtc.yoffset = fb_display[con].var.yoffset;
+ set_off_pitch(&info->current_par, info);
return 0;
}
@@ -1425,20 +2956,30 @@ static int atyfbcon_updatevar(int con, struct fb_info *info)
* Blank the display.
*/
-static void atyfbcon_blank(int blank, struct fb_info *info)
+static void atyfbcon_blank(int blank, struct fb_info *fb)
{
- char gen_cntl;
-
- gen_cntl = aty_ld_8(CRTC_GEN_CNTL);
- if (blank & VESA_VSYNC_SUSPEND)
- gen_cntl |= 0x8;
- if (blank & VESA_HSYNC_SUSPEND)
- gen_cntl |= 0x4;
- if ((blank & VESA_POWERDOWN) == VESA_POWERDOWN)
- gen_cntl |= 0x40;
- if (blank == VESA_NO_BLANKING)
- gen_cntl &= ~(0x4c);
- aty_st_8(CRTC_GEN_CNTL, gen_cntl);
+ struct fb_info_aty *info = (struct fb_info_aty *)fb;
+ u8 gen_cntl;
+
+ gen_cntl = aty_ld_8(CRTC_GEN_CNTL, info);
+ if (blank > 0)
+ switch (blank-1) {
+ case VESA_NO_BLANKING:
+ gen_cntl |= 0x40;
+ break;
+ case VESA_VSYNC_SUSPEND:
+ gen_cntl |= 0x8;
+ break;
+ case VESA_HSYNC_SUSPEND:
+ gen_cntl |= 0x4;
+ break;
+ case VESA_POWERDOWN:
+ gen_cntl |= 0x4c;
+ break;
+ }
+ else
+ gen_cntl &= ~(0x4c);
+ aty_st_8(CRTC_GEN_CNTL, gen_cntl, info);
}
@@ -1448,13 +2989,15 @@ static void atyfbcon_blank(int blank, struct fb_info *info)
*/
static int atyfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
- u_int *transp, struct fb_info *info)
+ u_int *transp, struct fb_info *fb)
{
+ struct fb_info_aty *info = (struct fb_info_aty *)fb;
+
if (regno > 255)
return 1;
- *red = palette[regno].red;
- *green = palette[regno].green;
- *blue = palette[regno].blue;
+ *red = info->palette[regno].red;
+ *green = info->palette[regno].green;
+ *blue = info->palette[regno].blue;
return 0;
}
@@ -1466,38 +3009,42 @@ static int atyfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
*/
static int atyfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
- u_int transp, struct fb_info *info)
+ u_int transp, struct fb_info *fb)
{
+ struct fb_info_aty *info = (struct fb_info_aty *)fb;
int i, scale;
if (regno > 255)
return 1;
- palette[regno].red = red;
- palette[regno].green = green;
- palette[regno].blue = blue;
- aty_WaitQueue(2);
- i = aty_ld_8(DAC_CNTL) & 0xfc;
- if (chip_type == MACH64_GT_ID)
- i |= 0x2; /*DAC_CNTL|0x2 turns off the extra brightness for gt*/
- aty_st_8(DAC_CNTL, i);
- aty_st_8(DAC_REGS + DAC_MASK, 0xff);
+ info->palette[regno].red = red;
+ info->palette[regno].green = green;
+ info->palette[regno].blue = blue;
+ i = aty_ld_8(DAC_CNTL, info) & 0xfc;
+ if ((Gx == GT_CHIP_ID) || (Gx == GU_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))
+ i |= 0x2; /*DAC_CNTL|0x2 turns off the extra brightness for gt*/
+ aty_st_8(DAC_CNTL, i, info);
+ aty_st_8(DAC_REGS + DAC_MASK, 0xff, info);
eieio();
- scale = ((chip_type != MACH64_GX_ID) &&
- (current_par.cmode == CMODE_16)) ? 3 : 0;
- aty_WaitQueue(4);
- aty_cmap_regs->windex = regno << scale;
+ scale = ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID) &&
+ (info->current_par.crtc.bpp == 16)) ? 3 : 0;
+ info->aty_cmap_regs->windex = regno << scale;
eieio();
- aty_cmap_regs->lut = red << scale;
+ info->aty_cmap_regs->lut = red << scale;
eieio();
- aty_cmap_regs->lut = green << scale;
+ info->aty_cmap_regs->lut = green << scale;
eieio();
- aty_cmap_regs->lut = blue << scale;
+ info->aty_cmap_regs->lut = blue << scale;
eieio();
if (regno < 16) {
-#ifdef CONFIG_FBCON_CFB16
+#ifdef FBCON_HAS_CFB16
fbcon_cfb16_cmap[regno] = (regno << 10) | (regno << 5) | regno;
#endif
-#ifdef CONFIG_FBCON_CFB32
+#ifdef FBCON_HAS_CFB24
+ fbcon_cfb24_cmap[regno] = (regno << 16) | (regno << 8) | regno;
+#endif
+#ifdef FBCON_HAS_CFB32
fbcon_cfb32_cmap[regno] = (regno << 24) | (regno << 16) |
(regno << 8) | regno;
#endif
@@ -1513,10 +3060,11 @@ static void do_install_cmap(int con, struct fb_info *info)
if (fb_display[con].cmap.len)
fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
atyfb_setcolreg, info);
- else
- fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
- &fb_display[con].var, 1, atyfb_setcolreg,
- info);
+ else {
+ int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
+ fb_set_cmap(fb_default_cmap(size), &fb_display[con].var, 1,
+ atyfb_setcolreg, info);
+ }
}
@@ -1524,15 +3072,34 @@ static void do_install_cmap(int con, struct fb_info *info)
* Accelerated functions
*/
-void aty_waitblit(void)
+static inline void draw_rect(s16 x, s16 y, u16 width, u16 height,
+ struct fb_info_aty *info)
{
- aty_WaitIdleEmpty(); /* Make sure that all commands have finished */
+ /* perform rectangle fill */
+ wait_for_fifo(2, info);
+ aty_st_le32(DST_Y_X, (x << 16) | y, info);
+ aty_st_le32(DST_HEIGHT_WIDTH, (width << 16) | height, info);
}
-void aty_rectcopy(int srcx, int srcy, int dstx, int dsty, u_int width,
- u_int height)
+static inline void aty_rectcopy(int srcx, int srcy, int dstx, int dsty,
+ u_int width, u_int height,
+ struct fb_info_aty *info)
{
- u_int direction = 0;
+ u32 direction = DST_LAST_PEL;
+ u32 pitch_value;
+
+ if (!width || !height)
+ return;
+
+ pitch_value = info->current_par.crtc.vxres;
+ if (info->current_par.crtc.bpp == 24) {
+ /* In 24 bpp, the engine is in 8 bpp - this requires that all */
+ /* horizontal coordinates and widths must be adjusted */
+ pitch_value *= 3;
+ srcx *= 3;
+ dstx *= 3;
+ width *= 3;
+ }
if (srcy < dsty) {
dsty += height - 1;
@@ -1546,46 +3113,40 @@ void aty_rectcopy(int srcx, int srcy, int dstx, int dsty, u_int width,
} else
direction |= DST_X_LEFT_TO_RIGHT;
- aty_WaitQueue(4);
- aty_st_le32(DP_WRITE_MSK, 0x000000FF /* pGC->planemask */ );
- aty_st_le32(DP_MIX, (MIX_SRC << 16) | MIX_DST);
- aty_st_le32(DP_SRC, FRGD_SRC_BLIT);
-
- aty_WaitQueue(5);
- aty_st_le32(SRC_Y_X, (srcx << 16) | (srcy & 0x0000ffff));
- aty_st_le32(SRC_WIDTH1, width);
- aty_st_le32(DST_CNTL, direction);
- aty_st_le32(DST_Y_X, (dstx << 16) | (dsty & 0x0000ffff));
- aty_st_le32(DST_HEIGHT_WIDTH, (width << 16) | (height & 0x0000ffff));
-
- aty_WaitIdleEmpty(); /* Make sure that all commands have finished */
-
+ wait_for_fifo(5, info);
+ aty_st_le32(DP_SRC, FRGD_SRC_BLIT, info);
/*
- * Make sure that the destination trajectory is correctly set
- * for subsequent calls. MACH64_BIT_BLT is the only function that
- * currently changes the destination trajectory from L->R and T->B.
+ * ++Geert:
+ * Warning: SRC_OFF_PITCH may be thrashed by writing to other registers
+ * (e.g. CRTC_H_TOTAL_DISP, DP_SRC, DP_FRGD_CLR)
*/
- aty_st_le32(DST_CNTL, (DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM));
+ aty_st_le32(SRC_OFF_PITCH, (pitch_value / 8) << 22, info);
+ aty_st_le32(SRC_Y_X, (srcx << 16) | srcy, info);
+ aty_st_le32(SRC_HEIGHT1_WIDTH1, (width << 16) | height, info);
+ aty_st_le32(DST_CNTL, direction, info);
+ draw_rect(dstx, dsty, width, height, info);
}
-void aty_rectfill(int dstx, int dsty, u_int width, u_int height, u_int color)
+static inline void aty_rectfill(int dstx, int dsty, u_int width, u_int height,
+ u_int color, struct fb_info_aty *info)
{
if (!width || !height)
return;
- aty_WaitQueue(5);
- aty_st_le32(DP_FRGD_CLR, color /* pGC->fgPixel */ );
- aty_st_le32(DP_WRITE_MSK, 0x000000FF /* pGC->planemask */ );
- aty_st_le32(DP_MIX, (MIX_SRC << 16) | MIX_DST);
- aty_st_le32(DP_SRC, FRGD_SRC_FRGD_CLR);
-
- aty_st_le32(DST_CNTL, DST_X_LEFT_TO_RIGHT | DST_Y_TOP_TO_BOTTOM);
-
- aty_WaitQueue(2);
- aty_st_le32(DST_Y_X, (((u_int)dstx << 16) | ((u_int)dsty & 0x0000ffff)));
- aty_st_le32(DST_HEIGHT_WIDTH, (((u_int)width << 16) | height));
+ if (info->current_par.crtc.bpp == 24) {
+ /* In 24 bpp, the engine is in 8 bpp - this requires that all */
+ /* horizontal coordinates and widths must be adjusted */
+ dstx *= 3;
+ width *= 3;
+ }
- aty_WaitIdleEmpty(); /* Make sure that all commands have finished */
+ wait_for_fifo(3, info);
+ aty_st_le32(DP_FRGD_CLR, color, info);
+ aty_st_le32(DP_SRC, BKGD_SRC_BKGD_CLR | FRGD_SRC_FRGD_CLR | MONO_SRC_ONE,
+ info);
+ aty_st_le32(DST_CNTL, DST_LAST_PEL | DST_Y_TOP_TO_BOTTOM |
+ DST_X_LEFT_TO_RIGHT, info);
+ draw_rect(dstx, dsty, width, height, info);
}
@@ -1593,9 +3154,16 @@ void aty_rectfill(int dstx, int dsty, u_int width, u_int height, u_int color)
* Text console acceleration
*/
-static void fbcon_aty8_bmove(struct display *p, int sy, int sx, int dy, int dx,
- int height, int width)
+static void fbcon_aty_bmove(struct display *p, int sy, int sx, int dy, int dx,
+ int height, int width)
{
+#ifdef __sparc__
+ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
+
+ if (fb->mmaped && currcon == fb->vtconsole)
+ return;
+#endif
+
sx *= p->fontwidth;
sy *= p->fontheight;
dx *= p->fontwidth;
@@ -1603,13 +3171,22 @@ static void fbcon_aty8_bmove(struct display *p, int sy, int sx, int dy, int dx,
width *= p->fontwidth;
height *= p->fontheight;
- aty_rectcopy(sx, sy, dx, dy, width, height);
+ aty_rectcopy(sx, sy, dx, dy, width, height,
+ (struct fb_info_aty *)p->fb_info);
}
-static void fbcon_aty8_clear(struct vc_data *conp, struct display *p, int sy,
- int sx, int height, int width)
+static void fbcon_aty_clear(struct vc_data *conp, struct display *p, int sy,
+ int sx, int height, int width)
{
- u32 bgx = attr_bgcol_ec(p, conp);
+ u32 bgx;
+#ifdef __sparc__
+ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
+
+ if (fb->mmaped && currcon == fb->vtconsole)
+ return;
+#endif
+
+ bgx = attr_bgcol_ec(p, conp);
bgx |= (bgx << 8);
bgx |= (bgx << 16);
@@ -1618,68 +3195,154 @@ static void fbcon_aty8_clear(struct vc_data *conp, struct display *p, int sy,
width *= p->fontwidth;
height *= p->fontheight;
- aty_rectfill(sx, sy, width, height, bgx);
+ aty_rectfill(sx, sy, width, height, bgx,
+ (struct fb_info_aty *)p->fb_info);
}
+#ifdef FBCON_HAS_CFB8
static void fbcon_aty8_putc(struct vc_data *conp, struct display *p, int c,
int yy, int xx)
{
- aty_waitblit();
+#ifdef __sparc__
+ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
+
+ if (fb->mmaped && currcon == fb->vtconsole)
+ return;
+#endif
+
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
fbcon_cfb8_putc(conp, p, c, yy, xx);
}
static void fbcon_aty8_putcs(struct vc_data *conp, struct display *p,
- const char *s, int count, int yy, int xx)
+ const unsigned short *s, int count, int yy,
+ int xx)
{
- aty_waitblit();
+#ifdef __sparc__
+ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
+
+ if (fb->mmaped && currcon == fb->vtconsole)
+ return;
+#endif
+
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
}
static struct display_switch fbcon_aty8 = {
- fbcon_cfb8_setup, fbcon_aty8_bmove, fbcon_aty8_clear, fbcon_aty8_putc,
- fbcon_aty8_putcs, fbcon_cfb8_revc
+ fbcon_cfb8_setup, fbcon_aty_bmove, fbcon_aty_clear, fbcon_aty8_putc,
+ fbcon_aty8_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_aty16_putc(struct vc_data *conp, struct display *p, int c,
+ int yy, int xx)
+{
+#ifdef __sparc__
+ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
-#ifdef CONFIG_FB_COMPAT_XPMAC
+ if (fb->mmaped && currcon == fb->vtconsole)
+ return;
+#endif
- /*
- * Backward compatibility mode for Xpmac
- */
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
+ fbcon_cfb16_putc(conp, p, c, yy, xx);
+}
-static int atyfb_console_setmode(struct vc_mode *mode, int doit)
+static void fbcon_aty16_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int yy,
+ int xx)
{
- int err;
- struct fb_var_screeninfo var;
- struct atyfb_par par;
- int vmode, cmode;
+#ifdef __sparc__
+ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
- if (mode->mode <= 0 || mode->mode > VMODE_MAX )
- return -EINVAL;
- vmode = mode->mode;
+ if (fb->mmaped && currcon == fb->vtconsole)
+ return;
+#endif
- switch (mode->depth) {
- case 24:
- case 32:
- cmode = CMODE_32;
- break;
- case 16:
- cmode = CMODE_16;
- break;
- case 8:
- case 0: /* (default) */
- cmode = CMODE_8;
- break;
- default:
- return -EINVAL;
- }
- init_par(&par, vmode, cmode);
- encode_var(&var, &par);
- if ((err = decode_var(&var, &par)))
- return err;
- if (doit)
- atyfb_set_var(&var, currcon, 0);
- return 0;
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
+ fbcon_cfb16_putcs(conp, p, s, count, yy, xx);
}
-#endif /* CONFIG_FB_COMPAT_XPMAC */
+static struct display_switch fbcon_aty16 = {
+ fbcon_cfb16_setup, fbcon_aty_bmove, fbcon_aty_clear, fbcon_aty16_putc,
+ fbcon_aty16_putcs, fbcon_cfb16_revc, NULL, NULL, fbcon_cfb16_clear_margins,
+ FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+
+#ifdef FBCON_HAS_CFB24
+static void fbcon_aty24_putc(struct vc_data *conp, struct display *p, int c,
+ int yy, int xx)
+{
+#ifdef __sparc__
+ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
+
+ if (fb->mmaped && currcon == fb->vtconsole)
+ return;
+#endif
+
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
+ fbcon_cfb24_putc(conp, p, c, yy, xx);
+}
+
+static void fbcon_aty24_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int yy,
+ int xx)
+{
+#ifdef __sparc__
+ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
+
+ if (fb->mmaped && currcon == fb->vtconsole)
+ return;
+#endif
+
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
+ fbcon_cfb24_putcs(conp, p, s, count, yy, xx);
+}
+
+static struct display_switch fbcon_aty24 = {
+ fbcon_cfb24_setup, fbcon_cfb24_bmove, fbcon_cfb24_clear, fbcon_aty24_putc,
+ fbcon_aty24_putcs, fbcon_cfb24_revc, NULL, NULL, fbcon_cfb24_clear_margins,
+ FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+
+#ifdef FBCON_HAS_CFB32
+static void fbcon_aty32_putc(struct vc_data *conp, struct display *p, int c,
+ int yy, int xx)
+{
+#ifdef __sparc__
+ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
+
+ if (fb->mmaped && currcon == fb->vtconsole)
+ return;
+#endif
+
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
+ fbcon_cfb32_putc(conp, p, c, yy, xx);
+}
+
+static void fbcon_aty32_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int yy,
+ int xx)
+{
+#ifdef __sparc__
+ struct fb_info_aty *fb = (struct fb_info_aty *)(p->fb_info);
+
+ if (fb->mmaped && currcon == fb->vtconsole)
+ return;
+#endif
+
+ wait_for_idle((struct fb_info_aty *)p->fb_info);
+ fbcon_cfb32_putcs(conp, p, s, count, yy, xx);
+}
+
+static struct display_switch fbcon_aty32 = {
+ fbcon_cfb32_setup, fbcon_aty_bmove, fbcon_aty_clear, fbcon_aty32_putc,
+ fbcon_aty32_putcs, fbcon_cfb32_revc, NULL, NULL, fbcon_cfb32_clear_margins,
+ FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
diff --git a/drivers/video/bwtwofb.c b/drivers/video/bwtwofb.c
new file mode 100644
index 000000000..a907fc2d1
--- /dev/null
+++ b/drivers/video/bwtwofb.c
@@ -0,0 +1,222 @@
+/* $Id: bwtwofb.c,v 1.1 1998/07/21 14:50:48 jj Exp $
+ * bwtwofb.c: BWtwo frame buffer driver
+ *
+ * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
+ * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
+ * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
+ * Copyright (C) 1998 Pavel Machek (pavel@ucw.cz)
+ */
+
+#include <linux/config.h>
+#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 "sbusfb.h"
+#include <asm/io.h>
+#ifndef __sparc_v9__
+#include <asm/sun4paddr.h>
+#endif
+
+#include "fbcon-mfb.h"
+
+/* OBio addresses for the bwtwo registers */
+#define BWTWO_REGISTER_OFFSET 0x400000
+
+struct bw2_regs {
+ struct bt_regs bt;
+ volatile u8 control;
+ volatile u8 status;
+ volatile u8 cursor_start;
+ volatile u8 cursor_end;
+ volatile u8 h_blank_start;
+ volatile u8 h_blank_end;
+ volatile u8 h_sync_start;
+ volatile u8 h_sync_end;
+ volatile u8 comp_sync_end;
+ volatile u8 v_blank_start_high;
+ volatile u8 v_blank_start_low;
+ volatile u8 v_blank_end;
+ volatile u8 v_sync_start;
+ volatile u8 v_sync_end;
+ volatile u8 xfer_holdoff_start;
+ volatile u8 xfer_holdoff_end;
+};
+
+/* Status Register Constants */
+#define BWTWO_SR_RES_MASK 0x70
+#define BWTWO_SR_1600_1280 0x50
+#define BWTWO_SR_1152_900_76_A 0x40
+#define BWTWO_SR_1152_900_76_B 0x60
+#define BWTWO_SR_ID_MASK 0x0f
+#define BWTWO_SR_ID_MONO 0x02
+#define BWTWO_SR_ID_MONO_ECL 0x03
+#define BWTWO_SR_ID_MSYNC 0x04
+
+/* Control Register Constants */
+#define BWTWO_CTL_ENABLE_INTS 0x80
+#define BWTWO_CTL_ENABLE_VIDEO 0x40
+#define BWTWO_CTL_ENABLE_TIMING 0x20
+#define BWTWO_CTL_ENABLE_CURCMP 0x10
+#define BWTWO_CTL_XTAL_MASK 0x0C
+#define BWTWO_CTL_DIVISOR_MASK 0x03
+
+/* Status Register Constants */
+#define BWTWO_STAT_PENDING_INT 0x80
+#define BWTWO_STAT_MSENSE_MASK 0x70
+#define BWTWO_STAT_ID_MASK 0x0f
+
+static struct sbus_mmap_map bw2_mmap_map[] = {
+ { 0, 0, SBUS_MMAP_FBSIZE(1) },
+ { 0, 0, 0 }
+};
+
+static void bw2_blank (struct fb_info_sbusfb *fb)
+{
+ fb->s.bw2.regs->control &= ~BWTWO_CTL_ENABLE_VIDEO;
+}
+
+static void bw2_unblank (struct fb_info_sbusfb *fb)
+{
+ fb->s.bw2.regs->control |= BWTWO_CTL_ENABLE_VIDEO;
+}
+
+static void bw2_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)) >> 3;
+}
+
+static u8 bw2regs_1600[] __initdata = {
+ 0x14, 0x8b, 0x15, 0x28, 0x16, 0x03, 0x17, 0x13,
+ 0x18, 0x7b, 0x19, 0x05, 0x1a, 0x34, 0x1b, 0x2e,
+ 0x1c, 0x00, 0x1d, 0x0a, 0x1e, 0xff, 0x1f, 0x01,
+ 0x10, 0x21, 0
+};
+
+static u8 bw2regs_ecl[] __initdata = {
+ 0x14, 0x65, 0x15, 0x1e, 0x16, 0x04, 0x17, 0x0c,
+ 0x18, 0x5e, 0x19, 0x03, 0x1a, 0xa7, 0x1b, 0x23,
+ 0x1c, 0x00, 0x1d, 0x08, 0x1e, 0xff, 0x1f, 0x01,
+ 0x10, 0x20, 0
+};
+
+static u8 bw2regs_analog[] __initdata = {
+ 0x14, 0xbb, 0x15, 0x2b, 0x16, 0x03, 0x17, 0x13,
+ 0x18, 0xb0, 0x19, 0x03, 0x1a, 0xa6, 0x1b, 0x22,
+ 0x1c, 0x01, 0x1d, 0x05, 0x1e, 0xff, 0x1f, 0x01,
+ 0x10, 0x20, 0
+};
+
+static u8 bw2regs_76hz[] __initdata = {
+ 0x14, 0xb7, 0x15, 0x27, 0x16, 0x03, 0x17, 0x0f,
+ 0x18, 0xae, 0x19, 0x03, 0x1a, 0xae, 0x1b, 0x2a,
+ 0x1c, 0x01, 0x1d, 0x09, 0x1e, 0xff, 0x1f, 0x01,
+ 0x10, 0x24, 0
+};
+
+static u8 bw2regs_66hz[] __initdata = {
+ 0x14, 0xbb, 0x15, 0x2b, 0x16, 0x04, 0x17, 0x14,
+ 0x18, 0xae, 0x19, 0x03, 0x1a, 0xa8, 0x1b, 0x24,
+ 0x1c, 0x01, 0x1d, 0x05, 0x1e, 0xff, 0x1f, 0x01,
+ 0x10, 0x20, 0
+};
+
+static char idstring[60] __initdata = { 0 };
+
+__initfunc(char *bwtwofb_init(struct fb_info_sbusfb *fb))
+{
+ struct fb_fix_screeninfo *fix = &fb->fix;
+ struct display *disp = &fb->disp;
+ struct fbtype *type = &fb->type;
+#ifdef CONFIG_SUN4
+ unsigned long phys = SUN4_300_BWTWO_PHYSADDR;
+#else
+ unsigned long phys = fb->sbdp->reg_addrs[0].phys_addr;
+#endif
+
+#ifndef FBCON_HAS_MFB
+ return NULL;
+#endif
+
+ if (!fb->s.bw2.regs) {
+ fb->s.bw2.regs = (struct bw2_regs *)sparc_alloc_io(phys+BWTWO_REGISTER_OFFSET, 0,
+ sizeof(struct bw2_regs), "bw2_regs", fb->iospace, 0);
+ if (!prom_getbool(fb->prom_node, "width")) {
+ /* Ugh, broken PROM didn't initialize us.
+ * Let's deal with this ourselves.
+ */
+ u8 status, mon;
+ u8 *p;
+ int sizechange = 0;
+
+ status = fb->s.bw2.regs->status;
+ mon = status & BWTWO_SR_RES_MASK;
+ switch (status & BWTWO_SR_ID_MASK) {
+ case BWTWO_SR_ID_MONO_ECL:
+ if (mon == BWTWO_SR_1600_1280) {
+ p = bw2regs_1600;
+ fb->type.fb_width = 1600;
+ fb->type.fb_height = 1280;
+ sizechange = 1;
+ } else
+ p = bw2regs_ecl;
+ break;
+ case BWTWO_SR_ID_MONO:
+ p = bw2regs_analog;
+ break;
+ case BWTWO_SR_ID_MSYNC:
+ if (mon == BWTWO_SR_1152_900_76_A ||
+ mon == BWTWO_SR_1152_900_76_B)
+ p = bw2regs_76hz;
+ else
+ p = bw2regs_66hz;
+ break;
+ default:
+ prom_printf("bw2: can't handle SR %02x\n",
+ status);
+ prom_halt();
+ return NULL; /* fool gcc. */
+ }
+ for ( ; *p; p += 2)
+ ((u8 *)fb->s.bw2.regs)[p[0]] = p[1];
+ }
+ }
+
+ strcpy(fb->info.modename, "BWtwo");
+ strcpy(fix->id, "BWtwo");
+ fix->line_length = fb->var.xres_virtual>>3;
+
+ disp->scrollmode = SCROLL_YREDRAW;
+ if (!disp->screen_base)
+ disp->screen_base = (char *)sparc_alloc_io(phys, 0,
+ type->fb_size, "bw2_ram", fb->iospace, 0);
+ disp->screen_base += (fix->line_length * fb->y_margin + fb->x_margin) >> 3;
+ fb->dispsw = fbcon_mfb;
+ fix->visual = FB_VISUAL_MONO01;
+
+ fb->blank = bw2_blank;
+ fb->unblank = bw2_unblank;
+ fb->margins = bw2_margins;
+
+ fb->physbase = phys;
+ fb->mmap_map = bw2_mmap_map;
+
+#ifdef __sparc_v9__
+ sprintf(idstring, "bwtwo at %016lx", phys);
+#else
+ sprintf(idstring, "bwtwo at %x.%08lx", fb->iospace, phys);
+#endif
+
+ return idstring;
+}
diff --git a/drivers/video/cgsixfb.c b/drivers/video/cgsixfb.c
new file mode 100644
index 000000000..d5fc9f495
--- /dev/null
+++ b/drivers/video/cgsixfb.c
@@ -0,0 +1,683 @@
+/* $Id: cgsixfb.c,v 1.7 1998/07/22 12:44:59 jj Exp $
+ * cgsixfb.c: CGsix (GX,GXplus) frame buffer driver
+ *
+ * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
+ * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
+ * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
+ */
+
+#include <linux/config.h>
+#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 "sbusfb.h"
+#include <asm/io.h>
+
+/* Offset of interesting structures in the OBIO space */
+/*
+ * Brooktree is the video dac and is funny to program on the cg6.
+ * (it's even funnier on the cg3)
+ * The FBC could be the frame buffer control
+ * The FHC could is the frame buffer hardware control.
+ */
+#define CG6_ROM_OFFSET 0x0
+#define CG6_BROOKTREE_OFFSET 0x200000
+#define CG6_DHC_OFFSET 0x240000
+#define CG6_ALT_OFFSET 0x280000
+#define CG6_FHC_OFFSET 0x300000
+#define CG6_THC_OFFSET 0x301000
+#define CG6_FBC_OFFSET 0x700000
+#define CG6_TEC_OFFSET 0x701000
+#define CG6_RAM_OFFSET 0x800000
+
+/* FHC definitions */
+#define CG6_FHC_FBID_SHIFT 24
+#define CG6_FHC_FBID_MASK 255
+#define CG6_FHC_REV_SHIFT 20
+#define CG6_FHC_REV_MASK 15
+#define CG6_FHC_FROP_DISABLE (1 << 19)
+#define CG6_FHC_ROW_DISABLE (1 << 18)
+#define CG6_FHC_SRC_DISABLE (1 << 17)
+#define CG6_FHC_DST_DISABLE (1 << 16)
+#define CG6_FHC_RESET (1 << 15)
+#define CG6_FHC_LITTLE_ENDIAN (1 << 13)
+#define CG6_FHC_RES_MASK (3 << 11)
+#define CG6_FHC_1024 (0 << 11)
+#define CG6_FHC_1152 (1 << 11)
+#define CG6_FHC_1280 (2 << 11)
+#define CG6_FHC_1600 (3 << 11)
+#define CG6_FHC_CPU_MASK (3 << 9)
+#define CG6_FHC_CPU_SPARC (0 << 9)
+#define CG6_FHC_CPU_68020 (1 << 9)
+#define CG6_FHC_CPU_386 (2 << 9)
+#define CG6_FHC_TEST (1 << 8)
+#define CG6_FHC_TEST_X_SHIFT 4
+#define CG6_FHC_TEST_X_MASK 15
+#define CG6_FHC_TEST_Y_SHIFT 0
+#define CG6_FHC_TEST_Y_MASK 15
+
+/* FBC mode definitions */
+#define CG6_FBC_BLIT_IGNORE 0x00000000
+#define CG6_FBC_BLIT_NOSRC 0x00100000
+#define CG6_FBC_BLIT_SRC 0x00200000
+#define CG6_FBC_BLIT_ILLEGAL 0x00300000
+#define CG6_FBC_BLIT_MASK 0x00300000
+
+#define CG6_FBC_VBLANK 0x00080000
+
+#define CG6_FBC_MODE_IGNORE 0x00000000
+#define CG6_FBC_MODE_COLOR8 0x00020000
+#define CG6_FBC_MODE_COLOR1 0x00040000
+#define CG6_FBC_MODE_HRMONO 0x00060000
+#define CG6_FBC_MODE_MASK 0x00060000
+
+#define CG6_FBC_DRAW_IGNORE 0x00000000
+#define CG6_FBC_DRAW_RENDER 0x00008000
+#define CG6_FBC_DRAW_PICK 0x00010000
+#define CG6_FBC_DRAW_ILLEGAL 0x00018000
+#define CG6_FBC_DRAW_MASK 0x00018000
+
+#define CG6_FBC_BWRITE0_IGNORE 0x00000000
+#define CG6_FBC_BWRITE0_ENABLE 0x00002000
+#define CG6_FBC_BWRITE0_DISABLE 0x00004000
+#define CG6_FBC_BWRITE0_ILLEGAL 0x00006000
+#define CG6_FBC_BWRITE0_MASK 0x00006000
+
+#define CG6_FBC_BWRITE1_IGNORE 0x00000000
+#define CG6_FBC_BWRITE1_ENABLE 0x00000800
+#define CG6_FBC_BWRITE1_DISABLE 0x00001000
+#define CG6_FBC_BWRITE1_ILLEGAL 0x00001800
+#define CG6_FBC_BWRITE1_MASK 0x00001800
+
+#define CG6_FBC_BREAD_IGNORE 0x00000000
+#define CG6_FBC_BREAD_0 0x00000200
+#define CG6_FBC_BREAD_1 0x00000400
+#define CG6_FBC_BREAD_ILLEGAL 0x00000600
+#define CG6_FBC_BREAD_MASK 0x00000600
+
+#define CG6_FBC_BDISP_IGNORE 0x00000000
+#define CG6_FBC_BDISP_0 0x00000080
+#define CG6_FBC_BDISP_1 0x00000100
+#define CG6_FBC_BDISP_ILLEGAL 0x00000180
+#define CG6_FBC_BDISP_MASK 0x00000180
+
+#define CG6_FBC_INDEX_MOD 0x00000040
+#define CG6_FBC_INDEX_MASK 0x00000030
+
+/* THC definitions */
+#define CG6_THC_MISC_REV_SHIFT 16
+#define CG6_THC_MISC_REV_MASK 15
+#define CG6_THC_MISC_RESET (1 << 12)
+#define CG6_THC_MISC_VIDEO (1 << 10)
+#define CG6_THC_MISC_SYNC (1 << 9)
+#define CG6_THC_MISC_VSYNC (1 << 8)
+#define CG6_THC_MISC_SYNC_ENAB (1 << 7)
+#define CG6_THC_MISC_CURS_RES (1 << 6)
+#define CG6_THC_MISC_INT_ENAB (1 << 5)
+#define CG6_THC_MISC_INT (1 << 4)
+#define CG6_THC_MISC_INIT 0x9f
+
+/* The contents are unknown */
+struct cg6_tec {
+ volatile int tec_matrix;
+ volatile int tec_clip;
+ volatile int tec_vdc;
+};
+
+struct cg6_thc {
+ uint thc_pad0[512];
+ volatile uint thc_hs; /* hsync timing */
+ volatile uint thc_hsdvs;
+ volatile uint thc_hd;
+ volatile uint thc_vs; /* vsync timing */
+ volatile uint thc_vd;
+ volatile uint thc_refresh;
+ volatile uint thc_misc;
+ uint thc_pad1[56];
+ volatile uint thc_cursxy; /* cursor x,y position (16 bits each) */
+ volatile uint thc_cursmask[32]; /* cursor mask bits */
+ volatile uint thc_cursbits[32]; /* what to show where mask enabled */
+};
+
+struct cg6_fbc {
+ u32 xxx0[1];
+ volatile u32 mode;
+ volatile u32 clip;
+ u32 xxx1[1];
+ volatile u32 s;
+ volatile u32 draw;
+ volatile u32 blit;
+ volatile u32 font;
+ u32 xxx2[24];
+ volatile u32 x0, y0, z0, color0;
+ volatile u32 x1, y1, z1, color1;
+ volatile u32 x2, y2, z2, color2;
+ volatile u32 x3, y3, z3, color3;
+ volatile u32 offx, offy;
+ u32 xxx3[2];
+ volatile u32 incx, incy;
+ u32 xxx4[2];
+ volatile u32 clipminx, clipminy;
+ u32 xxx5[2];
+ volatile u32 clipmaxx, clipmaxy;
+ u32 xxx6[2];
+ volatile u32 fg;
+ volatile u32 bg;
+ volatile u32 alu;
+ volatile u32 pm;
+ volatile u32 pixelm;
+ u32 xxx7[2];
+ volatile u32 patalign;
+ volatile u32 pattern[8];
+ u32 xxx8[432];
+ volatile u32 apointx, apointy, apointz;
+ u32 xxx9[1];
+ volatile u32 rpointx, rpointy, rpointz;
+ u32 xxx10[5];
+ volatile u32 pointr, pointg, pointb, pointa;
+ volatile u32 alinex, aliney, alinez;
+ u32 xxx11[1];
+ volatile u32 rlinex, rliney, rlinez;
+ u32 xxx12[5];
+ volatile u32 liner, lineg, lineb, linea;
+ volatile u32 atrix, atriy, atriz;
+ u32 xxx13[1];
+ volatile u32 rtrix, rtriy, rtriz;
+ u32 xxx14[5];
+ volatile u32 trir, trig, trib, tria;
+ volatile u32 aquadx, aquady, aquadz;
+ u32 xxx15[1];
+ volatile u32 rquadx, rquady, rquadz;
+ u32 xxx16[5];
+ volatile u32 quadr, quadg, quadb, quada;
+ volatile u32 arectx, arecty, arectz;
+ u32 xxx17[1];
+ volatile u32 rrectx, rrecty, rrectz;
+ u32 xxx18[5];
+ volatile u32 rectr, rectg, rectb, recta;
+};
+
+static struct sbus_mmap_map cg6_mmap_map[] = {
+ { CG6_FBC, CG6_FBC_OFFSET, PAGE_SIZE },
+ { CG6_TEC, CG6_TEC_OFFSET, PAGE_SIZE },
+ { CG6_BTREGS, CG6_BROOKTREE_OFFSET, PAGE_SIZE },
+ { CG6_FHC, CG6_FHC_OFFSET, PAGE_SIZE },
+ { CG6_THC, CG6_THC_OFFSET, PAGE_SIZE },
+ { CG6_ROM, CG6_ROM_OFFSET, 0x10000 },
+ { CG6_RAM, CG6_RAM_OFFSET, SBUS_MMAP_FBSIZE(1) },
+ { CG6_DHC, CG6_DHC_OFFSET, 0x40000 },
+ { 0, 0, 0 }
+};
+
+static void cg6_setup(struct display *p)
+{
+ p->next_line = sbusfbinfo(p->fb_info)->var.xres_virtual;
+ p->next_plane = 0;
+}
+
+static void cg6_clear(struct vc_data *conp, struct display *p, int sy, int sx,
+ int height, int width)
+{
+ struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;
+ register struct cg6_fbc *fbc = fb->s.cg6.fbc;
+ int x, y, w, h;
+ int i;
+
+ do {
+ i = fbc->s;
+ } while (i & 0x10000000);
+ fbc->fg = attr_bgcol_ec(p,conp);
+ fbc->bg = attr_bgcol_ec(p,conp);
+ fbc->pixelm = ~(0);
+ fbc->alu = 0xea80ff00;
+ fbc->s = 0;
+ fbc->clip = 0;
+ fbc->pm = ~(0);
+
+ if (p->fontheightlog) {
+ y = sy << p->fontheightlog; h = height << p->fontheightlog;
+ } else {
+ y = sy * p->fontheight; h = height * p->fontheight;
+ }
+ if (p->fontwidthlog) {
+ x = sx << p->fontwidthlog; w = width << p->fontwidthlog;
+ } else {
+ x = sx * p->fontwidth; w = width * p->fontwidth;
+ }
+ fbc->arecty = y + fb->y_margin;
+ fbc->arectx = x + fb->x_margin;
+ fbc->arecty = y + fb->y_margin + h;
+ fbc->arectx = x + fb->x_margin + w;
+ do {
+ i = fbc->draw;
+ } while (i < 0 && (i & 0x20000000));
+}
+
+static void cg6_fill(struct fb_info_sbusfb *fb, struct display *p, int s,
+ int count, unsigned short *boxes)
+{
+ int i;
+ register struct cg6_fbc *fbc = fb->s.cg6.fbc;
+
+ do {
+ i = fbc->s;
+ } while (i & 0x10000000);
+ fbc->fg = attr_bgcol(p,s);
+ fbc->bg = attr_bgcol(p,s);
+ fbc->pixelm = ~(0);
+ fbc->alu = 0xea80ff00;
+ fbc->s = 0;
+ fbc->clip = 0;
+ fbc->pm = ~(0);
+ while (count-- > 0) {
+ fbc->arecty = boxes[1];
+ fbc->arectx = boxes[0];
+ fbc->arecty = boxes[3];
+ fbc->arectx = boxes[2];
+ boxes += 4;
+ do {
+ i = fbc->draw;
+ } while (i < 0 && (i & 0x20000000));
+ }
+}
+
+static void cg6_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx)
+{
+ struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;
+ register struct cg6_fbc *fbc = fb->s.cg6.fbc;
+ int i, x, y;
+ u8 *fd;
+
+ if (p->fontheightlog) {
+ y = fb->y_margin + (yy << p->fontheightlog);
+ i = ((c & p->charmask) << p->fontheightlog);
+ } else {
+ y = fb->y_margin + (yy * p->fontheight);
+ i = (c & p->charmask) * p->fontheight;
+ }
+#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
+ fd = p->fontdata + i;
+ x = fb->x_margin + xx * 8;
+#else
+ if (p->fontwidth <= 8)
+ fd = p->fontdata + i;
+ else
+ fd = p->fontdata + (i << 1);
+ if (p->fontwidthlog)
+ x = fb->x_margin + (xx << p->fontwidthlog);
+ else
+ x = fb->x_margin + (xx * p->fontwidth);
+#endif
+ do {
+ i = fbc->s;
+ } while (i & 0x10000000);
+ fbc->fg = attr_fgcol(p,c);
+ fbc->bg = attr_bgcol(p,c);
+ fbc->mode = 0x140000;
+ fbc->alu = 0xe880fc30;
+ fbc->pixelm = ~(0);
+ fbc->s = 0;
+ fbc->clip = 0;
+ fbc->pm = 0xff;
+ fbc->incx = 0;
+ fbc->incy = 1;
+ fbc->x0 = x;
+ fbc->x1 = x + p->fontwidth - 1;
+ fbc->y0 = y;
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (p->fontwidth <= 8) {
+#endif
+ for (i = 0; i < p->fontheight; i++)
+ fbc->font = *fd++ << 24;
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ } else {
+ for (i = 0; i < p->fontheight; i++) {
+ fbc->font = *(u16 *)fd << 16;
+ fd += 2;
+ }
+ }
+#endif
+}
+
+static void cg6_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
+ int count, int yy, int xx)
+{
+ struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;
+ register struct cg6_fbc *fbc = fb->s.cg6.fbc;
+ int i, x, y;
+ u8 *fd1, *fd2, *fd3, *fd4;
+
+ do {
+ i = fbc->s;
+ } while (i & 0x10000000);
+ fbc->fg = attr_fgcol(p,*s);
+ fbc->bg = attr_bgcol(p,*s);
+ fbc->mode = 0x140000;
+ fbc->alu = 0xe880fc30;
+ fbc->pixelm = ~(0);
+ fbc->s = 0;
+ fbc->clip = 0;
+ fbc->pm = 0xff;
+ x = fb->x_margin;
+ y = fb->y_margin;
+#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
+ x += xx * 8;
+#else
+ if (p->fontwidthlog)
+ x += (xx << p->fontwidthlog);
+ else
+ x += xx * p->fontwidth;
+#endif
+ if (p->fontheightlog)
+ y += (yy << p->fontheightlog);
+ else
+ y += (yy * p->fontheight);
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (p->fontwidth <= 8) {
+#endif
+ while (count >= 4) {
+ count -= 4;
+ fbc->incx = 0;
+ fbc->incy = 1;
+ fbc->x0 = x;
+ fbc->x1 = (x += 4 * p->fontwidth) - 1;
+ fbc->y0 = y;
+ if (p->fontheightlog) {
+ fd1 = p->fontdata + ((*s++ & p->charmask) << p->fontheightlog);
+ fd2 = p->fontdata + ((*s++ & p->charmask) << p->fontheightlog);
+ fd3 = p->fontdata + ((*s++ & p->charmask) << p->fontheightlog);
+ fd4 = p->fontdata + ((*s++ & p->charmask) << p->fontheightlog);
+ } else {
+ fd1 = p->fontdata + ((*s++ & p->charmask) * p->fontheight);
+ fd2 = p->fontdata + ((*s++ & p->charmask) * p->fontheight);
+ fd3 = p->fontdata + ((*s++ & p->charmask) * p->fontheight);
+ fd4 = p->fontdata + ((*s++ & p->charmask) * p->fontheight);
+ }
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (p->fontwidth == 8) {
+#endif
+ for (i = 0; i < p->fontheight; i++)
+ fbc->font = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++)
+ << 8)) << 8)) << 8);
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ } else {
+ for (i = 0; i < p->fontheight; i++)
+ fbc->font = (((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++)
+ << p->fontwidth)) << p->fontwidth)) << p->fontwidth)) << (24 - 3 * p->fontwidth);
+ }
+ }
+ } else {
+ while (count >= 2) {
+ count -= 2;
+ fbc->incx = 0;
+ fbc->incy = 1;
+ fbc->x0 = x;
+ fbc->x1 = (x += 2 * p->fontwidth) - 1;
+ fbc->y0 = y;
+ if (p->fontheightlog) {
+ fd1 = p->fontdata + ((*s++ & p->charmask) << (p->fontheightlog + 1));
+ fd2 = p->fontdata + ((*s++ & p->charmask) << (p->fontheightlog + 1));
+ } else {
+ fd1 = p->fontdata + (((*s++ & p->charmask) * p->fontheight) << 1);
+ fd2 = p->fontdata + (((*s++ & p->charmask) * p->fontheight) << 1);
+ }
+ for (i = 0; i < p->fontheight; i++) {
+ fbc->font = ((((u32)*(u16 *)fd1) << p->fontwidth) | ((u32)*(u16 *)fd2)) << (16 - p->fontwidth);
+ fd1 += 2; fd2 += 2;
+ }
+ }
+#endif
+ }
+ while (count) {
+ count--;
+ fbc->incx = 0;
+ fbc->incy = 1;
+ fbc->x0 = x;
+ fbc->x1 = (x += p->fontwidth) - 1;
+ fbc->y0 = y;
+ if (p->fontheightlog)
+ i = ((*s++ & p->charmask) << p->fontheightlog);
+ else
+ i = ((*s++ & p->charmask) * p->fontheight);
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (p->fontwidth <= 8) {
+#endif
+ fd1 = p->fontdata + i;
+ for (i = 0; i < p->fontheight; i++)
+ fbc->font = *fd1++ << 24;
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ } else {
+ fd1 = p->fontdata + (i << 1);
+ for (i = 0; i < p->fontheight; i++) {
+ fbc->font = *(u16 *)fd1 << 16;
+ fd1 += 2;
+ }
+ }
+#endif
+ }
+}
+
+static void cg6_revc(struct display *p, int xx, int yy)
+{
+ /* Not used if hw cursor */
+}
+
+static void cg6_loadcmap (struct fb_info_sbusfb *fb, int index, int count)
+{
+ struct bt_regs *bt = fb->s.cg6.bt;
+ int i;
+
+ bt->addr = index << 24;
+ for (i = index; count--; i++){
+ bt->color_map = fb->color_map CM(i,0) << 24;
+ bt->color_map = fb->color_map CM(i,1) << 24;
+ bt->color_map = fb->color_map CM(i,2) << 24;
+ }
+}
+
+static void cg6_restore_palette (struct fb_info_sbusfb *fb)
+{
+ struct bt_regs *bt = fb->s.cg6.bt;
+
+ bt->addr = 0;
+ bt->color_map = 0xffffffff;
+ bt->color_map = 0xffffffff;
+ bt->color_map = 0xffffffff;
+}
+
+static struct display_switch cg6_dispsw __initdata = {
+ cg6_setup, fbcon_redraw_bmove, cg6_clear, cg6_putc, cg6_putcs, cg6_revc,
+ NULL, NULL, NULL, FONTWIDTHRANGE(1,16) /* Allow fontwidths up to 16 */
+};
+
+static void cg6_setcursormap (struct fb_info_sbusfb *fb, u8 *red, u8 *green, u8 *blue)
+{
+ struct bt_regs *bt = fb->s.cg6.bt;
+
+ bt->addr = 1 << 24;
+ bt->cursor = red[0] << 24;
+ bt->cursor = green[0] << 24;
+ bt->cursor = blue[0] << 24;
+ bt->addr = 3 << 24;
+ bt->cursor = red[1] << 24;
+ bt->cursor = green[1] << 24;
+ bt->cursor = blue[1] << 24;
+}
+
+/* Set cursor shape */
+static void cg6_setcurshape (struct fb_info_sbusfb *fb)
+{
+ struct cg6_thc *thc = fb->s.cg6.thc;
+ int i;
+
+ for (i = 0; i < 32; i++) {
+ thc->thc_cursmask [i] = fb->cursor.bits[0][i];
+ thc->thc_cursbits [i] = fb->cursor.bits[1][i];
+ }
+}
+
+/* Load cursor information */
+static void cg6_setcursor (struct fb_info_sbusfb *fb)
+{
+ unsigned int v;
+ struct cg_cursor *c = &fb->cursor;
+
+ if (c->enable)
+ v = ((c->cpos.fbx - c->chot.fbx) << 16)
+ |((c->cpos.fby - c->chot.fby) & 0xffff);
+ else
+ /* Magic constant to turn off the cursor */
+ v = ((65536-32) << 16) | (65536-32);
+ fb->s.cg6.thc->thc_cursxy = v;
+}
+
+static void cg6_blank (struct fb_info_sbusfb *fb)
+{
+ fb->s.cg6.thc->thc_misc &= ~CG6_THC_MISC_VIDEO;
+}
+
+static void cg6_unblank (struct fb_info_sbusfb *fb)
+{
+ fb->s.cg6.thc->thc_misc |= CG6_THC_MISC_VIDEO;
+}
+
+static void cg6_reset (struct fb_info_sbusfb *fb)
+{
+ unsigned int rev, conf;
+
+ /* Turn off stuff in the Transform Engine. */
+ fb->s.cg6.tec->tec_matrix = 0;
+ fb->s.cg6.tec->tec_clip = 0;
+ fb->s.cg6.tec->tec_vdc = 0;
+
+ /* Take care of bugs in old revisions. */
+ rev = (*(fb->s.cg6.fhc) >> CG6_FHC_REV_SHIFT) & CG6_FHC_REV_MASK;
+ if (rev < 5) {
+ conf = (*(fb->s.cg6.fhc) & CG6_FHC_RES_MASK) |
+ CG6_FHC_CPU_68020 | CG6_FHC_TEST |
+ (11 << CG6_FHC_TEST_X_SHIFT) |
+ (11 << CG6_FHC_TEST_Y_SHIFT);
+ if (rev < 2)
+ conf |= CG6_FHC_DST_DISABLE;
+ *(fb->s.cg6.fhc) = conf;
+ }
+
+ /* Set things in the FBC. */
+ fb->s.cg6.fbc->mode &= ~(CG6_FBC_BLIT_MASK | CG6_FBC_MODE_MASK |
+ CG6_FBC_DRAW_MASK | CG6_FBC_BWRITE0_MASK |
+ CG6_FBC_BWRITE1_MASK | CG6_FBC_BREAD_MASK |
+ CG6_FBC_BDISP_MASK);
+ fb->s.cg6.fbc->mode |= (CG6_FBC_BLIT_SRC | CG6_FBC_MODE_COLOR8 |
+ CG6_FBC_DRAW_RENDER | CG6_FBC_BWRITE0_ENABLE |
+ CG6_FBC_BWRITE1_DISABLE | CG6_FBC_BREAD_0 |
+ CG6_FBC_BDISP_0);
+ fb->s.cg6.fbc->clip = 0;
+ fb->s.cg6.fbc->offx = 0;
+ fb->s.cg6.fbc->offy = 0;
+ fb->s.cg6.fbc->clipminx = 0;
+ fb->s.cg6.fbc->clipminy = 0;
+ fb->s.cg6.fbc->clipmaxx = fb->type.fb_width - 1;
+ fb->s.cg6.fbc->clipmaxy = fb->type.fb_height - 1;
+ /* Enable cursor in Brooktree DAC. */
+ fb->s.cg6.bt->addr = 0x06 << 24;
+ fb->s.cg6.bt->control |= 0x03 << 24;
+}
+
+static void cg6_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 };
+
+__initfunc(char *cgsixfb_init(struct fb_info_sbusfb *fb))
+{
+ struct fb_fix_screeninfo *fix = &fb->fix;
+ struct fb_var_screeninfo *var = &fb->var;
+ struct display *disp = &fb->disp;
+ struct fbtype *type = &fb->type;
+ unsigned long phys = fb->sbdp->reg_addrs[0].phys_addr;
+ u32 conf;
+ char *p;
+
+ strcpy(fb->info.modename, "CGsix");
+
+ strcpy(fix->id, "CGsix");
+ fix->line_length = fb->var.xres_virtual;
+ fix->accel = FB_ACCEL_SUN_CGSIX;
+
+ var->accel_flags = FB_ACCELF_TEXT;
+
+ disp->scrollmode = SCROLL_YREDRAW;
+ if (!disp->screen_base)
+ disp->screen_base = (char *)sparc_alloc_io(phys + CG6_RAM_OFFSET, 0,
+ type->fb_size, "cgsix_ram", fb->iospace, 0);
+ disp->screen_base += fix->line_length * fb->y_margin + fb->x_margin;
+ fb->s.cg6.fbc = (struct cg6_fbc *)sparc_alloc_io(phys + CG6_FBC_OFFSET, 0,
+ 4096, "cgsix_fbc", fb->iospace, 0);
+ fb->s.cg6.tec = (struct cg6_tec *)sparc_alloc_io(phys + CG6_TEC_OFFSET, 0,
+ sizeof(struct cg6_tec), "cgsix_tec", fb->iospace, 0);
+ fb->s.cg6.thc = (struct cg6_thc *)sparc_alloc_io(phys + CG6_THC_OFFSET, 0,
+ sizeof(struct cg6_thc), "cgsix_thc", fb->iospace, 0);
+ fb->s.cg6.bt = (struct bt_regs *)sparc_alloc_io(phys + CG6_BROOKTREE_OFFSET, 0,
+ sizeof(struct bt_regs), "cgsix_dac", fb->iospace, 0);
+ fb->s.cg6.fhc = (u32 *)sparc_alloc_io(phys + CG6_FHC_OFFSET, 0,
+ sizeof(u32), "cgsix_fhc", fb->iospace, 0);
+ fb->dispsw = cg6_dispsw;
+
+ fb->margins = cg6_margins;
+ fb->loadcmap = cg6_loadcmap;
+ fb->setcursor = cg6_setcursor;
+ fb->setcursormap = cg6_setcursormap;
+ fb->setcurshape = cg6_setcurshape;
+ fb->restore_palette = cg6_restore_palette;
+ fb->fill = cg6_fill;
+ fb->blank = cg6_blank;
+ fb->unblank = cg6_unblank;
+ fb->reset = cg6_reset;
+
+ fb->physbase = phys;
+ fb->mmap_map = cg6_mmap_map;
+
+ /* Initialize Brooktree DAC */
+ fb->s.cg6.bt->addr = 0x04 << 24; /* color planes */
+ fb->s.cg6.bt->control = 0xff << 24;
+ fb->s.cg6.bt->addr = 0x05 << 24;
+ fb->s.cg6.bt->control = 0x00 << 24;
+ fb->s.cg6.bt->addr = 0x06 << 24; /* overlay plane */
+ fb->s.cg6.bt->control = 0x73 << 24;
+ fb->s.cg6.bt->addr = 0x07 << 24;
+ fb->s.cg6.bt->control = 0x00 << 24;
+
+ conf = *fb->s.cg6.fhc;
+ switch(conf & CG6_FHC_CPU_MASK) {
+ case CG6_FHC_CPU_SPARC: p = "sparc"; break;
+ case CG6_FHC_CPU_68020: p = "68020"; break;
+ default: p = "i386"; break;
+ }
+
+ sprintf(idstring,
+#ifdef __sparc_v9__
+ "cgsix at %016lx TEC Rev %x CPU %s Rev %x", phys,
+#else
+ "cgsix at %x.%08lx TEC Rev %x CPU %s Rev %x", fb->iospace, phys,
+#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);
+
+ cg6_reset(fb);
+
+ return idstring;
+}
diff --git a/drivers/video/cgthreefb.c b/drivers/video/cgthreefb.c
new file mode 100644
index 000000000..2cab0fc25
--- /dev/null
+++ b/drivers/video/cgthreefb.c
@@ -0,0 +1,247 @@
+/* $Id: cgthreefb.c,v 1.1 1998/07/21 14:50:47 jj Exp $
+ * cgthreefb.c: CGthree frame buffer driver
+ *
+ * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
+ * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
+ * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
+ */
+
+#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 "sbusfb.h"
+#include <asm/io.h>
+
+#include "fbcon-cfb8.h"
+
+/* Control Register Constants */
+#define CG3_CR_ENABLE_INTS 0x80
+#define CG3_CR_ENABLE_VIDEO 0x40
+#define CG3_CR_ENABLE_TIMING 0x20
+#define CG3_CR_ENABLE_CURCMP 0x10
+#define CG3_CR_XTAL_MASK 0x0c
+#define CG3_CR_DIVISOR_MASK 0x03
+
+/* Status Register Constants */
+#define CG3_SR_PENDING_INT 0x80
+#define CG3_SR_RES_MASK 0x70
+#define CG3_SR_1152_900_76_A 0x40
+#define CG3_SR_1152_900_76_B 0x60
+#define CG3_SR_ID_MASK 0x0f
+#define CG3_SR_ID_COLOR 0x01
+#define CG3_SR_ID_MONO 0x02
+#define CG3_SR_ID_MONO_ECL 0x03
+
+enum cg3_type {
+ CG3_AT_66HZ = 0,
+ CG3_AT_76HZ,
+ CG3_RDI
+};
+
+struct cg3_regs {
+ struct bt_regs cmap;
+ volatile u8 control;
+ volatile u8 status;
+ volatile u8 cursor_start;
+ volatile u8 cursor_end;
+ volatile u8 h_blank_start;
+ volatile u8 h_blank_end;
+ volatile u8 h_sync_start;
+ volatile u8 h_sync_end;
+ volatile u8 comp_sync_end;
+ volatile u8 v_blank_start_high;
+ volatile u8 v_blank_start_low;
+ volatile u8 v_blank_end;
+ volatile u8 v_sync_start;
+ volatile u8 v_sync_end;
+ volatile u8 xfer_holdoff_start;
+ volatile u8 xfer_holdoff_end;
+};
+
+/* Offset of interesting structures in the OBIO space */
+#define CG3_REGS_OFFSET 0x400000
+#define CG3_RAM_OFFSET 0x800000
+
+static struct sbus_mmap_map cg3_mmap_map[] = {
+ { CG3_MMAP_OFFSET, CG3_RAM_OFFSET, SBUS_MMAP_FBSIZE(1) },
+ { 0, 0, 0 }
+};
+
+/* The cg3 palette is loaded with 4 color values at each time */
+/* so you end up with: (rgb)(r), (gb)(rg), (b)(rgb), and so on */
+
+#define D4M3(x) ((((x)>>2)<<1) + ((x)>>2)) /* (x/4)*3 */
+#define D4M4(x) ((x)&~0x3) /* (x/4)*4 */
+
+static void cg3_loadcmap (struct fb_info_sbusfb *fb, int index, int count)
+{
+ struct bt_regs *bt = &fb->s.cg3.regs->cmap;
+ u32 *i;
+ int steps;
+
+ i = (((u32 *)fb->color_map) + D4M3(index));
+ steps = D4M3(index+count-1) - D4M3(index)+3;
+
+ *(volatile u8 *)&bt->addr = (u8)D4M4(index);
+ while (steps--)
+ bt->color_map = *i++;
+}
+
+static void cg3_blank (struct fb_info_sbusfb *fb)
+{
+ fb->s.cg3.regs->control &= ~CG3_CR_ENABLE_VIDEO;
+}
+
+static void cg3_unblank (struct fb_info_sbusfb *fb)
+{
+ fb->s.cg3.regs->control |= CG3_CR_ENABLE_VIDEO;
+}
+
+static void cg3_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 u8 cg3regvals_66hz[] __initdata = { /* 1152 x 900, 66 Hz */
+ 0x14, 0xbb, 0x15, 0x2b, 0x16, 0x04, 0x17, 0x14,
+ 0x18, 0xae, 0x19, 0x03, 0x1a, 0xa8, 0x1b, 0x24,
+ 0x1c, 0x01, 0x1d, 0x05, 0x1e, 0xff, 0x1f, 0x01,
+ 0x10, 0x20, 0
+};
+
+static u8 cg3regvals_76hz[] __initdata = { /* 1152 x 900, 76 Hz */
+ 0x14, 0xb7, 0x15, 0x27, 0x16, 0x03, 0x17, 0x0f,
+ 0x18, 0xae, 0x19, 0x03, 0x1a, 0xae, 0x1b, 0x2a,
+ 0x1c, 0x01, 0x1d, 0x09, 0x1e, 0xff, 0x1f, 0x01,
+ 0x10, 0x24, 0
+};
+
+static u8 cg3regvals_rdi[] __initdata = { /* 640 x 480, cgRDI */
+ 0x14, 0x70, 0x15, 0x20, 0x16, 0x08, 0x17, 0x10,
+ 0x18, 0x06, 0x19, 0x02, 0x1a, 0x31, 0x1b, 0x51,
+ 0x1c, 0x06, 0x1d, 0x0c, 0x1e, 0xff, 0x1f, 0x01,
+ 0x10, 0x22, 0
+};
+
+static u8 *cg3_regvals[] __initdata = {
+ cg3regvals_66hz, cg3regvals_76hz, cg3regvals_rdi
+};
+
+static u_char cg3_dacvals[] __initdata = {
+ 4, 0xff, 5, 0x00, 6, 0x70, 7, 0x00, 0
+};
+
+static char idstring[60] __initdata = { 0 };
+
+__initfunc(char *cgthreefb_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[0].phys_addr;
+ int cgRDI = strstr(fb->sbdp->prom_name, "cgRDI") != NULL;
+
+#ifndef FBCON_HAS_CFB8
+ return NULL;
+#endif
+
+ if (!fb->s.cg3.regs) {
+ fb->s.cg3.regs = (struct cg3_regs *)sparc_alloc_io(phys+CG3_REGS_OFFSET, 0,
+ sizeof(struct cg3_regs), "cg3_regs", fb->iospace, 0);
+ if (cgRDI) {
+ char buffer[40];
+ char *p;
+ int ww, hh;
+
+ *buffer = 0;
+ prom_getstring (fb->prom_node, "params", buffer, sizeof(buffer));
+ if (*buffer) {
+ ww = simple_strtoul (buffer, &p, 10);
+ if (ww && *p == 'x') {
+ hh = simple_strtoul (p + 1, &p, 10);
+ if (hh && *p == '-') {
+ if (type->fb_width != ww || type->fb_height != hh) {
+ type->fb_width = ww;
+ type->fb_height = hh;
+ return SBUSFBINIT_SIZECHANGE;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ strcpy(fb->info.modename, "CGthree");
+ strcpy(fix->id, "CGthree");
+ fix->line_length = fb->var.xres_virtual;
+
+ disp->scrollmode = SCROLL_YREDRAW;
+ if (!disp->screen_base)
+ disp->screen_base = (char *)sparc_alloc_io(phys+CG3_RAM_OFFSET, 0,
+ type->fb_size, "cg3_ram", fb->iospace, 0);
+ disp->screen_base += fix->line_length * fb->y_margin + fb->x_margin;
+ fb->dispsw = fbcon_cfb8;
+
+ fb->margins = cg3_margins;
+ fb->loadcmap = cg3_loadcmap;
+ fb->blank = cg3_blank;
+ fb->unblank = cg3_unblank;
+
+ fb->physbase = phys;
+ fb->mmap_map = cg3_mmap_map;
+
+#ifdef __sparc_v9__
+ sprintf(idstring, "%s at %016lx", cgRDI ? "cgRDI" : "cgthree", phys);
+#else
+ sprintf(idstring, "%s at %x.%08lx", cgRDI ? "cgRDI" : "cgthree", fb->iospace, phys);
+#endif
+
+ if (!prom_getbool(fb->prom_node, "width")) {
+ /* Ugh, broken PROM didn't initialize us.
+ * Let's deal with this ourselves.
+ */
+ enum cg3_type type;
+ u8 *p;
+
+ if (cgRDI)
+ type = CG3_RDI;
+ else {
+ u8 status = fb->s.cg3.regs->status, mon;
+ if ((status & CG3_SR_ID_MASK) == CG3_SR_ID_COLOR) {
+ mon = status & CG3_SR_RES_MASK;
+ if (mon == CG3_SR_1152_900_76_A ||
+ mon == CG3_SR_1152_900_76_B)
+ type = CG3_AT_76HZ;
+ else
+ type = CG3_AT_66HZ;
+ } else {
+ prom_printf("cgthree: can't handle SR %02x\n",
+ status);
+ prom_halt();
+ return NULL; /* fool gcc. */
+ }
+ }
+
+ for (p = cg3_regvals[type]; *p; p += 2)
+ ((u8 *)fb->s.cg3.regs)[p[0]] = p[1];
+
+ for (p = cg3_dacvals; *p; p += 2) {
+ *(volatile u8 *)&fb->s.cg3.regs->cmap.addr = p[0];
+ *(volatile u8 *)&fb->s.cg3.regs->cmap.control = p[1];
+ }
+ }
+
+ return idstring;
+}
diff --git a/drivers/video/chipsfb.c b/drivers/video/chipsfb.c
new file mode 100644
index 000000000..c13954030
--- /dev/null
+++ b/drivers/video/chipsfb.c
@@ -0,0 +1,565 @@
+/*
+ * drivers/video/chipsfb.c -- frame buffer device for
+ * Chips & Technologies 65550 chip.
+ *
+ * Copyright (C) 1998 Paul Mackerras
+ *
+ * This file is derived from the Powermac "chips" driver:
+ * Copyright (C) 1997 Fabio Riccardi.
+ * And from the frame buffer device for Open Firmware-initialized devices:
+ * Copyright (C) 1997 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/config.h>
+#include <linux/module.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/selection.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#ifdef CONFIG_FB_COMPAT_XPMAC
+#include <asm/vc_ioctl.h>
+#endif
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <asm/adb.h>
+#include <asm/pmu.h>
+
+#include "fbcon.h"
+#include "fbcon-cfb8.h"
+#include "fbcon-cfb16.h"
+#include "macmodes.h"
+
+static int currcon = 0;
+
+struct fb_info_chips {
+ struct fb_info info;
+ struct fb_fix_screeninfo fix;
+ struct fb_var_screeninfo var;
+ struct display disp;
+ struct {
+ __u8 red, green, blue;
+ } palette[256];
+ __u8 *frame_buffer;
+ __u8 *blitter_regs;
+ __u8 *io_base;
+ unsigned long chips_base_phys;
+ unsigned long chips_io_phys;
+ struct fb_info_chips *next;
+#ifdef CONFIG_PMAC_PBOOK
+ unsigned char *save_framebuffer;
+#endif
+};
+
+#define write_xr(num,val) { out_8(p->io_base + 0x3D6, num); out_8(p->io_base + 0x3D7, val); }
+#define read_xr(num,var) { out_8(p->io_base + 0x3D6, num); var = in_8(p->io_base + 0x3D7); }
+#define write_fr(num,val) { out_8(p->io_base + 0x3D0, num); out_8(p->io_base + 0x3D1, val); }
+#define read_fr(num,var) { out_8(p->io_base + 0x3D0, num); var = in_8(p->io_base + 0x3D1); }
+#define write_cr(num,val) { out_8(p->io_base + 0x3D4, num); out_8(p->io_base + 0x3D5, val); }
+#define read_cr(num,var) { out_8(p->io_base + 0x3D4, num); var = in_8(p->io_base + 0x3D5); }
+
+
+static struct fb_info_chips *all_chips;
+
+#ifdef CONFIG_PMAC_PBOOK
+int chips_sleep_notify(struct notifier_block *, unsigned long, void *);
+static struct notifier_block chips_sleep_notifier = {
+ chips_sleep_notify, NULL, 0
+};
+#endif
+
+/*
+ * Exported functions
+ */
+void chips_init(void);
+void chips_of_init(struct device_node *dp);
+
+static int chips_open(struct fb_info *info, int user);
+static int chips_release(struct fb_info *info, int user);
+static int chips_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info);
+static int chips_get_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int chips_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int chips_pan_display(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int chips_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+static int chips_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+static int chips_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg, int con, struct fb_info *info);
+
+static struct fb_ops chipsfb_ops = {
+ chips_open,
+ chips_release,
+ chips_get_fix,
+ chips_get_var,
+ chips_set_var,
+ chips_get_cmap,
+ chips_set_cmap,
+ chips_pan_display,
+ chips_ioctl
+};
+
+static int chipsfb_getcolreg(u_int regno, u_int *red, u_int *green,
+ u_int *blue, u_int *transp, struct fb_info *info);
+static int chipsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info);
+static void do_install_cmap(int con, struct fb_info *info);
+static void chips_set_bitdepth(struct fb_info_chips *p, struct display* disp, int con, int bpp);
+
+
+static int chips_open(struct fb_info *info, int user)
+{
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static int chips_release(struct fb_info *info, int user)
+{
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+static int chips_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info)
+{
+ struct fb_info_chips *cp = (struct fb_info_chips *) info;
+
+ *fix = cp->fix;
+ return 0;
+}
+
+static int chips_get_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ struct fb_info_chips *cp = (struct fb_info_chips *) info;
+
+ *var = cp->var;
+ return 0;
+}
+
+static int chips_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ struct fb_info_chips *cp = (struct fb_info_chips *) info;
+ struct display *disp = (con >= 0)? &fb_display[con]: &cp->disp;
+
+ if (var->xres > 800 || var->yres > 600
+ || var->xres_virtual > 800 || var->yres_virtual > 600
+ || (var->bits_per_pixel != 8 && var->bits_per_pixel != 16)
+ || var->nonstd
+ || (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+ return -EINVAL;
+
+ if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW &&
+ var->bits_per_pixel != disp->var.bits_per_pixel) {
+ chips_set_bitdepth(cp, disp, con, var->bits_per_pixel);
+ }
+
+ return 0;
+}
+
+static int chips_pan_display(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ if (var->xoffset != 0 || var->yoffset != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int chips_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ if (con == currcon) /* current console? */
+ return fb_get_cmap(cmap, &fb_display[con].var, kspc,
+ chipsfb_getcolreg, info);
+ if (fb_display[con].cmap.len) /* non default colormap? */
+ fb_copy_cmap(&fb_display[con].cmap, cmap, kspc? 0: 2);
+ else
+ fb_copy_cmap(fb_default_cmap(256), cmap, kspc? 0: 2);
+ return 0;
+}
+
+static int chips_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ struct display *disp = &fb_display[con];
+ int err;
+
+ if (disp->cmap.len == 0) {
+ err = fb_alloc_cmap(&disp->cmap, 256, 0);
+ if (err)
+ return err;
+ }
+
+ if (con == currcon)
+ return fb_set_cmap(cmap, &disp->var, kspc, chipsfb_setcolreg,
+ info);
+ fb_copy_cmap(cmap, &disp->cmap, kspc==0);
+ return 0;
+}
+
+static int chips_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg, int con, struct fb_info *info)
+{
+ return -EINVAL;
+}
+
+static int chipsfb_switch(int con, struct fb_info *info)
+{
+ struct fb_info_chips *p = (struct fb_info_chips *) info;
+ struct display* old_disp = &fb_display[currcon];
+ struct display* new_disp = &fb_display[con];
+ int bit_depth;
+
+ if (fb_display[currcon].cmap.len)
+ fb_get_cmap(&old_disp->cmap,
+ &old_disp->var, 1, chipsfb_getcolreg,
+ info);
+
+ bit_depth = new_disp->var.bits_per_pixel;
+ if (old_disp->var.bits_per_pixel != bit_depth)
+ {
+ currcon = con;
+ chips_set_bitdepth(p, new_disp, con, bit_depth);
+ }
+ else
+ currcon = con;
+
+ do_install_cmap(con, info);
+ return 0;
+}
+
+static int chipsfb_updatevar(int con, struct fb_info *info)
+{
+ return 0;
+}
+
+static void chipsfb_blank(int blank, struct fb_info *info)
+{
+ struct fb_info_chips *p = (struct fb_info_chips *) info;
+ int i;
+
+ if (blank > 1) {
+ pmu_enable_backlight(0);
+ } else if (blank) {
+ for (i = 0; i < 256; ++i) {
+ out_8(p->io_base + 0x3c8, i);
+ udelay(1);
+ out_8(p->io_base + 0x3c9, 0);
+ out_8(p->io_base + 0x3c9, 0);
+ out_8(p->io_base + 0x3c9, 0);
+ }
+ } else {
+ pmu_enable_backlight(1);
+ do_install_cmap(currcon, info);
+ }
+}
+
+static int chipsfb_getcolreg(u_int regno, u_int *red, u_int *green,
+ u_int *blue, u_int *transp, struct fb_info *info)
+{
+ struct fb_info_chips *p = (struct fb_info_chips *) info;
+
+ if (regno > 255)
+ return 1;
+ *red = p->palette[regno].red;
+ *green = p->palette[regno].green;
+ *blue = p->palette[regno].blue;
+ return 0;
+}
+
+static int chipsfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info)
+{
+ struct fb_info_chips *p = (struct fb_info_chips *) info;
+
+ if (regno > 255)
+ return 1;
+ p->palette[regno].red = red;
+ p->palette[regno].green = green;
+ p->palette[regno].blue = blue;
+ out_8(p->io_base + 0x3c8, regno);
+ udelay(1);
+ out_8(p->io_base + 0x3c9, red);
+ out_8(p->io_base + 0x3c9, green);
+ out_8(p->io_base + 0x3c9, blue);
+
+#ifdef FBCON_HAS_CFB16
+ if (regno < 16)
+ fbcon_cfb16_cmap[regno] = (red << 10) | (green << 5) | blue;
+#endif
+
+ return 0;
+}
+
+static void do_install_cmap(int con, struct fb_info *info)
+{
+ if (con != currcon)
+ return;
+ if (fb_display[con].cmap.len)
+ fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
+ chipsfb_setcolreg, info);
+ else
+ fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), &fb_display[con].var, 1,
+ chipsfb_setcolreg, info);
+}
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+/* from drivers/macintosh/pmac-cons.h */
+#define VMODE_800_600_60 10 /* 800x600, 60Hz */
+#endif /* CONFIG_FB_COMPAT_XPMAC */
+
+static void chips_set_bitdepth(struct fb_info_chips *p, struct display* disp, int con, int bpp)
+{
+ int err;
+ struct fb_fix_screeninfo* fix = &p->fix;
+ struct fb_var_screeninfo* var = &p->var;
+
+ if (bpp == 16) {
+ if (con == currcon) {
+ write_cr(0x13, 200); // 16 bit display width (decimal)
+ write_xr(0x81, 0x14); // 15 bit (TrueColor) color mode
+ write_xr(0x82, 0x00); // disable palettes
+ write_xr(0x20, 0x10); // 16 bit blitter mode
+ }
+
+ fix->line_length = 800*2;
+ fix->visual = FB_VISUAL_TRUECOLOR;
+
+ var->red.offset = 10;
+ var->green.offset = 5;
+ var->blue.offset = 0;
+ var->red.length = var->green.length = var->blue.length = 5;
+
+#ifdef FBCON_HAS_CFB16
+ disp->dispsw = &fbcon_cfb16;
+#else
+ disp->dispsw = NULL;
+#endif
+ } else if (bpp == 8) {
+ if (con == currcon) {
+ write_cr(0x13, 100); // 8 bit display width (decimal)
+ write_xr(0x81, 0x12); // 8 bit color mode
+ write_xr(0x82, 0x08); // Graphics gamma enable
+ write_xr(0x20, 0x00); // 8 bit blitter mode
+ }
+
+ fix->line_length = 800;
+ fix->visual = FB_VISUAL_PSEUDOCOLOR;
+
+ var->red.offset = var->green.offset = var->blue.offset = 0;
+ var->red.length = var->green.length = var->blue.length = 8;
+
+#ifdef FBCON_HAS_CFB8
+ disp->dispsw = &fbcon_cfb8;
+#else
+ disp->dispsw = NULL;
+#endif
+ }
+
+ var->bits_per_pixel = bpp;
+ disp->line_length = p->fix.line_length;
+ disp->visual = fix->visual;
+ disp->var = *var;
+
+#ifdef CONFIG_PMAC_PBOOK
+ display_info.depth = bpp;
+ display_info.pitch = fix->line_length;
+#endif
+
+ if (p->info.changevar)
+ (*p->info.changevar)(con);
+
+ if ((err = fb_alloc_cmap(&disp->cmap, 0, 0)))
+ return;
+ do_install_cmap(con, (struct fb_info *)p);
+}
+
+__initfunc(static void init_chips(struct fb_info_chips *p))
+{
+ int i;
+
+ memset(&p->fix, 0, sizeof(p->fix));
+ strcpy(p->fix.id, "C&T 65550");
+ p->fix.smem_start = (char *) p->chips_base_phys;
+ p->fix.smem_len = 800 * 600;
+ p->fix.mmio_start = (char *) p->chips_io_phys;
+ p->fix.type = FB_TYPE_PACKED_PIXELS;
+ p->fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ p->fix.line_length = 800;
+
+ memset(&p->var, 0, sizeof(p->var));
+ p->var.xres = 800;
+ p->var.yres = 600;
+ p->var.xres_virtual = 800;
+ p->var.yres_virtual = 600;
+ p->var.bits_per_pixel = 8;
+ p->var.red.length = p->var.green.length = p->var.blue.length = 8;
+ p->var.height = p->var.width = -1;
+ p->var.vmode = FB_VMODE_NONINTERLACED;
+ p->var.pixclock = 10000;
+ p->var.left_margin = p->var.right_margin = 16;
+ p->var.upper_margin = p->var.lower_margin = 16;
+ p->var.hsync_len = p->var.vsync_len = 8;
+
+ memset(&p->disp, 0, sizeof(p->disp));
+ p->disp.var = p->var;
+ p->disp.cmap.red = NULL;
+ p->disp.cmap.green = NULL;
+ p->disp.cmap.blue = NULL;
+ p->disp.cmap.transp = NULL;
+ p->disp.screen_base = (char *) p->frame_buffer;
+ p->disp.visual = p->fix.visual;
+ p->disp.type = p->fix.type;
+ p->disp.type_aux = p->fix.type_aux;
+ p->disp.line_length = p->fix.line_length;
+ p->disp.can_soft_blank = 1;
+ p->disp.dispsw = &fbcon_cfb8;
+ p->disp.scrollmode = SCROLL_YREDRAW;
+
+ strcpy(p->info.modename, p->fix.id);
+ p->info.node = -1;
+ p->info.fbops = &chipsfb_ops;
+ p->info.disp = &p->disp;
+ p->info.fontname[0] = 0;
+ p->info.changevar = NULL;
+ p->info.switch_con = &chipsfb_switch;
+ p->info.updatevar = &chipsfb_updatevar;
+ p->info.blank = &chipsfb_blank;
+
+ for (i = 0; i < 16; ++i) {
+ int j = color_table[i];
+ p->palette[i].red = default_red[j];
+ p->palette[i].green = default_grn[j];
+ p->palette[i].blue = default_blu[j];
+ }
+
+ if (register_framebuffer(&p->info) < 0) {
+ kfree(p);
+ return;
+ }
+
+ printk("fb%d: Chips 65550 frame buffer\n", GET_FB_IDX(p->info.node));
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+ if (!console_fb_info) {
+ display_info.height = p->var.yres;
+ display_info.width = p->var.xres;
+ display_info.depth = 8;
+ display_info.pitch = p->fix.line_length;
+ display_info.mode = VMODE_800_600_60;
+ strncpy(display_info.name, "chips65550",
+ sizeof(display_info.name));
+ display_info.fb_address = p->chips_base_phys + 0x800000;
+ display_info.cmap_adr_address = p->chips_io_phys + 0x3c8;
+ display_info.cmap_data_address = p->chips_io_phys + 0x3c9;
+ display_info.disp_reg_address = p->chips_base_phys + 0xc00000;
+ console_fb_info = &p->info;
+ }
+#endif /* CONFIG_FB_COMPAT_XPMAC */
+
+#ifdef CONFIG_PMAC_PBOOK
+ if (all_chips == NULL)
+ notifier_chain_register(&sleep_notifier_list,
+ &chips_sleep_notifier);
+#endif /* CONFIG_PMAC_PBOOK */
+ p->next = all_chips;
+ all_chips = p;
+}
+
+__initfunc(void chips_init(void))
+{
+#ifndef CONFIG_FB_OF
+ struct device_node *dp;
+
+ dp = find_devices("chips65550");
+ if (dp != 0)
+ chips_of_init(dp);
+#endif /* CONFIG_FB_OF */
+}
+
+__initfunc(void chips_of_init(struct device_node *dp))
+{
+ struct fb_info_chips *p;
+ unsigned long addr;
+ unsigned char bus, devfn;
+ unsigned short cmd;
+
+ if (dp->n_addrs == 0)
+ return;
+ p = kmalloc(sizeof(*p), GFP_ATOMIC);
+ if (p == 0)
+ return;
+ addr = dp->addrs[0].address;
+ p->chips_base_phys = addr;
+ p->frame_buffer = __ioremap(addr+0x800000, 0x100000, _PAGE_NO_CACHE);
+ p->blitter_regs = ioremap(addr + 0xC00000, 0x1000);
+
+ if (pci_device_loc(dp, &bus, &devfn) == 0) {
+ pcibios_read_config_word(bus, devfn, PCI_COMMAND, &cmd);
+ cmd |= 3; /* enable memory and IO space */
+ pcibios_write_config_word(bus, devfn, PCI_COMMAND, cmd);
+ p->io_base = (unsigned char *) pci_io_base(bus);
+ /* XXX really want the physical address here */
+ p->chips_io_phys = (unsigned long) pci_io_base(bus);
+ }
+
+ /* Clear the entire framebuffer */
+ memset(p->frame_buffer, 0, 0x100000);
+
+ /* turn on the backlight */
+ pmu_enable_backlight(1);
+
+ init_chips(p);
+}
+
+#ifdef CONFIG_PMAC_PBOOK
+/*
+ * Save the contents of the frame buffer when we go to sleep,
+ * and restore it when we wake up again.
+ */
+int
+chips_sleep_notify(struct notifier_block *this, unsigned long code, void *x)
+{
+ struct fb_info_chips *p;
+
+ for (p = all_chips; p != NULL; p = p->next) {
+ int nb = p->var.yres * p->fix.line_length;
+
+ switch (code) {
+ case PBOOK_SLEEP:
+ p->save_framebuffer = vmalloc(nb);
+ if (p->save_framebuffer)
+ memcpy(p->save_framebuffer,
+ p->frame_buffer, nb);
+ break;
+ case PBOOK_WAKE:
+ if (p->save_framebuffer) {
+ memcpy(p->frame_buffer,
+ p->save_framebuffer, nb);
+ vfree(p->save_framebuffer);
+ p->save_framebuffer = 0;
+ }
+ break;
+ }
+ }
+ return NOTIFY_DONE;
+}
+#endif /* CONFIG_PMAC_PBOOK */
diff --git a/drivers/video/clgenfb.c b/drivers/video/clgenfb.c
new file mode 100644
index 000000000..fc3f15efe
--- /dev/null
+++ b/drivers/video/clgenfb.c
@@ -0,0 +1,2121 @@
+/*
+ * Based on retz3fb.c and clgen.c
+ */
+
+#include <linux/module.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/delay.h>
+#include <linux/fb.h>
+#include <linux/zorro.h>
+#include <linux/init.h>
+#include <asm/amigahw.h>
+#include <asm/pgtable.h>
+#include <asm/delay.h>
+#include "fbcon.h"
+
+#include "fbcon.h"
+#include "fbcon-mfb.h"
+#include "fbcon-cfb8.h"
+#include "fbcon-cfb16.h"
+#include "fbcon-cfb24.h"
+#include "fbcon-cfb32.h"
+
+#include "clgenfb.h"
+
+#define CLGEN_VERSION "1.4 ?"
+/* #define DEBUG if(1) */
+#define DEBUG if(0)
+
+#define arraysize(x) (sizeof(x)/sizeof(*(x)))
+
+/* zorro IDs */
+#define ZORRO_PROD_HELFRICH_SD64_RAM 0x08930A00
+#define ZORRO_PROD_HELFRICH_SD64_REG 0x08930B00
+#define ZORRO_PROD_HELFRICH_PICCOLO_RAM 0x08930500
+#define ZORRO_PROD_HELFRICH_PICCOLO_REG 0x08930600
+#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM 0x08770B00
+#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_REG 0x08770C00
+#define ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM 0x08910200
+#define ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_REG 0x08910100
+#define ZORRO_PROD_VILLAGE_TRONIC_PICASSO_IV_Z3 0x08771800
+
+/* 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
+
+#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;
+};
+
+/* 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 */
+
+ struct clgenfb_par currentmode;
+};
+
+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 */
+
+/*
+ * Predefined Video Modes
+ */
+
+static struct fb_videomode clgenfb_predefined[] __initdata =
+{
+ { "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
+ }
+ },
+
+ /* 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
+ }
+ }
+};
+
+#define NUM_TOTAL_MODES arraysize(clgenfb_predefined)
+static struct fb_var_screeninfo clgenfb_default;
+
+/*
+ * Frame Buffer Name
+ */
+
+static char clgenfb_name[16] = "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);
+
+/* 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
+};
+
+/*--- Hardware Specific Routines -------------------------------------------*/
+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,
+ struct fb_info_gen *info);
+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,
+ unsigned blue, unsigned transp,
+ struct fb_info *info);
+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 struct display_switch *clgen_get_dispsw(const void *par,
+ struct fb_info_gen *info);
+
+/* function table of the above functions */
+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_get_dispsw
+};
+
+/* Text console acceleration */
+
+#ifdef FBCON_HAS_CFB8
+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,
+ 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)
+};
+#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);
+
+/*** END PROTOTYPES ********************************************************/
+/*****************************************************************************/
+/*** BEGIN Interface Used by the World ***************************************/
+
+static int opencount = 0;
+
+/*--- Open /dev/fbx ---------------------------------------------------------*/
+int clgenfb_open(struct fb_info *info, int user)
+{
+ MOD_INC_USE_COUNT;
+ if (opencount++ == 0) switch_monitor(1);
+ return 0;
+}
+
+/*--- Close /dev/fbx --------------------------------------------------------*/
+int clgenfb_release(struct fb_info *info, int user)
+{
+ if (--opencount == 0) switch_monitor(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)
+{
+ printk(">clgenfb_ioctl()\n");
+ /* Nothing exciting here... */
+ printk("<clgenfb_ioctl()\n");
+ return -EINVAL;
+}
+
+/**** END Interface used by the World *************************************/
+/****************************************************************************/
+/**** BEGIN Hardware specific Routines **************************************/
+
+static void clgen_detect(void)
+{
+ printk(">clgen_detect()\n");
+ printk("<clgen_detect()\n");
+}
+
+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;
+
+ /* 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->regs;
+ fix->mmio_len = 0x10000;
+ fix->accel = FB_ACCEL_NONE;
+
+ return 0;
+}
+
+static int clgen_decode_var(const struct fb_var_screeninfo *var, void *par,
+ struct fb_info_gen *info)
+{
+ 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
+
+ _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;
+ }
+
+ 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.xres_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");
+ 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;
+ break;
+
+ case 16:
+ _par->line_length = _par->var.xres_virtual * 2;
+ _par->visual = FB_VISUAL_DIRECTCOLOR;
+ break;
+
+ case 24:
+ _par->line_length = _par->var.xres_virtual * 3;
+ _par->visual = FB_VISUAL_DIRECTCOLOR;
+ break;
+
+ case 32:
+ _par->line_length = _par->var.xres_virtual * 4;
+ _par->visual = FB_VISUAL_DIRECTCOLOR;
+ break;
+ }
+ _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;
+}
+
+
+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;
+}
+
+/* get current video mode */
+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;
+
+ *_par = _info->currentmode;
+}
+
+/*************************************************************************
+ clgen_set_par()
+
+ 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)
+{
+ 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, 0xff, 0xff, 0xff); /* 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;
+
+ 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;
+
+ 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;
+
+ case BT_SPECTRUM:
+ DEBUG printk(KERN_INFO "(for Spectrum)\n");
+ WSeq(SEQR7, 0x80);
+/* ### ueberall 0x22? */
+ WSeq(SEQR1F, 0x22); /* ##vorher 1c MCLK select */
+ WSeq(SEQRF, 0xb0); /* evtl d0? avoid FIFO underruns..? */
+ 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;
+
+ 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;
+
+ case BT_PICCOLO:
+ WSeq(SEQR7, 0x81);
+ WSeq(SEQR1F, 0x22); /* ### vorher 1c MCLK select */
+ WSeq(SEQRF, 0xb0); /* Fast Page-Mode writes */
+ break;
+
+ case BT_PICASSO:
+ WSeq(SEQR7, 0x21);
+ WSeq(SEQR1F, 0x22); /* ### vorher 1c MCLK select */
+ WSeq(SEQRF, 0xb0); /* Fast Page-Mode writes */
+ break;
+
+ case BT_SPECTRUM:
+ WSeq(SEQR7, 0x81);
+ WSeq(SEQR1F, 0x22); /* ### vorher 1c MCLK select */
+ WSeq(SEQRF, 0xb0); /* Fast Page-Mode writes */
+ break;
+
+ case BT_PICASSO4:
+ WSeq(SEQR7, 0x21);
+ WSeq(SEQRF, 0xb8); /* ### INCOMPLETE!! */
+/* WSeq(SEQR1F, 0x1c); */
+ 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(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;
+
+ case BT_PICCOLO:
+ WSeq(SEQR7, 0x87);
+ WSeq(SEQRF, 0xb0); /* Fast Page-Mode writes */
+ WSeq(SEQR1F, 0x22); /* MCLK select */
+ break;
+
+ case BT_PICASSO:
+ WSeq(SEQR7, 0x27);
+ WSeq(SEQRF, 0xb0); /* Fast Page-Mode writes */
+ WSeq(SEQR1F, 0x22); /* MCLK select */
+ break;
+
+ case BT_SPECTRUM:
+ WSeq(SEQR7, 0x87);
+ WSeq(SEQRF, 0xb0); /* Fast Page-Mode writes */
+ WSeq(SEQR1F, 0x22); /* MCLK select */
+ break;
+
+ case BT_PICASSO4:
+ WSeq(SEQR7, 0x27);
+/* WSeq(SEQR1F, 0x1c); */
+ 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(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;
+
+ case BT_PICASSO:
+ WSeq(SEQR7, 0x25);
+ WSeq(SEQRF, 0xb0); /* Fast Page-Mode writes */
+ WSeq(SEQR1F, 0x22); /* MCLK select */
+ break;
+
+ 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;
+
+ 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;
+
+/*** FB_VMODE_CLOCK_HALVE in linux/fb.h not defined anymore ?
+ if (var->vmode & FB_VMODE_CLOCK_HALVE)
+ tmp |= 0x08;
+*/
+
+ WSeq(SEQR1, tmp);
+ DEBUG printk("SEQR1: %d\n", tmp);
+
+#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");
+#endif
+
+ fb_info->currentmode = *_par;
+
+ 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);
+
+ DEBUG printk("<clgen_set_par()\n");
+ return;
+}
+
+static int clgen_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+ unsigned *blue, unsigned *transp,
+ struct fb_info *info)
+{
+ unsigned char bred, bgreen, bblue;
+
+ if (regno > 255 || regno < 0)
+ return (1);
+
+ fb_info = (struct clgenfb_info *)info;
+
+ RClut(regno, &bred, &bgreen, &bblue);
+
+ *red = (u_int)bred;
+ *green = (u_int)bgreen;
+ *blue = (u_int)bblue;
+ *transp = 0;
+ return (0);
+}
+
+static int clgen_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp,
+ struct fb_info *info)
+{
+ if (regno > 255 || regno < 0)
+ return (1);
+
+ fb_info = (struct clgenfb_info *)info;
+
+ /* "transparent" stuff is completely ignored. */
+ WClut(regno, (red & 0xff), (green & 0xff), (blue & 0xff));
+
+ return (0);
+}
+
+/*************************************************************************
+ 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)
+{
+ 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);
+}
+
+
+static int clgen_blank(int blank_mode, struct fb_info_gen *info)
+{
+ unsigned char val;
+ printk(">clgen_blank(%d)\n",blank_mode);
+
+ fb_info = (struct clgenfb_info *)info;
+
+ val = RSeq(SEQR1);
+ if (blank_mode)
+ WSeq(SEQR1, val | 0x20); /* set "FullBandwidth" bit */
+ else
+ WSeq(SEQR1, val & 0xdf); /* clear "FullBandwidth" bit */
+
+ printk("<clgen_blank()\n");
+ return 0;
+}
+
+/**** END Hardware specific Routines **************************************/
+/****************************************************************************/
+/**** BEGIN Internal Routines ***********************************************/
+
+static void init_vgachip(void)
+{
+ 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 */
+ }
+ 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, 0xff, 0xff, 0xff); /* foreground: white */
+ WClut( 2, 0x00, 0x80, 0x00);
+ WClut( 3, 0x00, 0x80, 0x80);
+ WClut( 4, 0x80, 0x00, 0x00);
+ WClut( 5, 0x80, 0x00, 0x80);
+ WClut( 6, 0x80, 0x40, 0x00);
+ WClut( 7, 0x80, 0x80, 0x80);
+ WClut( 8, 0x40, 0x40, 0x40);
+ WClut( 9, 0x40, 0x40, 0xc0);
+ WClut(10, 0x40, 0xc0, 0x40);
+ WClut(11, 0x40, 0xc0, 0xc0);
+ WClut(12, 0xc0, 0x40, 0x40);
+ WClut(13, 0xc0, 0x40, 0xc0);
+ WClut(14, 0xc0, 0xc0, 0x40);
+ WClut(15, 0xc0, 0xc0, 0xc0);
+
+ /* the rest a grey ramp */
+ {
+ int i;
+
+ for (i = 16; i < 256; i++)
+ WClut(i, i, i, i);
+ }
+
+
+ /* misc... */
+ WHDR(0); /* Hidden DAC register: - */
+
+#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;
+
+ ram += (fb_info->size >> 1);
+
+ for (i = 0; i < 256; i++)
+ ram[i] = (unsigned char)i;
+
+ for (i = 0; i < 256; i++)
+ {
+ if (ram[i] != i)
+ flag = 1;
+ }
+
+ /* if the DRAM test failed, halve RAM value */
+ if (flag)
+ {
+ 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;
+}
+
+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);
+ 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;
+ }
+ 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;
+ }
+}
+
+static struct display_switch *clgen_get_dispsw(const void *par,
+ struct fb_info_gen *info)
+{
+ struct clgenfb_par *_par = (struct clgenfb_par*) par;
+
+ printk("clgen_get_dispsw(): ");
+ switch (_par->var.bits_per_pixel)
+ {
+#ifdef FBCON_HAS_MFB
+ case 1:
+ printk("monochrome\n");
+ return &fbcon_mfb;
+#endif
+#ifdef FBCON_HAS_CFB8
+ case 8:
+ printk("8 bit color depth\n");
+ return &fbcon_clgen_8;
+#endif
+#ifdef FBCON_HAS_CFB16
+ case 16:
+ printk("16 bit color depth\n");
+ return &fbcon_cfb16;
+#endif
+#ifdef FBCON_HAS_CFB24
+ case 24:
+ printk("24 bit color depth\n");
+ return &fbcon_cfb24;
+#endif
+#ifdef FBCON_HAS_CFB32
+ case 32:
+ printk("32 bit color depth\n");
+ return &fbcon_cfb32;
+#endif
+
+ default:
+ printk("unsupported color depth\n");
+ return NULL;
+ }
+}
+
+static void fbcon_clgen8_bmove(struct display *p, int sy, int sx,
+ int dy, int dx, int height, int width)
+{
+ sx *= p->fontwidth;
+ sy *= p->fontheight;
+ dx *= p->fontwidth;
+ dy *= p->fontheight;
+ width *= p->fontwidth;
+ height *= p->fontheight;
+
+ 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();
+}
+
+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 *= p->fontwidth;
+ sy *= p->fontheight;
+ width *= p->fontwidth;
+ height *= p->fontheight;
+
+ 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();
+}
+
+
+/********************************************************************/
+/* clgenfb_init() - master initialization function */
+/********************************************************************/
+__initfunc(void clgenfb_init(void))
+{
+ 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 = (unsigned char *)kernel_map(board_addr, 16777216,
+ KERNELMAP_NOCACHE_SER, NULL);
+ DEBUG printk(KERN_INFO "clgen: Virtual address for board set to: $%p\n", fb_info->regs);
+ fb_info->regs += 0x600000;
+
+ fb_info->fbmem = kernel_map(board_addr + 16777216, 16777216,
+ KERNELMAP_NOCACHE_SER, NULL);
+ 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);
+
+ if (board_addr > 0x01000000)
+ fb_info->fbmem = kernel_map(board_addr, board_size,
+ KERNELMAP_NOCACHE_SER, NULL);
+ 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);
+
+ 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;
+
+ /* 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;
+
+ 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);
+ return;
+ }
+
+ printk("<clgenfb_init()\n");
+ return;
+}
+
+ /*
+ * Cleanup
+ */
+
+void clgenfb_cleanup(struct clgenfb_info *info)
+{
+ printk(">clgenfb_cleanup()\n");
+
+ fb_info = info;
+
+ switch_monitor(0);
+
+ zorro_unconfig_board(info->keyRAM, 0);
+ if (fb_info->btype != BT_PICASSO4)
+ zorro_unconfig_board(info->keyREG, 0);
+
+ unregister_framebuffer(&info->gen.info);
+ printk("Framebuffer unregistered\n");
+ printk("<clgenfb_cleanup()\n");
+}
+
+
+/* A strtok which returns empty strings, too */
+static char *strtoke(char *s,const char *ct)
+{
+ 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;
+}
+
+/*****************************************************************/
+/* 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))
+{
+// char *this_opt;
+
+// printk("clgenfb_setup(): options: %s\n", options);
+}
+
+
+ /*
+ * Modularization
+ */
+
+#ifdef MODULE
+int init_module(void)
+{
+ printk("init_module()\n");
+ clgenfb_init(0);
+ return 0;
+}
+
+void cleanup_module(void)
+{
+ printk("module_cleanup()\n");
+ clgenfb_cleanup(fb_info);
+}
+#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)
+{
+ unsigned volatile char *reg = fb_info->regs + regnum;
+
+ 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;
+ }
+
+ *reg = val;
+}
+
+/*** RGen() - read out one of the external/general registers ***/
+unsigned char RGen(int regnum)
+{
+ unsigned volatile char *reg = fb_info->regs + regnum;
+
+ 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;
+ }
+
+ return *reg;
+}
+
+/*** WSeq() - write into a register of the sequencer ***/
+void WSeq(unsigned char regnum, unsigned char val)
+{
+ fb_info->regs[SEQRX] = regnum;
+ fb_info->regs[SEQRX+1] = val;
+}
+
+/*** RSeq() - read out one of the Sequencer registers ***/
+unsigned char RSeq(unsigned char regnum)
+{
+ fb_info->regs[SEQRX] = regnum;
+ return fb_info->regs[SEQRX+1];
+}
+
+/*** WCrt() - write into a register of the CRT controller ***/
+void WCrt(unsigned char regnum, unsigned char val)
+{
+ fb_info->regs[CRTX] = regnum;
+ fb_info->regs[CRTX+1] = val;
+}
+
+/*** RCrt() - read out one of the CRT controller registers ***/
+unsigned char RCrt(unsigned char regnum)
+{
+ fb_info->regs[CRTX] = regnum;
+ return fb_info->regs[CRTX+1];
+}
+
+/*** WGfx() - write into a register of the Gfx controller ***/
+void WGfx(unsigned char regnum, unsigned char val)
+{
+ fb_info->regs[GRX] = regnum;
+ fb_info->regs[GRX+1] = val;
+}
+
+/*** RGfx() - read out one of the Gfx controller registers ***/
+unsigned char RGfx(unsigned char regnum)
+{
+ fb_info->regs[GRX] = regnum;
+ return fb_info->regs[GRX+1];
+}
+
+/*** WAttr() - write into a register of the Attribute controller ***/
+void WAttr(unsigned char regnum, unsigned char val)
+{
+ /* 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;
+}
+
+/*** AttrOn() - turn on VideoEnable for Attribute controller ***/
+void AttrOn()
+{
+ if (RCrt(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];
+
+ /* turn on video bit */
+/* fb_info->regs[ARX] = 0x20; */
+ fb_info->regs[ARX] = 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];
+
+ fb_info->regs[ARX] = regnum;
+ return fb_info->regs[ARX+1];
+}
+
+
+/*** 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)
+{
+ unsigned char dummy;
+
+ 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);
+ /* next read dummy from pixel address (3c8) */
+ dummy = RGen(M_3C8); 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);
+
+ WGen(M_3C6, val); udelay(200);
+
+ if(fb_info->btype == BT_PICASSO)
+ {
+ /* now first reset HDR access counter */
+ dummy = RGen(M_3C8); udelay(200);
+
+ /* and at the end, restore the mask value */
+ /* ## is this mask always 0xff? */
+ WGen(M_3C6, 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)
+{
+ fb_info->SFR = val;
+ fb_info->regs[0x8000] = val;
+}
+
+/* The Picasso has a second register for switching the monitor bit */
+void WSFR2(unsigned char val)
+{
+ /* 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;
+}
+
+/*** WClut - set CLUT entry (range: 0..255 is automat. shifted to 0..63) ***/
+void WClut(unsigned char regnum, unsigned char red, unsigned char green, unsigned char blue)
+{
+ unsigned int data = 0x3c9;
+
+ /* address write mode register is not translated.. */
+ fb_info->regs[0x3c8] = regnum;
+
+ if(fb_info->btype == BT_PICASSO || fb_info->btype == BT_PICASSO4)
+ {
+ /* but DAC data register IS, at least for Picasso II */
+ if(fb_info->btype == BT_PICASSO)
+ data += 0xfff;
+ fb_info->regs[data] = (red >> 2);
+ fb_info->regs[data] = (green >> 2);
+ fb_info->regs[data] = (blue >> 2);
+ }
+ else
+ {
+ fb_info->regs[data] = (blue >> 2);
+ fb_info->regs[data] = (green >> 2);
+ fb_info->regs[data] = (red >> 2);
+ }
+}
+
+/*** RClut - read CLUT entry and convert to 0..255 range ***/
+void RClut(unsigned char regnum, unsigned char *red, unsigned char *green, unsigned char *blue)
+{
+ unsigned int data = 0x3c9;
+
+ fb_info->regs[0x3c7] = regnum;
+
+ if(fb_info->btype == BT_PICASSO || fb_info->btype == BT_PICASSO4)
+ {
+ if(fb_info->btype == BT_PICASSO)
+ data += 0xfff;
+ *red = fb_info->regs[data] << 2;
+ *green = fb_info->regs[data] << 2;
+ *blue = fb_info->regs[data] << 2;
+ }
+ else
+ {
+ *blue = fb_info->regs[data] << 2;
+ *green = fb_info->regs[data] << 2;
+ *red = fb_info->regs[data] << 2;
+ }
+}
+
+
+/*******************************************************************
+ clgen_WaitBLT()
+
+ Wait for the BitBLT engine to complete a possible earlier job
+*********************************************************************/
+
+void clgen_WaitBLT()
+{
+ /* now busy-wait until we're done */
+ while (RGfx(GR31) & 0x08)
+ ;
+}
+
+/*******************************************************************
+ clgen_BitBLT()
+
+ 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)
+{
+ u_short nwidth, nheight;
+ u_long nsrc, ndest;
+ u_char bltmode;
+
+ nwidth = width - 1;
+ nheight = height - 1;
+
+ bltmode = 0x00;
+ /* if source adr < dest addr, do the Blt backwards */
+ if (cury <= desty)
+ {
+ if (cury == desty)
+ {
+ /* if src and dest are on the same line, check x */
+ if (curx < destx)
+ bltmode |= 0x01;
+ }
+ else
+ bltmode |= 0x01;
+ }
+
+ if (!bltmode)
+ {
+ /* standard case: forward blitting */
+ nsrc = (cury * line_length) + curx;
+ ndest = (desty * line_length) + destx;
+ }
+ 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! */
+
+ /*
+ 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
+ */
+
+ /* 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 */
+
+ /* BLT width: actual number of pixels - 1 */
+ WGfx(GR20, nwidth & 0xff); /* BLT width low */
+ WGfx(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 */
+
+ /* 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 */
+
+ /* 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 */
+
+ /* BLT mode */
+ WGfx(GR30, bltmode); /* BLT mode */
+
+ /* BLT ROP: SrcCopy */
+ WGfx(GR32, 0x0d); /* BLT ROP */
+
+ /* and finally: GO! */
+ WGfx(GR31, 0x02); /* BLT Start/status */
+}
+
+/*******************************************************************
+ clgen_RectFill()
+
+ 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)
+{
+ u_short nwidth, nheight;
+ u_long ndest;
+
+ nwidth = width - 1;
+ nheight = height - 1;
+
+ ndest = (y * line_length) + x;
+
+// clgen_WaitBLT(); /* ### NOT OK for multiple boards! */
+
+ /* 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 */
+
+ /* BLT width: actual number of pixels - 1 */
+ WGfx(GR20, nwidth & 0xff); /* BLT width low */
+ WGfx(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 */
+
+ /* 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 */
+
+ /* 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 */
+
+ /* This is a ColorExpand Blt, using the */
+ /* same color for foreground and background */
+ WGfx(GR0, color); /* foreground color */
+ WGfx(GR1, color); /* background color */
+
+ /* BLT mode: color expand, Enable 8x8 copy (faster?) */
+ WGfx(GR30, 0xc0); /* BLT mode */
+
+ /* BLT ROP: SrcCopy */
+ WGfx(GR32, 0x0d); /* BLT ROP */
+
+ /* and finally: GO! */
+ WGfx(GR31, 0x02); /* BLT Start/status */
+}
+
+/**************************************************************************
+ * bestclock() - determine closest possible clock lower(?) than the
+ * 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)
+{
+ 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;
+ }
+ 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;
+ }
+ }
+ }
+ }
+}
+
diff --git a/drivers/video/clgenfb.h b/drivers/video/clgenfb.h
new file mode 100644
index 000000000..3f66ec294
--- /dev/null
+++ b/drivers/video/clgenfb.h
@@ -0,0 +1,175 @@
+
+/* definitions for Piccolo/SD64 VGA controller chip */
+/* these definitions might most of the time also work */
+/* 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 */
+
+/*** 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 */
+/* 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 */
+
+/*** 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 */
+/* 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" */
+
+/*** 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 */
+/* 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 */
+
+/*** 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) */
+
diff --git a/drivers/video/controlfb.c b/drivers/video/controlfb.c
new file mode 100644
index 000000000..466bf52ee
--- /dev/null
+++ b/drivers/video/controlfb.c
@@ -0,0 +1,997 @@
+/*
+ * controlfb.c -- frame buffer device for the PowerMac 'control' display
+ *
+ * Created 12 July 1998 by Dan Jacobowitz <dan@debian.org>
+ * Copyright (C) 1998 Dan Jacobowitz
+ *
+ * Frame buffer structure from:
+ * drivers/video/chipsfb.c -- frame buffer device for
+ * Chips & Technologies 65550 chip.
+ *
+ * Copyright (C) 1998 Paul Mackerras
+ *
+ * This file is derived from the Powermac "chips" driver:
+ * Copyright (C) 1997 Fabio Riccardi.
+ * And from the frame buffer device for Open Firmware-initialized devices:
+ * Copyright (C) 1997 Geert Uytterhoeven.
+ *
+ * Hardware information from:
+ * control.c: Console support for PowerMac "control" display adaptor.
+ * Copyright (C) 1996 Paul Mackerras
+ *
+ * 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/config.h>
+#include <linux/module.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/selection.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/nvram.h>
+#ifdef CONFIG_FB_COMPAT_XPMAC
+#include <asm/vc_ioctl.h>
+#endif
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pgtable.h>
+#include <asm/adb.h>
+#include <asm/cuda.h>
+
+#include "fbcon.h"
+#include "fbcon-cfb8.h"
+#include "fbcon-cfb16.h"
+#include "fbcon-cfb32.h"
+
+#include "macmodes.h"
+#include "controlfb.h"
+
+static int currcon = 0;
+static int switching = 0;
+
+struct fb_par_control {
+ int vmode, cmode;
+ int xres, yres;
+ int vxres, vyres;
+ int xoffset, yoffset;
+};
+
+struct fb_info_control {
+ struct fb_info info;
+ struct fb_fix_screeninfo fix;
+ struct fb_var_screeninfo var;
+ struct display disp;
+ struct fb_par_control par;
+ struct {
+ __u8 red, green, blue;
+ } palette[256];
+
+ struct cmap_regs *cmap_regs;
+ unsigned long cmap_regs_phys;
+
+ struct control_regs *control_regs;
+ unsigned long control_regs_phys;
+
+ __u8 *frame_buffer;
+ unsigned long frame_buffer_phys;
+
+ int sense, control_use_bank2;
+ unsigned long total_vram;
+};
+
+/*
+ * Exported functions
+ */
+void control_init(void);
+void control_of_init(struct device_node *dp);
+
+static int control_open(struct fb_info *info, int user);
+static int control_release(struct fb_info *info, int user);
+static int control_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info);
+static int control_get_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int control_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int control_pan_display(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int control_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+static int control_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+static int control_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg, int con, struct fb_info *info);
+
+static int read_control_sense(struct fb_info_control *p);
+static inline int control_vram_reqd(int video_mode, int color_mode);
+static void set_control_clock(unsigned char *params);
+static void control_set_hardware(struct fb_info_control *p);
+static void control_par_to_all(struct fb_info_control *p, int init);
+static inline void control_par_to_var(struct fb_par_control *par, struct fb_var_screeninfo *var);
+static int control_var_to_par(struct fb_var_screeninfo *var,
+ struct fb_par_control *par, const struct fb_info *fb_info);
+
+static void control_init_info(struct fb_info *info, struct fb_info_control *p);
+static void control_par_to_display(struct fb_par_control *par,
+ struct display *disp, struct fb_fix_screeninfo *fix, struct fb_info_control *p);
+static void control_init_display(struct display *disp);
+static void control_par_to_fix(struct fb_par_control *par, struct fb_fix_screeninfo *fix,
+ struct fb_info_control *p);
+static void control_init_fix(struct fb_fix_screeninfo *fix, struct fb_info_control *p);
+
+static struct fb_ops controlfb_ops = {
+ control_open,
+ control_release,
+ control_get_fix,
+ control_get_var,
+ control_set_var,
+ control_get_cmap,
+ control_set_cmap,
+ control_pan_display,
+ control_ioctl
+};
+
+static int controlfb_getcolreg(u_int regno, u_int *red, u_int *green,
+ u_int *blue, u_int *transp, struct fb_info *info);
+static int controlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info);
+static void do_install_cmap(int con, struct fb_info *info);
+
+
+__openfirmware
+
+
+static int control_open(struct fb_info *info, int user)
+{
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static int control_release(struct fb_info *info, int user)
+{
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+static int control_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info)
+{
+ struct fb_info_control *cp = (struct fb_info_control *) info;
+
+ *fix = cp->fix;
+ return 0;
+}
+
+static int control_get_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ struct fb_info_control *cp = (struct fb_info_control *) info;
+
+ *var = cp->var;
+ return 0;
+}
+
+/* Sets everything according to var */
+static int control_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ struct fb_info_control *p = (struct fb_info_control *) info;
+ struct display *disp;
+ struct fb_par_control par;
+ int depthchange, err;
+
+ disp = (con >= 0) ? &fb_display[con] : &p->disp;
+ if((err = control_var_to_par(var, &par, info))) {
+ printk (KERN_ERR "Error in control_set_var, calling control_var_to_par: %d.\n", err);
+ return err;
+ }
+
+ if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) {
+ printk("Not activating, in control_set_var.\n");
+ control_par_to_var(&par, var);
+ return 0;
+ }
+/* I know, we want to use fb_display[con], but grab certain info from p->var instead. */
+#define DIRTY(x) (p->var.x != var->x)
+ depthchange = DIRTY(bits_per_pixel);
+ if(!DIRTY(xres) && !DIRTY(yres) && !DIRTY(xres_virtual) &&
+ !DIRTY(yres_virtual) && !DIRTY(bits_per_pixel)) {
+ control_par_to_var(&par, var);
+ p->var = disp->var = *var;
+ return 0;
+ }
+printk("Original bpp is %d, new bpp %d.\n", p->var.bits_per_pixel, var->bits_per_pixel);
+ /* OK, we're getting here at the right times... */
+ p->par = par;
+ control_par_to_var(&par, var);
+ p->var = *var;
+ control_par_to_fix(&par, &p->fix, p);
+ control_par_to_display(&par, disp, &p->fix, p);
+ p->disp = *disp;
+
+ if(info->changevar && !switching) /* Don't want to do this if just switching consoles. */
+ (*info->changevar)(con);
+ if(con == currcon)
+ control_set_hardware(p);
+ if(depthchange)
+ if((err = fb_alloc_cmap(&disp->cmap, 0, 0)))
+ return err;
+ if(depthchange || switching)
+ do_install_cmap(con, info);
+ return 0;
+}
+
+static int control_pan_display(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ if (var->xoffset != 0 || var->yoffset != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int control_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ if (con == currcon) /* current console? */
+ return fb_get_cmap(cmap, &fb_display[con].var, kspc,
+ controlfb_getcolreg, info);
+ if (fb_display[con].cmap.len) /* non default colormap? */
+ fb_copy_cmap(&fb_display[con].cmap, cmap, kspc? 0: 2);
+ else {
+ int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
+ fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
+ }
+ return 0;
+}
+
+static int control_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ struct display *disp = &fb_display[con];
+ int err;
+
+ if (disp->cmap.len == 0) {
+ int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
+ err = fb_alloc_cmap(&disp->cmap, size, 0);
+ if (err)
+ return err;
+ }
+
+ if (con == currcon)
+ return fb_set_cmap(cmap, &disp->var, kspc, controlfb_setcolreg,
+ info);
+ fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);
+ return 0;
+}
+
+static int control_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg, int con, struct fb_info *info)
+{
+ return -EINVAL;
+}
+
+static int controlfb_switch(int con, struct fb_info *info)
+{
+ if (fb_display[currcon].cmap.len)
+ fb_get_cmap(&fb_display[currcon].cmap,
+ &fb_display[currcon].var, 1, controlfb_getcolreg,
+ info);
+ currcon = con;
+#if 0
+ control_var_to_par(&fb_display[currcon].var, &par, info);
+ control_set_par(&par, info); /*STOPPEDHERE - did i define that? */
+ do_install_cmap(con, info);
+#else
+ /* I see no reason not to do this. Minus info->changevar(). */
+ /* DOH. This makes control_set_var compare, you guessed it, */
+ /* fb_display[con].var (first param), and fb_display[con].var! */
+ /* Perhaps I just fixed that... */
+ switching = 1;
+ control_set_var(&fb_display[con].var, con, info);
+ switching = 0;
+#endif
+ return 0;
+}
+
+static int controlfb_updatevar(int con, struct fb_info *info)
+{
+ return 0;
+}
+
+static void controlfb_blank(int blank_mode, struct fb_info *info)
+{
+/*
+ * 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
+ */
+/* [danj] I think there's something fishy about those constants... */
+ struct fb_info_control *p = (struct fb_info_control *) info;
+ int ctrl;
+
+ ctrl = ld_le32(&p->control_regs->ctrl.r) | 0x33;
+ if (blank_mode)
+ --blank_mode;
+ if (blank_mode & VESA_VSYNC_SUSPEND)
+ ctrl &= ~3;
+ if (blank_mode & VESA_HSYNC_SUSPEND)
+ ctrl &= ~0x30;
+ out_le32(&p->control_regs->ctrl.r, ctrl);
+
+/* TODO: Figure out how the heck to powerdown this thing! */
+
+ return;
+}
+
+static int controlfb_getcolreg(u_int regno, u_int *red, u_int *green,
+ u_int *blue, u_int *transp, struct fb_info *info)
+{
+ struct fb_info_control *p = (struct fb_info_control *) info;
+
+ if (regno > 255)
+ return 1;
+ *red = p->palette[regno].red;
+ *green = p->palette[regno].green;
+ *blue = p->palette[regno].blue;
+ return 0;
+}
+
+static int controlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info)
+{
+ struct fb_info_control *p = (struct fb_info_control *) info;
+
+ if (regno > 255 || regno < 0)
+ return 1;
+ p->palette[regno].red = red;
+ p->palette[regno].green = green;
+ p->palette[regno].blue = blue;
+
+ out_8(&p->cmap_regs->addr, regno); /* tell clut what addr to fill */
+ out_8(&p->cmap_regs->lut, red); /* send one color channel at */
+ out_8(&p->cmap_regs->lut, green); /* a time... */
+ out_8(&p->cmap_regs->lut, blue);
+
+ if(regno < 16) {
+#if 0
+#ifdef FBCON_HAS_CFB16
+ fbcon_cfb16_cmap[regno] = (red << 10) | (green << 5) | blue;
+#endif
+#ifdef FBCON_HAS_CFB32
+ fbcon_cfb32_cmap[regno] = (red << 16) | (green << 8) | blue;
+ /* I think. */
+#endif
+#else
+#ifdef FBCON_HAS_CFB16
+ fbcon_cfb16_cmap[regno] = (regno << 10) | (regno << 5) | regno;
+#endif
+#ifdef FBCON_HAS_CFB32
+ fbcon_cfb32_cmap[regno] = (regno << 24) | (regno << 16) | (regno << 8) | regno;
+ /* I think. */
+#endif
+#endif
+ }
+ return 0;
+}
+
+static void do_install_cmap(int con, struct fb_info *info)
+{
+ if (con != currcon)
+ return;
+ if (fb_display[con].cmap.len)
+ fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
+ controlfb_setcolreg, info);
+ else {
+ int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
+ fb_set_cmap(fb_default_cmap(size), &fb_display[con].var, 1,
+ controlfb_setcolreg, info);
+ }
+}
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+extern struct vc_mode display_info;
+extern struct fb_info *console_fb_info;
+#if 0
+extern int (*console_setmode_ptr)(struct vc_mode *, int);
+extern int (*console_set_cmap_ptr)(struct fb_cmap *, int, int,
+ struct fb_info *);
+int console_setmode(struct vc_mode *, int);
+#endif
+#endif /* CONFIG_FB_COMPAT_XPMAC */
+
+static inline int control_vram_reqd(int video_mode, int color_mode)
+{
+ return control_reg_init[video_mode-1]->vres
+ * control_reg_init[video_mode-1]->pitch[color_mode];
+}
+
+static void set_control_clock(unsigned char *params)
+{
+ struct adb_request req;
+ int i;
+
+ for (i = 0; i < 3; ++i) {
+ cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
+ 0x50, i + 1, params[i]);
+ while (!req.complete)
+ cuda_poll();
+ }
+}
+
+
+__initfunc(static void init_control(struct fb_info_control *p))
+{
+ struct fb_par_control *par = &p->par;
+
+ p->sense = read_control_sense(p);
+ printk("Monitor sense value = 0x%x, ", p->sense);
+ /* Try to pick a video mode out of NVRAM if we have one. */
+ par->vmode = nvram_read_byte(NV_VMODE);
+ if(par->vmode <= 0 || par->vmode > VMODE_MAX || !control_reg_init[par->vmode - 1])
+ par->vmode = VMODE_CHOOSE;
+ if(par->vmode == VMODE_CHOOSE)
+ par->vmode = mac_map_monitor_sense(p->sense);
+ if(!control_reg_init[par->vmode - 1])
+ par->vmode = VMODE_640_480_60;
+
+ par->cmode = nvram_read_byte(NV_CMODE);
+ if(par->cmode < CMODE_8 || par->cmode > CMODE_32)
+ par->cmode = CMODE_8;
+ /*
+ * Reduce the pixel size if we don't have enough VRAM.
+ */
+ while(par->cmode > CMODE_8 && control_vram_reqd(par->vmode, par->cmode) > p->total_vram)
+ par->cmode--;
+
+ printk("using video mode %d and color mode %d.\n", par->vmode, par->cmode);
+
+ par->vxres = par->xres = control_reg_init[par->vmode - 1]->hres;
+ par->vyres = par->yres = control_reg_init[par->vmode - 1]->vres;
+ par->xoffset = par->yoffset = 0;
+
+ control_par_to_all(p, 1);
+
+ if (register_framebuffer(&p->info) < 0) {
+ kfree(p);
+ return;
+ }
+ control_set_hardware(p);
+
+ printk("fb%d: control display adapter\n", GET_FB_IDX(p->info.node));
+}
+
+/* Now how about actually saying, Make it so! */
+/* Some things in here probably don't need to be done each time. */
+static void control_set_hardware(struct fb_info_control *p)
+{
+ struct control_regvals *init;
+ struct preg *rp;
+ int flags, ctrl, i;
+ int vmode, cmode;
+
+ vmode = p->par.vmode;
+ cmode = p->par.cmode;
+
+ init = control_reg_init[vmode - 1];
+
+ if (control_vram_reqd(vmode, cmode) > 0x200000)
+ flags = 0x51;
+ else if (p->control_use_bank2)
+ flags = 0x39;
+ else
+ flags = 0x31;
+ if (vmode >= VMODE_1280_960_75 && cmode >= CMODE_16)
+ ctrl = 0x7f;
+ else
+ ctrl = 0x3b;
+
+ /* Initialize display timing registers */
+ out_le32(&p->control_regs->ctrl.r, 0x43b);
+
+ set_control_clock(init->clock_params);
+
+ p->cmap_regs->addr = 0x20; p->cmap_regs->d2 = init->radacal_ctrl[cmode];
+ p->cmap_regs->addr = 0x21; p->cmap_regs->d2 = p->control_use_bank2 ? 0: 1;
+ p->cmap_regs->addr = 0x10; p->cmap_regs->d2 = 0;
+ p->cmap_regs->addr = 0x11; p->cmap_regs->d2 = 0;
+
+ rp = &p->control_regs->vswin;
+ for (i = 0; i < 16; ++i, ++rp)
+ out_le32(&rp->r, init->regs[i]);
+
+ out_le32(&p->control_regs->pitch.r, init->pitch[cmode]);
+ out_le32(&p->control_regs->mode.r, init->mode[cmode]);
+ out_le32(&p->control_regs->flags.r, flags);
+ out_le32(&p->control_regs->start_addr.r, 0);
+ out_le32(&p->control_regs->reg18.r, 0x1e5);
+ out_le32(&p->control_regs->reg19.r, 0);
+
+ for (i = 0; i < 16; ++i) {
+ controlfb_setcolreg(color_table[i], default_red[i], default_grn[i],
+ default_blu[i], 0, (struct fb_info *)p);
+ }
+/* Does the above need to be here each time? -- danj */
+
+ /* Turn on display */
+ out_le32(&p->control_regs->ctrl.r, ctrl);
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+ /* And let the world know the truth. */
+ if (!console_fb_info || console_fb_info == &p->info) {
+ display_info.height = p->var.yres;
+ display_info.width = p->var.xres;
+ display_info.depth = (cmode == CMODE_32) ? 32 :
+ ((cmode == CMODE_16) ? 16 : 8);
+ display_info.pitch = p->fix.line_length;
+ display_info.mode = vmode;
+ strncpy(display_info.name, "control",
+ sizeof(display_info.name));
+ display_info.fb_address = p->frame_buffer_phys
+ + control_reg_init[vmode-1]->offset[cmode];
+ display_info.cmap_adr_address = p->cmap_regs_phys;
+ display_info.cmap_data_address = p->cmap_regs_phys + 0x30;
+ display_info.disp_reg_address = p->control_regs_phys;
+ console_fb_info = &p->info;
+ }
+#endif /* CONFIG_FB_COMPAT_XPMAC */
+}
+
+__initfunc(void control_init(void))
+{
+#ifndef CONFIG_FB_OF
+ struct device_node *dp;
+
+ dp = find_devices("control");
+ if (dp != 0)
+ control_of_init(dp);
+#endif /* CONFIG_FB_OF */
+}
+
+__initfunc(void control_of_init(struct device_node *dp))
+{
+ struct fb_info_control *p;
+ unsigned long addr, size;
+ int i, bank1, bank2;
+
+ if(dp->next != 0)
+ printk("Warning: only using first control display device.\n");
+ /* danj: I have a feeling this no longer applies - if we somehow *
+ * had two of them, they'd be two framebuffers, right? */
+ if(dp->n_addrs != 2)
+ panic("expecting 2 address for control (got %d)", dp->n_addrs);
+ p = kmalloc(sizeof(*p), GFP_ATOMIC);
+ if (p == 0)
+ return;
+
+ /* Map in frame buffer and registers */
+ for (i = 0; i < dp->n_addrs; ++i) {
+ addr = dp->addrs[i].address;
+ size = dp->addrs[i].size;
+ if (size >= 0x800000) {
+ /* use the big-endian aperture (??) */
+ addr += 0x800000;
+ /* map at most 8MB for the frame buffer */
+ p->frame_buffer_phys = addr;
+ p->frame_buffer = __ioremap(addr, 0x800000, _PAGE_WRITETHRU);
+ } else {
+ p->control_regs_phys = addr;
+ p->control_regs = ioremap(addr, size);
+ }
+ }
+ p->cmap_regs_phys = 0xf301b000; /* XXX not in prom? */
+ p->cmap_regs = ioremap(p->cmap_regs_phys, 0x1000);
+
+ /* Work out which banks of VRAM we have installed. */
+ /* danj: I guess the card just ignores writes to nonexistant VRAM... */
+ p->frame_buffer[0] = 0x5a;
+ p->frame_buffer[1] = 0xc7;
+ bank1 = p->frame_buffer[0] == 0x5a && p->frame_buffer[1] == 0xc7;
+ p->frame_buffer[0x600000] = 0xa5;
+ p->frame_buffer[0x600001] = 0x38;
+ bank2 = p->frame_buffer[0x600000] == 0xa5 && p->frame_buffer[0x600001] == 0x38;
+ 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)
+ p->frame_buffer += 0x600000;
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+#if 0
+ console_set_cmap_ptr = control_set_cmap;
+ console_setmode_ptr = control_console_setmode;
+#endif
+#endif /* CONFIG_FB_COMPAT_XPMAC */
+
+ init_control(p);
+}
+
+/*
+ * Get the monitor sense value.
+ * Note that this can be called before calibrate_delay,
+ * so we can't use udelay.
+ *
+ * Hmm - looking at platinum, should we be calling eieio() here?
+ */
+static int read_control_sense(struct fb_info_control *p)
+{
+ int sense;
+
+ out_le32(&p->control_regs->mon_sense.r, 7); /* drive all lines high */
+ __delay(200);
+ out_le32(&p->control_regs->mon_sense.r, 077); /* turn off drivers */
+ __delay(2000);
+ sense = (in_le32(&p->control_regs->mon_sense.r) & 0x1c0) << 2;
+
+ /* drive each sense line low in turn and collect the other 2 */
+ out_le32(&p->control_regs->mon_sense.r, 033); /* drive A low */
+ __delay(2000);
+ sense |= (in_le32(&p->control_regs->mon_sense.r) & 0xc0) >> 2;
+ out_le32(&p->control_regs->mon_sense.r, 055); /* drive B low */
+ __delay(2000);
+ sense |= ((in_le32(&p->control_regs->mon_sense.r) & 0x100) >> 5)
+ | ((in_le32(&p->control_regs->mon_sense.r) & 0x40) >> 4);
+ out_le32(&p->control_regs->mon_sense.r, 066); /* drive C low */
+ __delay(2000);
+ sense |= (in_le32(&p->control_regs->mon_sense.r) & 0x180) >> 7;
+
+ out_le32(&p->control_regs->mon_sense.r, 077); /* turn off drivers */
+
+ return sense;
+}
+
+#if 1
+/* This routine takes a user-supplied var, and picks the best vmode/cmode from it. */
+static int control_var_to_par(struct fb_var_screeninfo *var,
+ struct fb_par_control *par, const struct fb_info *fb_info)
+{
+ int xres = var->xres;
+ int yres = var->yres;
+ int bpp = var->bits_per_pixel;
+
+ struct control_regvals *init;
+ struct fb_info_control *p = (struct fb_info_control *) fb_info;
+
+ /*
+ * Get the video params out of 'var'. If a value doesn't fit, round it up,
+ * if it's too big, return -EINVAL.
+ *
+ * Suggestion: Round up in the following order: bits_per_pixel, xres,
+ * yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
+ * bitfields, horizontal timing, vertical timing.
+ */
+ /* swiped by jonh from atyfb.c */
+ if (xres <= 512 && yres <= 384)
+ par->vmode = VMODE_512_384_60; /* 512x384, 60Hz */
+ else if (xres <= 640 && yres <= 480)
+ par->vmode = VMODE_640_480_67; /* 640x480, 67Hz */
+ else if (xres <= 640 && yres <= 870)
+ par->vmode = VMODE_640_870_75P; /* 640x870, 75Hz (portrait) */
+ else if (xres <= 768 && yres <= 576)
+ par->vmode = VMODE_768_576_50I; /* 768x576, 50Hz (PAL full frame) */
+ else if (xres <= 800 && yres <= 600)
+ par->vmode = VMODE_800_600_75; /* 800x600, 75Hz */
+ else if (xres <= 832 && yres <= 624)
+ par->vmode = VMODE_832_624_75; /* 832x624, 75Hz */
+ else if (xres <= 1024 && yres <= 768)
+ par->vmode = VMODE_1024_768_75; /* 1024x768, 75Hz */
+ else if (xres <= 1152 && yres <= 870)
+ par->vmode = VMODE_1152_870_75; /* 1152x870, 75Hz */
+ else if (xres <= 1280 && yres <= 960)
+ par->vmode = VMODE_1280_960_75; /* 1280x960, 75Hz */
+ else if (xres <= 1280 && yres <= 1024)
+ par->vmode = VMODE_1280_1024_75; /* 1280x1024, 75Hz */
+ else
+ return -EINVAL;
+
+ xres = control_reg_init[par->vmode-1]->hres;
+ yres = control_reg_init[par->vmode-1]->vres;
+
+/*
+ if (var->xres_virtual <= xres)
+ par->vxres = xres;
+ else
+ par->vxres = (var->xres_virtual+7) & ~7;
+ if (var->yres_virtual <= yres)
+ par->vyres = yres;
+ else
+ par->vyres = var->yres_virtual;
+
+ par->xoffset = (var->xoffset+7) & ~7;
+ par->yoffset = var->yoffset;
+ if (par->xoffset+xres > par->vxres || par->yoffset+yres > par->vyres)
+ return -EINVAL;
+*/
+
+ /* I'm too chicken to think about virtual */
+ /* resolutions just yet. Bok bok. */
+
+ /* And I'm too chicken to even figure out what they are. Awk awk. [danj] */
+ if (var->xres_virtual > xres || var->yres_virtual > yres
+ || var->xoffset != 0 || var->yoffset != 0) {
+ return -EINVAL;
+ }
+
+ par->xres = xres;
+ par->yres = yres;
+ par->vxres = xres;
+ par->vyres = yres;
+ par->xoffset = 0;
+ par->yoffset = 0;
+
+ if (bpp <= 8)
+ par->cmode = CMODE_8;
+ else if (bpp <= 16)
+ par->cmode = CMODE_16;
+ else if (bpp <= 32)
+ par->cmode = CMODE_32;
+ else
+ return -EINVAL;
+
+ if (control_vram_reqd(par->vmode, par->cmode) > p->total_vram)
+ return -EINVAL;
+
+ /* Check if we know about the wanted video mode */
+ init = control_reg_init[par->vmode-1];
+ if (init == NULL) {
+ /* I'm not sure if control has any specific requirements -- */
+ /* if we have a regvals struct, we're good to go? */
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#else
+/* This routine takes a user-supplied var, and picks the best vmode/cmode from it. */
+static int control_var_to_par(struct fb_var_screeninfo *var,
+ struct fb_par_control *par, const struct fb_info *fb_info)
+{
+ struct fb_info_control *p = (struct fb_info_control *) fb_info;
+
+ if(mac_var_to_vmode(var, &par->vmode, &par->cmode) != 0)
+ return -EINVAL;
+ par->xres = par->vxres = vmode_attrs[par->vmode - 1].hres;
+ par->yres = par->vyres = vmode_attrs[par->vmode - 1].vres;
+ par->xoffset = par->yoffset = 0;
+
+ if (control_vram_reqd(par->vmode, par->cmode) > p->total_vram)
+ return -EINVAL;
+
+ /* Check if we know about the wanted video mode */
+ if(!control_reg_init[par->vmode-1]) {
+ /* I'm not sure if control has any specific requirements -- */
+ /* if we have a regvals struct, we're good to go? */
+ return -EINVAL;
+ }
+ return 0;
+}
+#endif
+
+#if 1
+static void control_par_to_var(struct fb_par_control *par, struct fb_var_screeninfo *var)
+{
+ memset(var, 0, sizeof(*var));
+ var->xres = control_reg_init[par->vmode - 1]->hres;
+ var->yres = control_reg_init[par->vmode - 1]->vres;
+ var->xres_virtual = var->xres;
+ var->yres_virtual = var->yres; /* For now. */
+ var->xoffset = par->xoffset;
+ var->yoffset = par->yoffset;
+ var->grayscale = 0;
+
+ if(par->cmode != CMODE_8 && par->cmode != CMODE_16 && par->cmode != CMODE_32) {
+ printk(KERN_ERR "Bad color mode in control_par_to_var()!\n");
+ par->cmode = CMODE_8;
+ }
+ switch(par->cmode) {
+ case CMODE_8:
+ var->bits_per_pixel = 8;
+ var->red.offset = 0;
+ var->red.length = 8;
+ var->green.offset = 0;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ break;
+ case CMODE_16: /* RGB 555 */
+ var->bits_per_pixel = 16;
+ var->red.offset = 10;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 5;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ break;
+ case CMODE_32: /* RGB 888 */
+ var->bits_per_pixel = 32;
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->transp.offset = 24;
+ var->transp.length = 8;
+ break;
+ }
+ var->red.msb_right = 0;
+ var->green.msb_right = 0;
+ var->blue.msb_right = 0;
+ var->transp.msb_right = 0;
+ var->nonstd = 0;
+ var->activate = 0;
+ var->height = -1;
+ var->width = -1;
+ var->vmode = FB_VMODE_NONINTERLACED;
+
+ /* these are total guesses, copied right out of atyfb.c */
+ var->left_margin = var->right_margin = 64;
+ var->upper_margin = var->lower_margin = 32;
+ var->hsync_len = /*64*/8;
+ var->vsync_len = /*2*/8;
+ var->sync = 0;
+
+#if 0
+/* jonh's pixclocks...*/
+ /* no long long support in the kernel :-( */
+ /* this splittig trick will work if xres > 232 */
+ var->pixclock = 1000000000/
+ (var->left_margin+var->xres+var->right_margin+var->hsync_len);
+ var->pixclock *= 1000;
+ var->pixclock /= vmode_attrs[par->vmode-1].vfreq*
+ (var->upper_margin+var->yres+var->lower_margin+var->vsync_len);
+#else
+/* danj's */
+ /* 10^12 * clock_params[0] / (3906400 * clock_params[1] * 2^clock_params[2]) */
+ /* (10^12 * clock_params[0] / (3906400 * clock_params[1])) >> clock_params[2] */
+ /* (255990.17 * clock_params[0] / clock_params[1]) >> clock_params[2] */
+ var->pixclock = 255990 * control_reg_init[par->vmode-1]->clock_params[0];
+ var->pixclock /= control_reg_init[par->vmode-1]->clock_params[1];
+ var->pixclock >>= control_reg_init[par->vmode-1]->clock_params[2];
+#endif
+}
+#else
+static inline void control_par_to_var(struct fb_par_control *par, struct fb_var_screeninfo *var)
+{
+ mac_vmode_to_var(par->vmode, par->cmode, var);
+}
+#endif
+
+static void control_init_fix(struct fb_fix_screeninfo *fix, struct fb_info_control *p)
+{
+ memset(fix, 0, sizeof(*fix));
+ strcpy(fix->id, "control");
+ fix->mmio_start = (char *)p->control_regs_phys;
+ fix->mmio_len = sizeof(struct control_regs);
+ fix->type = FB_TYPE_PACKED_PIXELS;
+
+ /*
+ fix->type_aux = 0;
+ fix->ywrapstep = 0;
+ fix->ypanstep = 0;
+ fix->xpanstep = 0;
+ */
+}
+
+/* Fix must already be inited ^^^^^^^ */
+static void control_par_to_fix(struct fb_par_control *par, struct fb_fix_screeninfo *fix,
+ struct fb_info_control *p)
+{
+ fix->smem_start = (void *)(p->frame_buffer_phys
+ + control_reg_init[par->vmode-1]->offset[par->cmode]);
+ p->fix.smem_len = control_vram_reqd(par->vmode, par->cmode);
+ /* Hmm, jonh used total_vram here. */
+ p->fix.visual = (par->cmode == CMODE_8) ?
+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
+ p->fix.line_length = par->vxres << par->cmode;
+ /* ywrapstep, xpanstep, ypanstep */
+}
+
+static void control_init_display(struct display *disp)
+{
+ memset(disp, 0, sizeof(*disp));
+ disp->type = /* fix->type */ FB_TYPE_PACKED_PIXELS;
+ disp->can_soft_blank = 1;
+ disp->scrollmode = SCROLL_YREDRAW;
+#if 0
+ disp->type_aux = fix->type_aux;
+ disp->cmap.red = NULL; /* ??? danj */
+ disp->cmap.green = NULL;
+ disp->cmap.blue = NULL;
+ disp->cmap.transp = NULL;
+ /* Yeah, I realize I just set 0 = 0. */
+#endif
+}
+
+static void control_par_to_display(struct fb_par_control *par,
+ struct display *disp, struct fb_fix_screeninfo *fix, struct fb_info_control *p)
+{
+ disp->var = p->var;
+ disp->screen_base = (char *) p->frame_buffer
+ + control_reg_init[par->vmode-1]->offset[par->cmode];
+ disp->visual = fix->visual;
+ disp->line_length = fix->line_length;
+
+if(disp->scrollmode != SCROLL_YREDRAW) {
+ printk(KERN_ERR "Scroll mode not YREDRAW in control_par_to_display!!\n");
+ disp->scrollmode = SCROLL_YREDRAW;
+}
+ disp->dispsw = (par->cmode == CMODE_32) ? &fbcon_cfb32 :
+ ((par->cmode == CMODE_16) ? &fbcon_cfb16 : &fbcon_cfb8);
+}
+
+static void control_init_info(struct fb_info *info, struct fb_info_control *p)
+{
+ strcpy(info->modename, p->fix.id);
+ info->node = -1; /* ??? danj */
+ info->fbops = &controlfb_ops;
+ info->disp = &p->disp;
+ info->fontname[0] = 0;
+ info->changevar = NULL;
+ info->switch_con = &controlfb_switch;
+ info->updatevar = &controlfb_updatevar;
+ info->blank = &controlfb_blank;
+}
+
+/* danj: Oh, I HOPE I didn't miss anything major in here... */
+static void control_par_to_all(struct fb_info_control *p, int init)
+{
+ if(init) {
+ control_init_fix(&p->fix, p);
+ }
+ control_par_to_fix(&p->par, &p->fix, p);
+
+ control_par_to_var(&p->par, &p->var);
+
+ if(init) {
+ control_init_display(&p->disp);
+ }
+ control_par_to_display(&p->par, &p->disp, &p->fix, p);
+
+ if(init) {
+ control_init_info(&p->info, p);
+ }
+}
+
+#if 0
+__initfunc(void controlfb_setup(char *options, int *ints))
+{
+ /* Parse user speficied options (`video=controlfb:') */
+ FUNCID;
+}
+
+static int controlfb_pan_display(struct fb_var_screeninfo *var,
+ struct controlfb_par *par,
+ const struct fb_info *fb_info)
+{
+ /*
+ * Pan (or wrap, depending on the `vmode' field) the display using the
+ * `xoffset' and `yoffset' fields of the `var' structure.
+ * If the values don't fit, return -EINVAL.
+ */
+
+ FUNCID;
+
+ return 0;
+}
+
+#endif
diff --git a/drivers/video/controlfb.h b/drivers/video/controlfb.h
new file mode 100644
index 000000000..2e138b7c7
--- /dev/null
+++ b/drivers/video/controlfb.h
@@ -0,0 +1,262 @@
+/*
+ * controlfb_hw.h: Constants of all sorts for controlfb
+ *
+ * Copyright (C) 1998 Daniel Jacobowitz <dan@debian.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Based on an awful lot of code, including:
+ *
+ * control.c: Console support for PowerMac "control" display adaptor.
+ * Copyright (C) 1996 Paul Mackerras.
+ *
+ * The so far unpublished platinumfb.c
+ * Copyright (C) 1998 Jon Howell
+ */
+
+/*
+ * Structure of the registers for the RADACAL colormap device.
+ */
+struct cmap_regs {
+ unsigned char addr;
+ char pad1[15];
+ unsigned char d1;
+ char pad2[15];
+ unsigned char d2;
+ char pad3[15];
+ unsigned char lut;
+ char pad4[15];
+};
+
+/*
+ * Structure of the registers for the "control" display adaptor.
+ */
+#define PAD(x) char x[12]
+
+struct preg { /* padded register */
+ unsigned r;
+ char pad[12];
+};
+
+struct control_regs {
+ struct preg vcount; /* vertical counter */
+ /* Vertical parameters are in units of 1/2 scan line */
+ struct preg vswin; /* between vsblank and vssync */
+ struct preg vsblank; /* vert start blank */
+ struct preg veblank; /* vert end blank (display start) */
+ struct preg vewin; /* between vesync and veblank */
+ struct preg vesync; /* vert end sync */
+ struct preg vssync; /* vert start sync */
+ struct preg vperiod; /* vert period */
+ struct preg reg8;
+ /* Horizontal params are in units of 2 pixels */
+ struct preg hperiod; /* horiz period - 2 */
+ struct preg hsblank; /* horiz start blank */
+ struct preg heblank; /* horiz end blank */
+ struct preg hesync; /* horiz end sync */
+ struct preg hssync; /* horiz start sync */
+ struct preg rege;
+ struct preg regf;
+ struct preg reg10;
+ struct preg reg11;
+ struct preg ctrl; /* display control */
+ struct preg start_addr; /* start address: 5 lsbs zero */
+ struct preg pitch; /* addrs diff between scan lines */
+ struct preg mon_sense; /* monitor sense bits */
+ struct preg flags;
+ struct preg mode;
+ struct preg reg18;
+ struct preg reg19;
+ struct preg res[6];
+};
+
+/*
+ * Register initialization tables for the control display.
+ *
+ * Dot clock rate is
+ * 3.9064MHz * 2**clock_params[2] * clock_params[1] / clock_params[0].
+ *
+ * The values for vertical frequency (V) in the comments below
+ * are the values measured using the modes under MacOS.
+ */
+struct control_regvals {
+ int pitch[3]; /* bytes/line, indexed by color_mode */
+ int offset[3]; /* first pixel address */
+ unsigned regs[16]; /* for vswin .. reg10 */
+ unsigned char mode[3]; /* indexed by color_mode */
+ unsigned char radacal_ctrl[3];
+ unsigned char clock_params[3];
+ int hres;
+ int vres;
+};
+
+/* Register values for 1280x1024, 75Hz mode (20) */
+static struct control_regvals control_reg_init_20 = {
+ { 1280, 2560, 0 },
+ { 0x10, 0x20, 0 },
+ { 2129, 2128, 80, 42, 4, 2130, 2132, 88,
+ 420, 411, 91, 35, 421, 18, 211, 386, },
+ { 1, 1, 1},
+ { 0x50, 0x64, 0x64 },
+ { 13, 56, 3 }, /* pixel clock = 134.61MHz for V=74.81Hz */
+ 1280, 1024
+};
+
+/* Register values for 1280x960, 75Hz mode (19) */
+static struct control_regvals control_reg_init_19 = {
+ { 1280, 2560, 0 },
+ { 0x10, 0x20, 0 },
+ { 1997, 1996, 76, 40, 4, 1998, 2000, 86,
+ 418, 409, 89, 35, 419, 18, 210, 384, },
+ { 1, 1, 1 },
+ { 0x50, 0x64, 0x64 },
+ { 31, 125, 3 }, /* pixel clock = 126.01MHz for V=75.01 Hz */
+ 1280, 960
+};
+
+/* Register values for 1152x870, 75Hz mode (18) */
+static struct control_regvals control_reg_init_18 = {
+ { 1152, 2304, 4608 },
+ { 0x10, 0x28, 0x50 },
+ { 1825, 1822, 82, 43, 4, 1828, 1830, 120,
+ 726, 705, 129, 63, 727, 32, 364, 664 },
+ { 2, 1, 1 },
+ { 0x10, 0x14, 0x28 },
+ { 19, 61, 3 }, /* pixel clock = 100.33MHz for V=75.31Hz */
+ 1152, 870
+};
+
+/* Register values for 1024x768, 75Hz mode (17) */
+static struct control_regvals control_reg_init_17 = {
+ { 1024, 2048, 4096 },
+ { 0x10, 0x28, 0x50 },
+ { 1603, 1600, 64, 34, 4, 1606, 1608, 120,
+ 662, 641, 129, 47, 663, 24, 332, 616 },
+ { 2, 1, 1 },
+ { 0x10, 0x14, 0x28 },
+ { 11, 28, 3 }, /* pixel clock = 79.55MHz for V=74.50Hz */
+ 1024, 768
+};
+
+/* Register values for 1024x768, 72Hz mode (15) */
+static struct control_regvals control_reg_init_15 = {
+ { 1024, 2048, 4096 },
+ { 0x10, 0x28, 0x50 },
+ { 1607, 1604, 68, 39, 10, 1610, 1612, 132,
+ 670, 653, 141, 67, 671, 34, 336, 604, },
+ { 2, 1, 1 },
+ { 0x10, 0x14, 0x28 },
+ { 12, 30, 3 }, /* pixel clock = 78.12MHz for V=72.12Hz */
+ 1024, 768
+};
+
+/* Register values for 1024x768, 60Hz mode (14) */
+static struct control_regvals control_reg_init_14 = {
+ { 1024, 2048, 4096 },
+ { 0x10, 0x28, 0x50 },
+ { 1607, 1604, 68, 39, 10, 1610, 1612, 132,
+ 670, 653, 141, 67, 671, 34, 336, 604, },
+ { 2, 1, 1 },
+ { 0x10, 0x14, 0x28 },
+ { 15, 31, 3 }, /* pixel clock = 64.58MHz for V=59.62Hz */
+ 1024, 768
+};
+
+/* Register values for 832x624, 75Hz mode (13) */
+static struct control_regvals control_reg_init_13 = {
+ { 832, 1664, 3328 },
+ { 0x10, 0x28, 0x50 },
+ { 1331, 1330, 82, 43, 4, 1332, 1334, 128,
+ 574, 553, 137, 31, 575, 16, 288, 544 },
+ { 2, 1, 0 }, { 0x10, 0x14, 0x18 },
+ { 23, 42, 3 }, /* pixel clock = 57.07MHz for V=74.27Hz */
+ 832, 624
+};
+
+/* Register values for 800x600, 75Hz mode (12) */
+static struct control_regvals control_reg_init_12 = {
+ { 800, 1600, 3200 },
+ { 0x10, 0x28, 0x50 },
+ { 1247, 1246, 46, 25, 4, 1248, 1250, 104,
+ 526, 513, 113, 39, 527, 20, 264, 488, },
+ { 2, 1, 0 }, { 0x10, 0x14, 0x18 },
+ { 7, 11, 3 }, /* pixel clock = 49.11MHz for V=74.40Hz */
+ 800, 600
+};
+
+/* Register values for 800x600, 72Hz mode (11) */
+static struct control_regvals control_reg_init_11 = {
+ { 800, 1600, 3200 },
+ { 0x10, 0x28, 0x50 },
+ { 1293, 1256, 56, 33, 10, 1330, 1332, 76,
+ 518, 485, 85, 59, 519, 30, 260, 460, },
+ { 2, 1, 0 }, { 0x10, 0x14, 0x18 },
+ { 17, 27, 3 }, /* pixel clock = 49.63MHz for V=71.66Hz */
+ 800, 600
+};
+
+/* Register values for 800x600, 60Hz mode (10) */
+static struct control_regvals control_reg_init_10 = {
+ { 800, 1600, 3200 },
+ { 0x10, 0x28, 0x50 },
+ { 1293, 1256, 56, 33, 10, 1330, 1332, 76,
+ 518, 485, 85, 59, 519, 30, 260, 460, },
+ { 2, 1, 0 }, { 0x10, 0x14, 0x18 },
+ { 20, 53, 2 }, /* pixel clock = 41.41MHz for V=59.78Hz */
+ 800, 600
+};
+
+/* Register values for 640x870, 75Hz Full Page Display (7) */
+static struct control_regvals control_reg_init_7 = {
+ { 640, 1280, 2560 },
+ { 0x10, 0x30, 0x68 },
+ { 0x727, 0x724, 0x58, 0x2e, 0x4, 0x72a, 0x72c, 0x40,
+ 0x19e, 0x18c, 0x4c, 0x27, 0x19f, 0x14, 0xd0, 0x178 },
+ { 2, 1, 0 }, { 0x10, 0x14, 0x18 },
+ { 9, 33, 2 }, /* pixel clock = 57.29MHz for V=75.01Hz */
+ 640, 870
+};
+
+/* Register values for 640x480, 67Hz mode (6) */
+static struct control_regvals control_reg_init_6 = {
+ { 640, 1280, 2560 },
+ { 0, 8, 0x10 },
+ { 1045, 1042, 82, 43, 4, 1048, 1050, 72,
+ 430, 393, 73, 31, 431, 16, 216, 400 },
+ { 2, 1, 0 }, { 0x10, 0x14, 0x18 },
+ { 14, 27, 2 }, /* pixel clock = 30.13MHz for V=66.43Hz */
+ 640, 480
+};
+
+/* Register values for 640x480, 60Hz mode (5) */
+static struct control_regvals control_reg_init_5 = {
+ { 640, 1280, 2560 },
+ { 0x10, 0x28, 0x50 },
+ { 1037, 1026, 66, 34, 2, 1048, 1050, 56,
+ 398, 385, 65, 47, 399, 24, 200, 352, },
+ { 2, 1, 0 }, { 0x10, 0x14, 0x18 },
+ { 23, 37, 2 }, /* pixel clock = 25.14MHz for V=59.85Hz */
+ 640, 480
+};
+
+static struct control_regvals *control_reg_init[VMODE_MAX] = {
+ NULL, NULL, NULL, NULL,
+ &control_reg_init_5,
+ &control_reg_init_6,
+ &control_reg_init_7,
+ NULL, NULL,
+ &control_reg_init_10,
+ &control_reg_init_11,
+ &control_reg_init_12,
+ &control_reg_init_13,
+ &control_reg_init_14,
+ &control_reg_init_15,
+ NULL,
+ &control_reg_init_17,
+ &control_reg_init_18,
+ &control_reg_init_19,
+ &control_reg_init_20
+};
diff --git a/drivers/video/creatorfb.c b/drivers/video/creatorfb.c
new file mode 100644
index 000000000..2175c9e5d
--- /dev/null
+++ b/drivers/video/creatorfb.c
@@ -0,0 +1,537 @@
+/* $Id: creatorfb.c,v 1.10 1998/07/25 22:54:37 davem Exp $
+ * creatorfb.c: Creator/Creator3D frame buffer driver
+ *
+ * Copyright (C) 1997,1998 Jakub Jelinek (jj@ultra.linux.cz)
+ */
+
+#include <linux/config.h>
+#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 "sbusfb.h"
+
+#define FFB_SFB8R_VOFF 0x00000000
+#define FFB_SFB8G_VOFF 0x00400000
+#define FFB_SFB8B_VOFF 0x00800000
+#define FFB_SFB8X_VOFF 0x00c00000
+#define FFB_SFB32_VOFF 0x01000000
+#define FFB_SFB64_VOFF 0x02000000
+#define FFB_FBC_REGS_VOFF 0x04000000
+#define FFB_BM_FBC_REGS_VOFF 0x04002000
+#define FFB_DFB8R_VOFF 0x04004000
+#define FFB_DFB8G_VOFF 0x04404000
+#define FFB_DFB8B_VOFF 0x04804000
+#define FFB_DFB8X_VOFF 0x04c04000
+#define FFB_DFB24_VOFF 0x05004000
+#define FFB_DFB32_VOFF 0x06004000
+#define FFB_DFB422A_VOFF 0x07004000 /* DFB 422 mode write to A */
+#define FFB_DFB422AD_VOFF 0x07804000 /* DFB 422 mode with line doubling */
+#define FFB_DFB24B_VOFF 0x08004000 /* DFB 24bit mode write to B */
+#define FFB_DFB422B_VOFF 0x09004000 /* DFB 422 mode write to B */
+#define FFB_DFB422BD_VOFF 0x09804000 /* DFB 422 mode with line doubling */
+#define FFB_SFB16Z_VOFF 0x0a004000 /* 16bit mode Z planes */
+#define FFB_SFB8Z_VOFF 0x0a404000 /* 8bit mode Z planes */
+#define FFB_SFB422_VOFF 0x0ac04000 /* SFB 422 mode write to A/B */
+#define FFB_SFB422D_VOFF 0x0b404000 /* SFB 422 mode with line doubling */
+#define FFB_FBC_KREGS_VOFF 0x0bc04000
+#define FFB_DAC_VOFF 0x0bc06000
+#define FFB_PROM_VOFF 0x0bc08000
+#define FFB_EXP_VOFF 0x0bc18000
+
+#define FFB_SFB8R_POFF 0x04000000
+#define FFB_SFB8G_POFF 0x04400000
+#define FFB_SFB8B_POFF 0x04800000
+#define FFB_SFB8X_POFF 0x04c00000
+#define FFB_SFB32_POFF 0x05000000
+#define FFB_SFB64_POFF 0x06000000
+#define FFB_FBC_REGS_POFF 0x00600000
+#define FFB_BM_FBC_REGS_POFF 0x00600000
+#define FFB_DFB8R_POFF 0x01000000
+#define FFB_DFB8G_POFF 0x01400000
+#define FFB_DFB8B_POFF 0x01800000
+#define FFB_DFB8X_POFF 0x01c00000
+#define FFB_DFB24_POFF 0x02000000
+#define FFB_DFB32_POFF 0x03000000
+#define FFB_FBC_KREGS_POFF 0x00610000
+#define FFB_DAC_POFF 0x00400000
+#define FFB_PROM_POFF 0x00000000
+#define FFB_EXP_POFF 0x00200000
+
+#define FFB_Y_BYTE_ADDR_SHIFT 11
+#define FFB_Y_ADDR_SHIFT 13
+
+#define FFB_PPC_ACE_DISABLE 1
+#define FFB_PPC_ACE_AUX_ADD 3
+#define FFB_PPC_ACE_SHIFT 18
+#define FFB_PPC_DCE_DISABLE 2
+#define FFB_PPC_DCE_SHIFT 16
+#define FFB_PPC_ABE_DISABLE 2
+#define FFB_PPC_ABE_SHIFT 14
+#define FFB_PPC_VCE_DISABLE 1
+#define FFB_PPC_VCE_2D 2
+#define FFB_PPC_VCE_SHIFT 12
+#define FFB_PPC_APE_DISABLE 2
+#define FFB_PPC_APE_SHIFT 10
+#define FFB_PPC_CS_VARIABLE 2
+#define FFB_PPC_CS_SHIFT 0
+
+#define FFB_FBC_WB_A 1
+#define FFB_FBC_WB_SHIFT 29
+#define FFB_FBC_PGE_MASK 3
+#define FFB_FBC_BE_SHIFT 4
+#define FFB_FBC_GE_SHIFT 2
+#define FFB_FBC_RE_SHIFT 0
+
+#define FFB_ROP_NEW 0x83
+#define FFB_ROP_RGB_SHIFT 0
+
+#define FFB_UCSR_FIFO_MASK 0x00000fff
+#define FFB_UCSR_RP_BUSY 0x02000000
+
+struct ffb_fbc {
+ u8 xxx1[0x60];
+ volatile u32 by;
+ volatile u32 bx;
+ u32 xxx2;
+ u32 xxx3;
+ volatile u32 bh;
+ volatile u32 bw;
+ u8 xxx4[0x188];
+ volatile u32 ppc;
+ u32 xxx5;
+ volatile u32 fg;
+ volatile u32 bg;
+ u8 xxx6[0x44];
+ volatile u32 fbc;
+ volatile u32 rop;
+ u8 xxx7[0x34];
+ volatile u32 pmask;
+ u8 xxx8[12];
+ volatile u32 clip0min;
+ volatile u32 clip0max;
+ volatile u32 clip1min;
+ volatile u32 clip1max;
+ volatile u32 clip2min;
+ volatile u32 clip2max;
+ volatile u32 clip3min;
+ volatile u32 clip3max;
+ u8 xxx9[0x3c];
+ volatile u32 unk1;
+ volatile u32 unk2;
+ u8 xxx10[0x10];
+ volatile u32 fontxy;
+ volatile u32 fontw;
+ volatile u32 fontinc;
+ volatile u32 font;
+ u8 xxx11[0x4dc];
+ volatile u32 unk3;
+ u8 xxx12[0xfc];
+ volatile u32 ucsr;
+};
+
+struct ffb_dac {
+ volatile u32 type;
+ volatile u32 value;
+ volatile u32 type2;
+ volatile u32 value2;
+};
+
+static struct sbus_mmap_map ffb_mmap_map[] = {
+ { FFB_SFB8R_VOFF, FFB_SFB8R_POFF, 0x0400000 },
+ { FFB_SFB8G_VOFF, FFB_SFB8G_POFF, 0x0400000 },
+ { FFB_SFB8B_VOFF, FFB_SFB8B_POFF, 0x0400000 },
+ { FFB_SFB8X_VOFF, FFB_SFB8X_POFF, 0x0400000 },
+ { FFB_SFB32_VOFF, FFB_SFB32_POFF, 0x1000000 },
+ { FFB_SFB64_VOFF, FFB_SFB64_POFF, 0x2000000 },
+ { FFB_FBC_REGS_VOFF, FFB_FBC_REGS_POFF, 0x0002000 },
+ { FFB_BM_FBC_REGS_VOFF, FFB_BM_FBC_REGS_POFF, 0x0002000 },
+ { FFB_DFB8R_VOFF, FFB_DFB8R_POFF, 0x0400000 },
+ { FFB_DFB8G_VOFF, FFB_DFB8G_POFF, 0x0400000 },
+ { FFB_DFB8B_VOFF, FFB_DFB8B_POFF, 0x0400000 },
+ { FFB_DFB8X_VOFF, FFB_DFB8X_POFF, 0x0400000 },
+ { FFB_DFB24_VOFF, FFB_DFB24_POFF, 0x1000000 },
+ { FFB_DFB32_VOFF, FFB_DFB32_POFF, 0x1000000 },
+ { FFB_FBC_KREGS_VOFF, FFB_FBC_KREGS_POFF, 0x0002000 },
+ { FFB_DAC_VOFF, FFB_DAC_POFF, 0x0002000 },
+ { FFB_PROM_VOFF, FFB_PROM_POFF, 0x0010000 },
+ { FFB_EXP_VOFF, FFB_EXP_POFF, 0x0002000 },
+ { 0, 0, 0 }
+};
+
+static u32 ffb_cmap[16];
+
+static void ffb_setup(struct display *p)
+{
+ p->next_line = 8192;
+ p->next_plane = 0;
+}
+
+static void ffb_clear(struct vc_data *conp, struct display *p, int sy, int sx,
+ int height, int width)
+{
+ struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;
+ register struct ffb_fbc *fbc = fb->s.ffb.fbc;
+ int x, y, w, h;
+
+ fbc->ppc = 0x1803;
+ fbc->fg = ffb_cmap[attr_bgcol_ec(p,conp)];
+ fbc->fbc = 0x2000707f;
+ fbc->rop = 0x83;
+ fbc->pmask = 0xffffffff;
+ fbc->unk2 = 8;
+
+ if (p->fontheightlog) {
+ y = sy << p->fontheightlog; h = height << p->fontheightlog;
+ } else {
+ y = sy * p->fontheight; h = height * p->fontheight;
+ }
+ if (p->fontwidthlog) {
+ x = sx << p->fontwidthlog; w = width << p->fontwidthlog;
+ } else {
+ x = sx * p->fontwidth; w = width * p->fontwidth;
+ }
+ fbc->by = y + fb->y_margin;
+ fbc->bx = x + fb->x_margin;
+ fbc->bh = h;
+ fbc->bw = w;
+}
+
+static void ffb_fill(struct fb_info_sbusfb *fb, struct display *p, int s,
+ int count, unsigned short *boxes)
+{
+ register struct ffb_fbc *fbc = fb->s.ffb.fbc;
+
+ fbc->ppc = 0x1803;
+ fbc->fg = ffb_cmap[attr_bgcol(p,s)];
+ fbc->fbc = 0x2000707f;
+ fbc->rop = 0x83;
+ fbc->pmask = 0xffffffff;
+ fbc->unk2 = 8;
+ while (count-- > 0) {
+ fbc->by = boxes[1];
+ fbc->bx = boxes[0];
+ fbc->bh = boxes[3] - boxes[1];
+ fbc->bw = boxes[2] - boxes[0];
+ boxes += 4;
+ }
+}
+
+static void ffb_putc(struct vc_data *conp, struct display *p, int c, int yy, int xx)
+{
+ struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;
+ register struct ffb_fbc *fbc = fb->s.ffb.fbc;
+ int i, xy;
+ u8 *fd;
+
+ if (p->fontheightlog) {
+ xy = (yy << (16 + p->fontheightlog));
+ i = ((c & p->charmask) << p->fontheightlog);
+ } else {
+ xy = ((yy * p->fontheight) << 16);
+ i = (c & p->charmask) * p->fontheight;
+ }
+#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
+ fd = p->fontdata + i;
+ xy += (xx * 8) + fb->s.ffb.xy_margin;
+#else
+ if (p->fontwidth <= 8)
+ fd = p->fontdata + i;
+ else
+ fd = p->fontdata + (i << 1);
+ if (p->fontwidthlog)
+ xy += (xx << p->fontwidthlog) + fb->s.ffb.xy_margin;
+ else
+ xy += (xx * p->fontwidth) + fb->s.ffb.xy_margin;
+#endif
+ fbc->ppc = 0x203;
+ fbc->fg = ffb_cmap[attr_fgcol(p,c)];
+ fbc->fbc = 0x2000707f;
+ fbc->rop = 0x83;
+ fbc->pmask = 0xffffffff;
+ fbc->bg = ffb_cmap[attr_bgcol(p,c)];
+ fbc->fontw = p->fontwidth;
+ fbc->fontinc = 0x10000;
+ fbc->fontxy = xy;
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (p->fontwidth <= 8) {
+#endif
+ for (i = 0; i < p->fontheight; i++)
+ fbc->font = *fd++ << 24;
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ } else {
+ for (i = 0; i < p->fontheight; i++) {
+ fbc->font = *(u16 *)fd << 16;
+ fd += 2;
+ }
+ }
+#endif
+}
+
+static void ffb_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
+ int count, int yy, int xx)
+{
+ struct fb_info_sbusfb *fb = (struct fb_info_sbusfb *)p->fb_info;
+ register struct ffb_fbc *fbc = fb->s.ffb.fbc;
+ int i, xy;
+ u8 *fd1, *fd2, *fd3, *fd4;
+
+ fbc->ppc = 0x203;
+ fbc->fg = ffb_cmap[attr_fgcol(p,*s)];
+ fbc->fbc = 0x2000707f;
+ fbc->rop = 0x83;
+ fbc->pmask = 0xffffffff;
+ fbc->bg = ffb_cmap[attr_bgcol(p,*s)];
+ xy = fb->s.ffb.xy_margin;
+#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
+ xy += xx * 8;
+#else
+ if (p->fontwidthlog)
+ xy += (xx << p->fontwidthlog);
+ else
+ xy += xx * p->fontwidth;
+#endif
+ if (p->fontheightlog)
+ xy += (yy << (16 + p->fontheightlog));
+ else
+ xy += ((yy * p->fontheight) << 16);
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (p->fontwidth <= 8) {
+#endif
+ while (count >= 4) {
+ count -= 4;
+ fbc->fontw = 4 * p->fontwidth;
+ fbc->fontinc = 0x10000;
+ fbc->fontxy = xy;
+ if (p->fontheightlog) {
+ fd1 = p->fontdata + ((*s++ & p->charmask) << p->fontheightlog);
+ fd2 = p->fontdata + ((*s++ & p->charmask) << p->fontheightlog);
+ fd3 = p->fontdata + ((*s++ & p->charmask) << p->fontheightlog);
+ fd4 = p->fontdata + ((*s++ & p->charmask) << p->fontheightlog);
+ } else {
+ fd1 = p->fontdata + ((*s++ & p->charmask) * p->fontheight);
+ fd2 = p->fontdata + ((*s++ & p->charmask) * p->fontheight);
+ fd3 = p->fontdata + ((*s++ & p->charmask) * p->fontheight);
+ fd4 = p->fontdata + ((*s++ & p->charmask) * p->fontheight);
+ }
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (p->fontwidth == 8) {
+#endif
+ for (i = 0; i < p->fontheight; i++)
+ fbc->font = ((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++)
+ << 8)) << 8)) << 8);
+ xy += 32;
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ } else {
+ for (i = 0; i < p->fontheight; i++)
+ fbc->font = (((u32)*fd4++) | ((((u32)*fd3++) | ((((u32)*fd2++) | (((u32)*fd1++)
+ << p->fontwidth)) << p->fontwidth)) << p->fontwidth)) << (24 - 3 * p->fontwidth);
+ xy += 4 * p->fontwidth;
+ }
+ }
+ } else {
+ while (count >= 2) {
+ count -= 2;
+ fbc->fontw = 2 * p->fontwidth;
+ fbc->fontinc = 0x10000;
+ fbc->fontxy = xy;
+ if (p->fontheightlog) {
+ fd1 = p->fontdata + ((*s++ & p->charmask) << (p->fontheightlog + 1));
+ fd2 = p->fontdata + ((*s++ & p->charmask) << (p->fontheightlog + 1));
+ } else {
+ fd1 = p->fontdata + (((*s++ & p->charmask) * p->fontheight) << 1);
+ fd2 = p->fontdata + (((*s++ & p->charmask) * p->fontheight) << 1);
+ }
+ for (i = 0; i < p->fontheight; i++) {
+ fbc->font = ((((u32)*(u16 *)fd1) << p->fontwidth) | ((u32)*(u16 *)fd2)) << (16 - p->fontwidth);
+ fd1 += 2; fd2 += 2;
+ }
+ xy += 2 * p->fontwidth;
+ }
+#endif
+ }
+ while (count) {
+ count--;
+ fbc->fontw = p->fontwidth;
+ fbc->fontinc = 0x10000;
+ fbc->fontxy = xy;
+ if (p->fontheightlog)
+ i = ((*s++ & p->charmask) << p->fontheightlog);
+ else
+ i = ((*s++ & p->charmask) * p->fontheight);
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (p->fontwidth <= 8) {
+#endif
+ fd1 = p->fontdata + i;
+ for (i = 0; i < p->fontheight; i++)
+ fbc->font = *fd1++ << 24;
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ } else {
+ fd1 = p->fontdata + (i << 1);
+ for (i = 0; i < p->fontheight; i++) {
+ fbc->font = *(u16 *)fd1 << 16;
+ fd1 += 2;
+ }
+ }
+#endif
+ xy += p->fontwidth;
+ }
+}
+
+static void ffb_revc(struct display *p, int xx, int yy)
+{
+ /* Not used if hw cursor */
+}
+
+static void ffb_loadcmap (struct fb_info_sbusfb *fb, int index, int count)
+{
+ struct ffb_dac *dac = fb->s.ffb.dac;
+ int i, j = count;
+
+ dac->type = 0x2000 | index;
+ for (i = index; j--; i++)
+ /* Feed the colors in :)) */
+ dac->value = ((fb->color_map CM(i,0))) |
+ ((fb->color_map CM(i,1)) << 8) |
+ ((fb->color_map CM(i,2)) << 16);
+ for (i = index, j = count; i < 16 && j--; i++)
+ ffb_cmap[i] = ((fb->color_map CM(i,0))) |
+ ((fb->color_map CM(i,1)) << 8) |
+ ((fb->color_map CM(i,2)) << 16);
+}
+
+static struct display_switch ffb_dispsw __initdata = {
+ ffb_setup, fbcon_redraw_bmove, ffb_clear, ffb_putc, ffb_putcs, ffb_revc,
+ NULL, NULL, NULL, FONTWIDTHRANGE(1,16) /* Allow fontwidths up to 16 */
+};
+
+static void ffb_margins (struct fb_info_sbusfb *fb, struct display *p, int x_margin, int y_margin)
+{
+ fb->s.ffb.xy_margin = (y_margin << 16) + x_margin;
+ p->screen_base += 8192 * (y_margin - fb->y_margin) + 4 * (x_margin - fb->x_margin);
+}
+
+static inline void ffb_curs_enable (struct fb_info_sbusfb *fb, int enable)
+{
+ struct ffb_dac *dac = fb->s.ffb.dac;
+
+ dac->type2 = 0x100;
+ if (fb->s.ffb.dac_rev <= 2)
+ dac->value2 = enable ? 3 : 0;
+ else
+ dac->value2 = enable ? 0 : 3;
+}
+
+static void ffb_setcursormap (struct fb_info_sbusfb *fb, u8 *red, u8 *green, u8 *blue)
+{
+ struct ffb_dac *dac = fb->s.ffb.dac;
+
+ ffb_curs_enable (fb, 0);
+ dac->type2 = 0x102;
+ dac->value2 = (red[0] | (green[0]<<8) | (blue[0]<<16));
+ dac->value2 = (red[1] | (green[1]<<8) | (blue[1]<<16));
+}
+
+/* Set cursor shape */
+static void ffb_setcurshape (struct fb_info_sbusfb *fb)
+{
+ struct ffb_dac *dac = fb->s.ffb.dac;
+ int i, j;
+
+ ffb_curs_enable (fb, 0);
+ for (j = 0; j < 2; j++) {
+ dac->type2 = j ? 0 : 0x80;
+ for (i = 0; i < 0x40; i++) {
+ if (fb->cursor.size.fbx <= 32) {
+ dac->value2 = fb->cursor.bits [j][i];
+ dac->value2 = 0;
+ } else {
+ dac->value2 = fb->cursor.bits [j][2*i];
+ dac->value2 = fb->cursor.bits [j][2*i+1];
+ }
+ }
+ }
+}
+
+/* Load cursor information */
+static void ffb_setcursor (struct fb_info_sbusfb *fb)
+{
+ struct ffb_dac *dac = fb->s.ffb.dac;
+ struct cg_cursor *c = &fb->cursor;
+
+ dac->type2 = 0x104;
+ /* Should this be just 0x7ff??
+ Should I do some margin handling and setcurshape in that case? */
+ dac->value2 = (((c->cpos.fby - c->chot.fby) & 0xffff) << 16)
+ |((c->cpos.fbx - c->chot.fbx) & 0xffff);
+ ffb_curs_enable (fb, fb->cursor.enable);
+}
+
+static char idstring[60] __initdata = { 0 };
+
+__initfunc(char *creatorfb_init(struct fb_info_sbusfb *fb))
+{
+ struct fb_fix_screeninfo *fix = &fb->fix;
+ struct fb_var_screeninfo *var = &fb->var;
+ struct display *disp = &fb->disp;
+ struct fbtype *type = &fb->type;
+ struct linux_prom64_registers regs[2*PROMREG_MAX];
+ int i;
+
+ if (prom_getproperty(fb->prom_node, "reg", (void *) regs, sizeof(regs)) <= 0)
+ return NULL;
+
+ strcpy(fb->info.modename, "Creator");
+
+ strcpy(fix->id, "Creator");
+ fix->visual = FB_VISUAL_DIRECTCOLOR;
+ fix->line_length = 8192;
+ fix->accel = FB_ACCEL_SUN_CREATOR;
+
+ var->bits_per_pixel = 32;
+ var->green.offset = 8;
+ var->blue.offset = 16;
+ var->accel_flags = FB_ACCELF_TEXT;
+
+ disp->scrollmode = SCROLL_YREDRAW;
+ disp->screen_base = (char *)__va(regs[0].phys_addr) + FFB_DFB24_POFF + 8192 * fb->y_margin + 4 * fb->x_margin;
+ fb->s.ffb.xy_margin = (fb->y_margin << 16) + fb->x_margin;
+ fb->s.ffb.fbc = (struct ffb_fbc *)((char *)__va(regs[0].phys_addr) + FFB_FBC_REGS_POFF);
+ fb->s.ffb.dac = (struct ffb_dac *)((char *)__va(regs[0].phys_addr) + FFB_DAC_POFF);
+ fb->dispsw = ffb_dispsw;
+
+ fb->margins = ffb_margins;
+ fb->loadcmap = ffb_loadcmap;
+ fb->setcursor = ffb_setcursor;
+ fb->setcursormap = ffb_setcursormap;
+ fb->setcurshape = ffb_setcurshape;
+ fb->fill = ffb_fill;
+
+ fb->physbase = regs[0].phys_addr;
+ fb->mmap_map = ffb_mmap_map;
+
+ fb->cursor.hwsize.fbx = 64;
+ fb->cursor.hwsize.fby = 64;
+
+ type->fb_depth = 24;
+
+ fb->s.ffb.dac->type = 0x8000;
+ fb->s.ffb.dac_rev = (fb->s.ffb.dac->value >> 0x1c);
+
+ i = prom_getintdefault (fb->prom_node, "board_type", 8);
+
+ sprintf(idstring, "Creator at %016lx type %d DAC %d", regs[0].phys_addr, i, fb->s.ffb.dac_rev);
+
+ return idstring;
+}
diff --git a/drivers/video/cyberfb.c b/drivers/video/cyberfb.c
index c0767a0f0..ebf72f0bd 100644
--- a/drivers/video/cyberfb.c
+++ b/drivers/video/cyberfb.c
@@ -20,7 +20,6 @@
* for more details.
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -61,6 +60,7 @@ struct cyberfb_par {
int xres;
int yres;
int bpp;
+ int accel;
};
static struct cyberfb_par current_par;
@@ -133,49 +133,49 @@ static struct fb_videomode cyberfb_predefined[] __initdata = {
"640x480-8", { /* Cybervision 8 bpp */
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, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}, {
"800x600-8", { /* Cybervision 8 bpp */
800, 600, 800, 600, 0, 0, 8, 0,
{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCEL_NONE, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}, {
"1024x768-8", { /* Cybervision 8 bpp */
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, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}, {
"1152x886-8", { /* Cybervision 8 bpp */
1152, 886, 1152, 886, 0, 0, 8, 0,
{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCEL_NONE, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}, {
"1280x1024-8", { /* Cybervision 8 bpp */
1280, 1024, 1280, 1024, 0, 0, 8, 0,
{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCEL_NONE, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}, {
"1600x1200-8", { /* Cybervision 8 bpp */
1600, 1200, 1600, 1200, 0, 0, 8, 0,
{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCEL_NONE, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, CYBER8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}, {
"800x600-16", { /* Cybervision 16 bpp */
800, 600, 800, 600, 0, 0, 16, 0,
{11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCEL_NONE, CYBER16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, CYBER16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}
@@ -207,8 +207,8 @@ static struct fb_var_screeninfo cyberfb_default;
void cyberfb_setup(char *options, int *ints);
-static int cyberfb_open(struct fb_info *info);
-static int cyberfb_release(struct fb_info *info);
+static int cyberfb_open(struct fb_info *info, int user);
+static int cyberfb_release(struct fb_info *info, int user);
static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con, struct
fb_info *info);
static int cyberfb_get_var(struct fb_var_screeninfo *var, int con, struct
@@ -229,7 +229,7 @@ static int cyberfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
* Interface to the low level console driver
*/
-unsigned long cyberfb_init(unsigned long mem_start);
+void 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);
@@ -239,7 +239,7 @@ static void Cyberfb_blank(int blank, struct fb_info *info);
* Text console acceleration
*/
-#ifdef CONFIG_FBCON_CFB8
+#ifdef FBCON_HAS_CFB8
static struct display_switch fbcon_cyber8;
#endif
@@ -371,12 +371,11 @@ static int Cyber_init(void)
static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
struct cyberfb_par *par)
{
- int i;
-
+ memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id, cyberfb_name);
- fix->smem_start = (caddr_t)CyberMem;
+ fix->smem_start = (char *)CyberMem;
fix->smem_len = CyberSize;
- fix->mmio_start = (unsigned char *)CyberRegs;
+ fix->mmio_start = (char *)CyberRegs;
fix->mmio_len = 0x10000;
fix->type = FB_TYPE_PACKED_PIXELS;
@@ -390,9 +389,7 @@ static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
fix->ypanstep = 0;
fix->ywrapstep = 0;
fix->line_length = 0;
-
- for (i = 0; i < arraysize(fix->reserved); i++)
- fix->reserved[i] = 0;
+ fix->accel = FB_ACCEL_S3_TRIO64;
return(0);
}
@@ -410,6 +407,10 @@ static int Cyber_decode_var(struct fb_var_screeninfo *var,
par->xres = var->xres;
par->yres = var->yres;
par->bpp = var->bits_per_pixel;
+ if (var->accel_flags & FB_ACCELF_TEXT)
+ par->accel = FB_ACCELF_TEXT;
+ else
+ par->accel = 0;
#else
if (Cyberfb_Cyber8) {
par->xres = CYBER8_WIDTH;
@@ -433,8 +434,6 @@ static int Cyber_decode_var(struct fb_var_screeninfo *var,
static int Cyber_encode_var(struct fb_var_screeninfo *var,
struct cyberfb_par *par)
{
- int i;
-
var->xres = par->xres;
var->yres = par->yres;
var->xres_virtual = par->xres;
@@ -471,8 +470,7 @@ static int Cyber_encode_var(struct fb_var_screeninfo *var,
var->height = -1;
var->width = -1;
- var->accel = FB_ACCEL_CYBERVISION;
- DPRINTK("accel CV64\n");
+ var->accel_flags = (par->accel && par->bpp == 8) ? FB_ACCELF_TEXT : 0;
var->vmode = FB_VMODE_NONINTERLACED;
@@ -490,9 +488,6 @@ static int Cyber_encode_var(struct fb_var_screeninfo *var,
var->hsync_len = 112;
var->vsync_len = 2;
- for (i = 0; i < arraysize(var->reserved); i++)
- var->reserved[i] = 0;
-
return(0);
}
@@ -774,7 +769,7 @@ static void do_install_cmap(int con, struct fb_info *info)
* Open/Release the frame buffer device
*/
-static int cyberfb_open(struct fb_info *info)
+static int cyberfb_open(struct fb_info *info, int user)
{
/*
* Nothing, only a usage count for the moment
@@ -784,7 +779,7 @@ static int cyberfb_open(struct fb_info *info)
return(0);
}
-static int cyberfb_release(struct fb_info *info)
+static int cyberfb_release(struct fb_info *info, int user)
{
MOD_DEC_USE_COUNT;
return(0);
@@ -847,7 +842,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 = (u_char *)fix.smem_start;
+ display->screen_base = fix.smem_start;
display->visual = fix.visual;
display->type = fix.type;
display->type_aux = fix.type_aux;
@@ -856,12 +851,16 @@ static void cyberfb_set_disp(int con, struct fb_info *info)
display->can_soft_blank = 1;
display->inverse = Cyberfb_inverse;
switch (display->var.bits_per_pixel) {
-#ifdef CONFIG_FBCON_CFB8
+#ifdef FBCON_HAS_CFB8
case 8:
- display->dispsw = &fbcon_cyber8;
+ if (display->var.accel_flags & FB_ACCELF_TEXT) {
+ display->dispsw = &fbcon_cyber8;
+#warning FIXME: We should reinit the graphics engine here
+ } else
+ display->dispsw = &fbcon_cfb8;
break;
#endif
-#ifdef CONFIG_FBCON_CFB16
+#ifdef FBCON_HAS_CFB16
case 16:
display->dispsw = &fbcon_cfb16;
break;
@@ -880,7 +879,7 @@ static void cyberfb_set_disp(int con, struct fb_info *info)
static int cyberfb_set_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
- int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp;
+ int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel;
if ((err = do_fb_set_var(var, con == currcon)))
return(err);
@@ -890,11 +889,13 @@ static int cyberfb_set_var(struct fb_var_screeninfo *var, int con,
oldvxres = fb_display[con].var.xres_virtual;
oldvyres = fb_display[con].var.yres_virtual;
oldbpp = fb_display[con].var.bits_per_pixel;
+ oldaccel = fb_display[con].var.accel_flags;
fb_display[con].var = *var;
if (oldxres != var->xres || oldyres != var->yres ||
oldvxres != var->xres_virtual ||
oldvyres != var->yres_virtual ||
- oldbpp != var->bits_per_pixel) {
+ oldbpp != var->bits_per_pixel ||
+ oldaccel != var->accel_flags) {
cyberfb_set_disp(con, info);
(*fb_info.changevar)(con);
fb_alloc_cmap(&fb_display[con].cmap, 0, 0);
@@ -975,7 +976,7 @@ static int cyberfb_ioctl(struct inode *inode, struct file *file,
static struct fb_ops cyberfb_ops = {
cyberfb_open, cyberfb_release, cyberfb_get_fix, cyberfb_get_var,
cyberfb_set_var, cyberfb_get_cmap, cyberfb_set_cmap,
- cyberfb_pan_display, NULL, cyberfb_ioctl
+ cyberfb_pan_display, cyberfb_ioctl
};
@@ -1013,15 +1014,14 @@ __initfunc(void cyberfb_setup(char *options, int *ints))
* Initialization
*/
-__initfunc(unsigned long cyberfb_init(unsigned long mem_start))
+__initfunc(void cyberfb_init(void))
{
- int err;
struct cyberfb_par par;
unsigned long board_addr;
const struct ConfigDev *cd;
if (!(CyberKey = zorro_find(ZORRO_PROD_PHASE5_CYBERVISION64, 0, 0)))
- return mem_start;
+ return;
cd = zorro_get_board (CyberKey);
zorro_config_board (CyberKey, 0);
@@ -1029,7 +1029,7 @@ __initfunc(unsigned long cyberfb_init(unsigned long mem_start))
/* This includes the video memory as well as the S3 register set */
CyberMem = kernel_map (board_addr + 0x01400000, 0x01000000,
- KERNELMAP_NOCACHE_SER, &mem_start);
+ KERNELMAP_NOCACHE_SER, NULL);
CyberRegs = (char*) (CyberMem + 0x00c00000);
fbhw = &Cyber_switch;
@@ -1043,10 +1043,6 @@ __initfunc(unsigned long cyberfb_init(unsigned long mem_start))
fb_info.updatevar = &Cyberfb_updatevar;
fb_info.blank = &Cyberfb_blank;
- err = register_framebuffer(&fb_info);
- if (err < 0)
- return mem_start;
-
fbhw->init();
fbhw->decode_var(&cyberfb_default, &par);
fbhw->encode_var(&cyberfb_default, &par);
@@ -1056,13 +1052,14 @@ __initfunc(unsigned long cyberfb_init(unsigned long mem_start))
cyberfb_set_disp(-1, &fb_info);
do_install_cmap(0, &fb_info);
+ if (register_framebuffer(&fb_info) < 0)
+ return;
+
printk("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 mem_start;
}
@@ -1128,7 +1125,7 @@ __initfunc(static int get_video_mode(const char *name))
* Text console acceleration
*/
-#ifdef CONFIG_FBCON_CFB8
+#ifdef FBCON_HAS_CFB8
static void fbcon_cyber8_bmove(struct display *p, int sy, int sx, int dy,
int dx, int height, int width)
{
@@ -1161,7 +1158,7 @@ static void fbcon_cyber8_putc(struct vc_data *conp, struct display *p, int c,
}
static void fbcon_cyber8_putcs(struct vc_data *conp, struct display *p,
- const char *s, int count, int yy, int xx)
+ const unsigned short *s, int count, int yy, int xx)
{
Cyber_WaitBlit();
fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
@@ -1175,7 +1172,8 @@ static void fbcon_cyber8_revc(struct display *p, int xx, int yy)
static struct display_switch fbcon_cyber8 = {
fbcon_cfb8_setup, fbcon_cyber8_bmove, fbcon_cyber8_clear, fbcon_cyber8_putc,
- fbcon_cyber8_putcs, fbcon_cyber8_revc
+ fbcon_cyber8_putcs, fbcon_cyber8_revc, NULL, NULL, fbcon_cfb8_clear_margins,
+ FONTWIDTH(8)
};
#endif
@@ -1183,7 +1181,8 @@ static struct display_switch fbcon_cyber8 = {
#ifdef MODULE
int init_module(void)
{
- return(cyberfb_init(NULL));
+ cyberfb_init();
+ return 0;
}
void cleanup_module(void)
diff --git a/drivers/video/dnfb.c b/drivers/video/dnfb.c
index db0a6172f..906554641 100644
--- a/drivers/video/dnfb.c
+++ b/drivers/video/dnfb.c
@@ -5,7 +5,6 @@
#include <linux/tty.h>
#include <linux/malloc.h>
#include <linux/delay.h>
-#include <linux/config.h>
#include <linux/interrupt.h>
#include <asm/setup.h>
#include <asm/segment.h>
@@ -114,8 +113,8 @@
/* frame buffer operations */
-static int dnfb_open(struct fb_info *info);
-static int dnfb_release(struct fb_info *info);
+static int dnfb_open(struct fb_info *info, int user);
+static int dnfb_release(struct fb_info *info, int user);
static int dnfb_get_fix(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info);
static int dnfb_get_var(struct fb_var_screeninfo *var, int con,
@@ -142,14 +141,14 @@ static struct display disp[MAX_NR_CONSOLES];
static struct fb_info fb_info;
static struct fb_ops dnfb_ops = {
dnfb_open,dnfb_release, dnfb_get_fix, dnfb_get_var, dnfb_set_var,
- dnfb_get_cmap, dnfb_set_cmap, dnfb_pan_display, NULL, dnfb_ioctl
+ dnfb_get_cmap, dnfb_set_cmap, dnfb_pan_display, dnfb_ioctl
};
static int currcon=0;
static char dnfb_name[]="Apollo";
-static int dnfb_open(struct fb_info *info)
+static int dnfb_open(struct fb_info *info, int user)
{
/*
* Nothing, only a usage count for the moment
@@ -159,7 +158,7 @@ static int dnfb_open(struct fb_info *info)
return(0);
}
-static int dnfb_release(struct fb_info *info)
+static int dnfb_release(struct fb_info *info, int user)
{
MOD_DEC_USE_COUNT;
return(0);
@@ -187,6 +186,7 @@ static int dnfb_get_fix(struct fb_fix_screeninfo *fix, int con,
static int dnfb_get_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
+ memset(var, 0, sizeof(struct fb_var_screeninfo));
var->xres=1280;
var->yres=1024;
var->xres_virtual=2048;
@@ -206,7 +206,6 @@ static int dnfb_get_var(struct fb_var_screeninfo *var, int con,
var->vsync_len=0;
var->sync=0;
var->vmode=FB_VMODE_NONINTERLACED;
- var->accel=FB_ACCEL_NONE;
return 0;
@@ -249,8 +248,6 @@ static int dnfb_set_var(struct fb_var_screeninfo *var, int con,
return -EINVAL;
if(var->vmode!=FB_VMODE_NONINTERLACED)
return -EINVAL;
- if(var->accel!=FB_ACCEL_NONE)
- return -EINVAL;
return 0;
@@ -297,7 +294,7 @@ static void dnfb_set_disp(int con, struct fb_info *info)
if(con==-1)
con=0;
- disp[con].screen_base = (u_char *)fix.smem_start;
+ disp[con].screen_base = fix.smem_start;
disp[con].visual = fix.visual;
disp[con].type = fix.type;
disp[con].type_aux = fix.type_aux;
@@ -306,17 +303,15 @@ static void dnfb_set_disp(int con, struct fb_info *info)
disp[con].can_soft_blank = 1;
disp[con].inverse = 0;
disp[con].line_length = fix.line_length;
-#ifdef CONFIG_FBCON_MFB
+#ifdef FBCON_HAS_MFB
disp[con].dispsw = &fbcon_mfb;
#else
disp[con].dispsw = NULL;
#endif
}
-unsigned long dnfb_init(unsigned long mem_start)
+void dnfb_init(void)
{
- int err;
-
fb_info.changevar=NULL;
strcpy(&fb_info.modename[0],dnfb_name);
fb_info.fontname[0]=0;
@@ -327,13 +322,6 @@ unsigned long dnfb_init(unsigned long mem_start)
fb_info.node = -1;
fb_info.fbops = &dnfb_ops;
- err=register_framebuffer(&fb_info);
- if(err < 0) {
- panic("unable to register apollo frame buffer\n");
- }
-
- /* now we have registered we can safely setup the hardware */
-
outb(RESET_CREG, AP_CONTROL_3A);
outw(0x0, AP_WRITE_ENABLE);
outb(NORMAL_MODE,AP_CONTROL_0);
@@ -341,16 +329,14 @@ unsigned long dnfb_init(unsigned long mem_start)
outb(S_DATA_PLN, AP_CONTROL_2);
outw(SWAP(0x3),AP_ROP_1);
- printk("fb%d: apollo frame buffer alive and kicking !\n",
- GET_FB_IDX(fb_info.node));
-
-
dnfb_get_var(&disp[0].var, 0, &fb_info);
-
dnfb_set_disp(-1, &fb_info);
- return mem_start;
-
+ if (register_framebuffer(&fb_info) < 0)
+ panic("unable to register apollo frame buffer\n");
+
+ printk("fb%d: apollo frame buffer alive and kicking !\n",
+ GET_FB_IDX(fb_info.node));
}
diff --git a/drivers/video/dummycon.c b/drivers/video/dummycon.c
new file mode 100644
index 000000000..4202a5a7d
--- /dev/null
+++ b/drivers/video/dummycon.c
@@ -0,0 +1,71 @@
+/*
+ * linux/drivers/video/dummycon.c -- A dummy console driver
+ *
+ * To be used if there's no other console driver (e.g. for plain VGA text)
+ * available, usually until fbcon takes console over.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kdev_t.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/console_struct.h>
+#include <linux/vt_kern.h>
+#include <linux/init.h>
+
+/*
+ * Dummy console driver
+ */
+
+#if defined(CONFIG_ARM)
+#define DUMMY_COLUMNS ORIG_VIDEO_COLS
+#define DUMMY_ROWS ORIG_VIDEO_LINES
+#else
+#define DUMMY_COLUMNS 80
+#define DUMMY_ROWS 25
+#endif
+
+__initfunc(static const char *dummycon_startup(void))
+{
+ return "dummy device";
+}
+
+static void dummycon_init(struct vc_data *conp, int init)
+{
+ conp->vc_can_do_color = 1;
+ if (init) {
+ conp->vc_cols = DUMMY_COLUMNS;
+ conp->vc_rows = DUMMY_ROWS;
+ } else
+ vc_resize_con(DUMMY_ROWS, DUMMY_COLUMNS, conp->vc_num);
+}
+
+static int dummycon_dummy(void)
+{
+ return 0;
+}
+
+/*
+ * The console `switch' structure for the dummy console
+ *
+ * Most of the operations are dummies.
+ */
+
+struct consw dummy_con = {
+ dummycon_startup, dummycon_init,
+ (void *)dummycon_dummy, /* con_deinit */
+ (void *)dummycon_dummy, /* con_clear */
+ (void *)dummycon_dummy, /* con_putc */
+ (void *)dummycon_dummy, /* con_putcs */
+ (void *)dummycon_dummy, /* con_cursor */
+ (void *)dummycon_dummy, /* con_scroll */
+ (void *)dummycon_dummy, /* con_bmove */
+ (void *)dummycon_dummy, /* con_switch */
+ (void *)dummycon_dummy, /* con_blank */
+ (void *)dummycon_dummy, /* con_font_op */
+ (void *)dummycon_dummy, /* con_set_palette */
+ (void *)dummycon_dummy, /* con_scrolldelta */
+ NULL, /* con_set_origin */
+ NULL, /* con_save_screen */
+};
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index bbf06d89b..d3e339e4f 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -59,7 +59,7 @@ static u16 red8[] = {
0x0000, 0x0000, 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0xaaaa, 0xaaaa
};
static u16 green8[] = {
- 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0xaaaa, 0xaaaa
+ 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa
};
static u16 blue8[] = {
0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa, 0x0000, 0xaaaa
@@ -70,7 +70,7 @@ static u16 red16[] = {
0x5555, 0x5555, 0x5555, 0x5555, 0xffff, 0xffff, 0xffff, 0xffff
};
static u16 green16[] = {
- 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0xaaaa, 0xaaaa,
+ 0x0000, 0x0000, 0xaaaa, 0xaaaa, 0x0000, 0x0000, 0x5555, 0xaaaa,
0x5555, 0x5555, 0xffff, 0xffff, 0x5555, 0x5555, 0xffff, 0xffff
};
static u16 blue16[] = {
diff --git a/drivers/video/fbcon-afb.c b/drivers/video/fbcon-afb.c
index efe9833cb..a8c01d6a0 100644
--- a/drivers/video/fbcon-afb.c
+++ b/drivers/video/fbcon-afb.c
@@ -250,12 +250,10 @@ void fbcon_afb_putc(struct vc_data *conp, struct display *p, int c, int yy,
u_short i, j;
int fg, bg;
- c &= 0xff;
-
dest0 = p->screen_base+yy*p->fontheight*p->next_line+xx;
- cdat0 = p->fontdata+c*p->fontheight;
- fg = attr_fgcol(p,conp);
- bg = attr_bgcol(p,conp);
+ cdat0 = p->fontdata+(c&p->charmask)*p->fontheight;
+ fg = attr_fgcol(p,c);
+ bg = attr_bgcol(p,c);
i = p->var.bits_per_pixel;
do {
@@ -282,22 +280,22 @@ void fbcon_afb_putc(struct vc_data *conp, struct display *p, int c, int yy,
* (cfr. fbcon_putcs_ilbm())
*/
-void fbcon_afb_putcs(struct vc_data *conp, struct display *p, const char *s,
- int count, int yy, int xx)
+void fbcon_afb_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int yy, int xx)
{
u8 *dest, *dest0, *dest1, *expand;
u8 *cdat1, *cdat2, *cdat3, *cdat4, *cdat10, *cdat20, *cdat30, *cdat40;
u_short i, j;
- u8 c1, c2, c3, c4;
+ u16 c1, c2, c3, c4;
int fg0, bg0, fg, bg;
dest0 = p->screen_base+yy*p->fontheight*p->next_line+xx;
- fg0 = attr_fgcol(p,conp);
- bg0 = attr_bgcol(p,conp);
+ fg0 = attr_fgcol(p,*s);
+ bg0 = attr_bgcol(p,*s);
while (count--)
if (xx&3 || count < 3) { /* Slow version */
- c1 = *s++;
+ c1 = *s++ & p->charmask;
dest1 = dest0++;
xx++;
@@ -324,10 +322,10 @@ void fbcon_afb_putcs(struct vc_data *conp, struct display *p, const char *s,
dest1 += p->next_plane;
} while (--i);
} else { /* Fast version */
- c1 = s[0];
- c2 = s[1];
- c3 = s[2];
- c4 = s[3];
+ c1 = s[0] & p->charmask;
+ c2 = s[1] & p->charmask;
+ c3 = s[2] & p->charmask;
+ c4 = s[3] & p->charmask;
dest1 = dest0;
cdat10 = p->fontdata+c1*p->fontheight;
@@ -414,10 +412,21 @@ void fbcon_afb_revc(struct display *p, int xx, int yy)
struct display_switch fbcon_afb = {
fbcon_afb_setup, fbcon_afb_bmove, fbcon_afb_clear, fbcon_afb_putc,
- fbcon_afb_putcs, fbcon_afb_revc
+ fbcon_afb_putcs, fbcon_afb_revc, NULL, NULL, NULL, FONTWIDTH(8)
};
+#ifdef MODULE
+int init_module(void)
+{
+ return 0;
+}
+
+void cleanup_module(void)
+{}
+#endif /* MODULE */
+
+
/*
* Visible symbols for modules
*/
diff --git a/drivers/video/fbcon-afb.h b/drivers/video/fbcon-afb.h
index 537b3bdd7..c82d98c41 100644
--- a/drivers/video/fbcon-afb.h
+++ b/drivers/video/fbcon-afb.h
@@ -2,6 +2,18 @@
* Amiga bitplanes (afb)
*/
+#include <linux/config.h>
+
+#ifdef MODULE
+#if defined(CONFIG_FBCON_AFB) || defined(CONFIG_FBCON_AFB_MODULE)
+#define FBCON_HAS_AFB
+#endif
+#else
+#if defined(CONFIG_FBCON_AFB)
+#define FBCON_HAS_AFB
+#endif
+#endif
+
extern struct display_switch fbcon_afb;
extern void fbcon_afb_setup(struct display *p);
extern void fbcon_afb_bmove(struct display *p, int sy, int sx, int dy, int dx,
@@ -11,5 +23,5 @@ extern void fbcon_afb_clear(struct vc_data *conp, struct display *p, int sy,
extern void fbcon_afb_putc(struct vc_data *conp, struct display *p, int c,
int yy, int xx);
extern void fbcon_afb_putcs(struct vc_data *conp, struct display *p,
- const char *s, int count, int yy, int xx);
+ const unsigned short *s, int count, int yy, int xx);
extern void fbcon_afb_revc(struct display *p, int xx, int yy);
diff --git a/drivers/video/fbcon-cfb16.c b/drivers/video/fbcon-cfb16.c
index 475095988..221fbc572 100644
--- a/drivers/video/fbcon-cfb16.c
+++ b/drivers/video/fbcon-cfb16.c
@@ -9,6 +9,7 @@
* more details.
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/console.h>
@@ -37,7 +38,7 @@ static u32 tab_cfb16[] = {
void fbcon_cfb16_setup(struct display *p)
{
- p->next_line = p->var.xres_virtual<<1;
+ p->next_line = p->line_length ? p->line_length : p->var.xres_virtual<<1;
p->next_plane = 0;
}
@@ -47,23 +48,34 @@ void fbcon_cfb16_bmove(struct display *p, int sy, int sx, int dy, int dx,
int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
u8 *src, *dst;
- if (sx == 0 && dx == 0 && width * 16 == bytes)
+ if (sx == 0 && dx == 0 && width * p->fontwidth * 2 == bytes) {
mymemmove(p->screen_base + dy * linesize,
p->screen_base + sy * linesize,
height * linesize);
- else if (dy < sy || (dy == sy && dx < sx)) {
- src = p->screen_base + sy * linesize + sx * 16;
- dst = p->screen_base + dy * linesize + dx * 16;
- for (rows = height * p->fontheight ; rows-- ;) {
- mymemmove(dst, src, width * 16);
+ return;
+ }
+ if (p->fontwidthlog) {
+ sx <<= p->fontwidthlog+1;
+ dx <<= p->fontwidthlog+1;
+ width <<= p->fontwidthlog+1;
+ } else {
+ sx *= p->fontwidth*2;
+ dx *= p->fontwidth*2;
+ width *= p->fontwidth*2;
+ }
+ if (dy < sy || (dy == sy && dx < sx)) {
+ src = p->screen_base + sy * linesize + sx;
+ dst = p->screen_base + dy * linesize + dx;
+ for (rows = height * p->fontheight; rows--;) {
+ mymemmove(dst, src, width);
src += bytes;
dst += bytes;
}
} else {
- src = p->screen_base + (sy+height) * linesize + sx * 16 - bytes;
- dst = p->screen_base + (dy+height) * linesize + dx * 16 - bytes;
- for (rows = height * p->fontheight ; rows-- ;) {
- mymemmove(dst, src, width * 16);
+ src = p->screen_base + (sy+height) * linesize + sx - bytes;
+ dst = p->screen_base + (dy+height) * linesize + dx - bytes;
+ for (rows = height * p->fontheight; rows--;) {
+ mymemmove(dst, src, width);
src -= bytes;
dst -= bytes;
}
@@ -77,29 +89,26 @@ void fbcon_cfb16_clear(struct vc_data *conp, struct display *p, int sy, int sx,
int bytes = p->next_line, lines = height * p->fontheight, rows, i;
u32 bgx;
- dest = p->screen_base + sy * p->fontheight * bytes + sx * 16;
+ dest = p->screen_base + sy * p->fontheight * bytes + sx * p->fontwidth * 2;
bgx = fbcon_cfb16_cmap[attr_bgcol_ec(p, conp)];
bgx |= (bgx << 16);
- if (sx == 0 && width * 16 == bytes)
- for (i = 0 ; i < lines * width ; i++) {
+ width *= p->fontwidth/4;
+ if (sx == 0 && width * 8 == bytes)
+ for (i = 0; i < lines * width; i++) {
((u32 *)dest)[0] = bgx;
((u32 *)dest)[1] = bgx;
- ((u32 *)dest)[2] = bgx;
- ((u32 *)dest)[3] = bgx;
- dest += 16;
+ dest += 8;
}
else {
dest0 = dest;
- for (rows = lines; rows-- ; dest0 += bytes) {
+ for (rows = lines; rows--; dest0 += bytes) {
dest = dest0;
- for (i = 0 ; i < width ; i++) {
+ for (i = 0; i < width; i++) {
((u32 *)dest)[0] = bgx;
((u32 *)dest)[1] = bgx;
- ((u32 *)dest)[2] = bgx;
- ((u32 *)dest)[3] = bgx;
- dest += 16;
+ dest += 8;
}
}
}
@@ -108,56 +117,124 @@ void fbcon_cfb16_clear(struct vc_data *conp, struct display *p, int sy, int sx,
void fbcon_cfb16_putc(struct vc_data *conp, struct display *p, int c, int yy,
int xx)
{
- u8 *dest, *cdat;
+ u8 *dest, *cdat, bits;
int bytes = p->next_line, rows;
u32 eorx, fgx, bgx;
- c &= 0xff;
+ dest = p->screen_base + yy * p->fontheight * bytes + xx * p->fontwidth * 2;
- dest = p->screen_base + yy * p->fontheight * bytes + xx * 16;
- cdat = p->fontdata + c * p->fontheight;
-
- fgx = fbcon_cfb16_cmap[attr_fgcol(p, conp)];
- bgx = fbcon_cfb16_cmap[attr_bgcol(p, conp)];
+ fgx = fbcon_cfb16_cmap[attr_fgcol(p, c)];
+ bgx = fbcon_cfb16_cmap[attr_bgcol(p, c)];
fgx |= (fgx << 16);
bgx |= (bgx << 16);
eorx = fgx ^ bgx;
- for (rows = p->fontheight ; rows-- ; dest += bytes) {
- u8 bits = *cdat++;
- ((u32 *)dest)[0] = (tab_cfb16[bits >> 6] & eorx) ^ bgx;
- ((u32 *)dest)[1] = (tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx;
- ((u32 *)dest)[2] = (tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx;
- ((u32 *)dest)[3] = (tab_cfb16[bits & 3] & eorx) ^ bgx;
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ switch (p->fontwidth) {
+ case 4:
+ case 8:
+#endif
+ cdat = p->fontdata + (c & p->charmask) * p->fontheight;
+ for (rows = p->fontheight; rows--; dest += bytes) {
+ bits = *cdat++;
+ ((u32 *)dest)[0] = (tab_cfb16[bits >> 6] & eorx) ^ bgx;
+ ((u32 *)dest)[1] = (tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx;
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (p->fontwidth == 8)
+#endif
+ {
+ ((u32 *)dest)[2] = (tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx;
+ ((u32 *)dest)[3] = (tab_cfb16[bits & 3] & eorx) ^ bgx;
+ }
+ }
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ break;
+ case 12:
+ case 16:
+ cdat = p->fontdata + ((c & p->charmask) * p->fontheight << 1);
+ for (rows = p->fontheight; rows--; dest += bytes) {
+ bits = *cdat++;
+ ((u32 *)dest)[0] = (tab_cfb16[bits >> 6] & eorx) ^ bgx;
+ ((u32 *)dest)[1] = (tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx;
+ ((u32 *)dest)[2] = (tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx;
+ ((u32 *)dest)[3] = (tab_cfb16[bits & 3] & eorx) ^ bgx;
+ bits = *cdat++;
+ ((u32 *)dest)[4] = (tab_cfb16[bits >> 6] & eorx) ^ bgx;
+ ((u32 *)dest)[5] = (tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx;
+ if (p->fontwidth == 16) {
+ ((u32 *)dest)[6] = (tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx;
+ ((u32 *)dest)[7] = (tab_cfb16[bits & 3] & eorx) ^ bgx;
+ }
+ }
+ break;
}
+#endif
}
-void fbcon_cfb16_putcs(struct vc_data *conp, struct display *p, const char *s,
- int count, int yy, int xx)
+void fbcon_cfb16_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int yy, int xx)
{
- u8 *cdat, c, *dest, *dest0;
+ u8 *cdat, *dest, *dest0;
+ u16 c;
int rows, bytes = p->next_line;
u32 eorx, fgx, bgx;
- dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 16;
- fgx = fbcon_cfb16_cmap[attr_fgcol(p, conp)];
- bgx = fbcon_cfb16_cmap[attr_bgcol(p, conp)];
+ dest0 = p->screen_base + yy * p->fontheight * bytes + xx * p->fontwidth * 2;
+ fgx = fbcon_cfb16_cmap[attr_fgcol(p, *s)];
+ bgx = fbcon_cfb16_cmap[attr_bgcol(p, *s)];
fgx |= (fgx << 16);
bgx |= (bgx << 16);
eorx = fgx ^ bgx;
- while (count--) {
- c = *s++;
- cdat = p->fontdata + c * p->fontheight;
- for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
- u8 bits = *cdat++;
- ((u32 *)dest)[0] = (tab_cfb16[bits >> 6] & eorx) ^ bgx;
- ((u32 *)dest)[1] = (tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx;
- ((u32 *)dest)[2] = (tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx;
- ((u32 *)dest)[3] = (tab_cfb16[bits & 3] & eorx) ^ bgx;
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ switch (p->fontwidth) {
+ case 4:
+ case 8:
+#endif
+ while (count--) {
+ c = *s++ & p->charmask;
+ cdat = p->fontdata + c * p->fontheight;
+ for (rows = p->fontheight, dest = dest0; rows--; dest += bytes) {
+ u8 bits = *cdat++;
+ ((u32 *)dest)[0] = (tab_cfb16[bits >> 6] & eorx) ^ bgx;
+ ((u32 *)dest)[1] = (tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx;
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (p->fontwidth == 8)
+#endif
+ {
+
+ ((u32 *)dest)[2] = (tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx;
+ ((u32 *)dest)[3] = (tab_cfb16[bits & 3] & eorx) ^ bgx;
+ }
+ }
+ dest0 += p->fontwidth*2;;
}
- dest0 += 16;
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ break;
+ case 12:
+ case 16:
+ while (count--) {
+ c = *s++ & p->charmask;
+ cdat = p->fontdata + (c * p->fontheight << 1);
+ for (rows = p->fontheight, dest = dest0; rows--; dest += bytes) {
+ u8 bits = *cdat++;
+ ((u32 *)dest)[0] = (tab_cfb16[bits >> 6] & eorx) ^ bgx;
+ ((u32 *)dest)[1] = (tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx;
+ ((u32 *)dest)[2] = (tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx;
+ ((u32 *)dest)[3] = (tab_cfb16[bits & 3] & eorx) ^ bgx;
+ bits = *cdat++;
+ ((u32 *)dest)[4] = (tab_cfb16[bits >> 6] & eorx) ^ bgx;
+ ((u32 *)dest)[5] = (tab_cfb16[bits >> 4 & 3] & eorx) ^ bgx;
+ if (p->fontwidth == 16) {
+ ((u32 *)dest)[6] = (tab_cfb16[bits >> 2 & 3] & eorx) ^ bgx;
+ ((u32 *)dest)[7] = (tab_cfb16[bits & 3] & eorx) ^ bgx;
+ }
+ }
+ dest0 += p->fontwidth*2;
+ }
+ break;
}
+#endif
}
void fbcon_cfb16_revc(struct display *p, int xx, int yy)
@@ -165,12 +242,60 @@ void fbcon_cfb16_revc(struct display *p, int xx, int yy)
u8 *dest;
int bytes = p->next_line, rows;
- dest = p->screen_base + yy * p->fontheight * bytes + xx * 16;
- for (rows = p->fontheight ; rows-- ; dest += bytes) {
- ((u32 *)dest)[0] ^= 0xffffffff;
- ((u32 *)dest)[1] ^= 0xffffffff;
- ((u32 *)dest)[2] ^= 0xffffffff;
- ((u32 *)dest)[3] ^= 0xffffffff;
+ dest = p->screen_base + yy * p->fontheight * bytes + xx * p->fontwidth*2;
+ for (rows = p->fontheight; rows--; dest += bytes) {
+#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
+ ((u32 *)dest)[2] ^= 0xffffffff; ((u32 *)dest)[3] ^= 0xffffffff;
+ ((u32 *)dest)[0] ^= 0xffffffff; ((u32 *)dest)[1] ^= 0xffffffff;
+#else
+ switch (p->fontwidth) {
+ case 16:
+ ((u32 *)dest)[6] ^= 0xffffffff; ((u32 *)dest)[7] ^= 0xffffffff;
+ /* FALL THROUGH */
+ case 12:
+ ((u32 *)dest)[4] ^= 0xffffffff; ((u32 *)dest)[5] ^= 0xffffffff;
+ /* FALL THROUGH */
+ case 8:
+ ((u32 *)dest)[2] ^= 0xffffffff; ((u32 *)dest)[3] ^= 0xffffffff;
+ /* FALL THROUGH */
+ case 4:
+ ((u32 *)dest)[0] ^= 0xffffffff; ((u32 *)dest)[1] ^= 0xffffffff;
+ }
+#endif
+ }
+}
+
+void fbcon_cfb16_clear_margins(struct vc_data *conp, struct display *p)
+{
+ u8 *dest0;
+ u32 *dest;
+ int bytes = p->next_line;
+ u32 bgx;
+ int i, j;
+
+ unsigned int right_start = conp->vc_cols*p->fontwidth;
+ unsigned int right_width = p->var.xres_virtual-right_start;
+ unsigned int bottom_start = conp->vc_rows*p->fontheight;
+ unsigned int bottom_width = p->var.yres_virtual-bottom_start;
+
+ bgx = fbcon_cfb16_cmap[attr_bgcol_ec(p, conp)];
+ bgx |= (bgx << 16);
+
+ if (right_width) {
+ dest0 = p->screen_base+right_start*2;
+ for (i = 0; i < bottom_start; i++, dest0 += bytes) {
+ for (j = 0, dest = (u32 *)dest0; j < right_width/2; j++)
+ *dest++ = bgx;
+ if (right_width & 1)
+ *(u16 *)dest = bgx;
+ }
+ }
+ if (bottom_width) {
+ dest = (u32 *)(p->screen_base+bottom_start*bytes);
+ for (i = 0; i < bytes*bottom_width/4; i++)
+ *dest++ = bgx;
+ if ((bytes*bottom_width) & 2)
+ *(u16 *)dest = bgx;
}
}
@@ -181,10 +306,22 @@ void fbcon_cfb16_revc(struct display *p, int xx, int yy)
struct display_switch fbcon_cfb16 = {
fbcon_cfb16_setup, fbcon_cfb16_bmove, fbcon_cfb16_clear, fbcon_cfb16_putc,
- fbcon_cfb16_putcs, fbcon_cfb16_revc
+ fbcon_cfb16_putcs, fbcon_cfb16_revc, NULL, NULL, fbcon_cfb16_clear_margins,
+ FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
};
+#ifdef MODULE
+int init_module(void)
+{
+ return 0;
+}
+
+void cleanup_module(void)
+{}
+#endif /* MODULE */
+
+
/*
* Visible symbols for modules
*/
diff --git a/drivers/video/fbcon-cfb16.h b/drivers/video/fbcon-cfb16.h
index 905d6329a..ebff9bcb9 100644
--- a/drivers/video/fbcon-cfb16.h
+++ b/drivers/video/fbcon-cfb16.h
@@ -2,6 +2,18 @@
* 16 bpp packed pixel (cfb16)
*/
+#include <linux/config.h>
+
+#ifdef MODULE
+#if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB16_MODULE)
+#define FBCON_HAS_CFB16
+#endif
+#else
+#if defined(CONFIG_FBCON_CFB16)
+#define FBCON_HAS_CFB16
+#endif
+#endif
+
extern struct display_switch fbcon_cfb16;
extern u16 fbcon_cfb16_cmap[16];
extern void fbcon_cfb16_setup(struct display *p);
@@ -12,5 +24,6 @@ extern void fbcon_cfb16_clear(struct vc_data *conp, struct display *p, int sy,
extern void fbcon_cfb16_putc(struct vc_data *conp, struct display *p, int c,
int yy, int xx);
extern void fbcon_cfb16_putcs(struct vc_data *conp, struct display *p,
- const char *s, int count, int yy, int xx);
+ const unsigned short *s, int count, int yy, int xx);
extern void fbcon_cfb16_revc(struct display *p, int xx, int yy);
+extern void fbcon_cfb16_clear_margins(struct vc_data *conp, struct display *p);
diff --git a/drivers/video/fbcon-cfb2.c b/drivers/video/fbcon-cfb2.c
index 6ed68e89d..60bed6275 100644
--- a/drivers/video/fbcon-cfb2.c
+++ b/drivers/video/fbcon-cfb2.c
@@ -32,10 +32,19 @@
*/
static u_char nibbletab_cfb2[]={
+#if defined(__BIG_ENDIAN)
0x00,0x03,0x0c,0x0f,
0x30,0x33,0x3c,0x3f,
0xc0,0xc3,0xcc,0xcf,
0xf0,0xf3,0xfc,0xff
+#elif defined(__LITTLE_ENDIAN)
+ 0x00,0xc0,0x30,0xf0,
+ 0x0c,0xcc,0x3c,0xfc,
+ 0x03,0xc3,0x33,0xf3,
+ 0x0f,0xcf,0x3f,0xff
+#else
+#error FIXME: No endianness??
+#endif
};
@@ -119,13 +128,11 @@ void fbcon_cfb2_putc(struct vc_data *conp, struct display *p, int c, int yy,
int bytes=p->next_line,rows;
u32 eorx,fgx,bgx;
- c &= 0xff;
-
dest = p->screen_base + yy * p->fontheight * bytes + xx * 2;
- cdat = p->fontdata + c * p->fontheight;
+ cdat = p->fontdata + (c & p->charmask) * p->fontheight;
- fgx=3;/*attr_fgcol(p,conp)&0x0F;*/
- bgx=attr_bgcol(p,conp)&0x0F;
+ fgx=3;/*attr_fgcol(p,c);*/
+ bgx=attr_bgcol(p,c);
fgx |= (fgx << 2); /* expand color to 8 bits */
fgx |= (fgx << 4);
bgx |= (bgx << 2);
@@ -140,23 +147,24 @@ void fbcon_cfb2_putc(struct vc_data *conp, struct display *p, int c, int yy,
}
}
-void fbcon_cfb2_putcs(struct vc_data *conp, struct display *p, const char *s,
+void fbcon_cfb2_putcs(struct vc_data *conp, struct display *p, const unsigned short *s,
int count, int yy, int xx)
{
- u8 *cdat, c, *dest, *dest0;
+ u8 *cdat, *dest, *dest0;
+ u16 c;
int rows,bytes=p->next_line;
u32 eorx, fgx, bgx;
dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 2;
- fgx=3/*attr_fgcol(p,conp)*/;
- bgx=attr_bgcol(p,conp);
+ fgx=3/*attr_fgcol(p,*s)*/;
+ bgx=attr_bgcol(p,*s);
fgx |= (fgx << 2);
fgx |= (fgx << 4);
bgx |= (bgx << 2);
bgx |= (bgx << 4);
eorx = fgx ^ bgx;
while (count--) {
- c = *s++;
+ c = *s++ & p->charmask;
cdat = p->fontdata + c * p->fontheight;
for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
@@ -187,10 +195,21 @@ void fbcon_cfb2_revc(struct display *p, int xx, int yy)
struct display_switch fbcon_cfb2 = {
fbcon_cfb2_setup, fbcon_cfb2_bmove, fbcon_cfb2_clear, fbcon_cfb2_putc,
- fbcon_cfb2_putcs, fbcon_cfb2_revc
+ fbcon_cfb2_putcs, fbcon_cfb2_revc, NULL, NULL, NULL, FONTWIDTH(8)
};
+#ifdef MODULE
+int init_module(void)
+{
+ return 0;
+}
+
+void cleanup_module(void)
+{}
+#endif /* MODULE */
+
+
/*
* Visible symbols for modules
*/
diff --git a/drivers/video/fbcon-cfb2.h b/drivers/video/fbcon-cfb2.h
index 4fb3bb13a..1cb29c5a9 100644
--- a/drivers/video/fbcon-cfb2.h
+++ b/drivers/video/fbcon-cfb2.h
@@ -2,6 +2,18 @@
* 2 bpp packed pixel (cfb2)
*/
+#include <linux/config.h>
+
+#ifdef MODULE
+#if defined(CONFIG_FBCON_CFB2) || defined(CONFIG_FBCON_CFB2_MODULE)
+#define FBCON_HAS_CFB2
+#endif
+#else
+#if defined(CONFIG_FBCON_CFB2)
+#define FBCON_HAS_CFB2
+#endif
+#endif
+
extern struct display_switch fbcon_cfb2;
extern void fbcon_cfb2_setup(struct display *p);
extern void fbcon_cfb2_bmove(struct display *p, int sy, int sx, int dy, int dx,
@@ -11,5 +23,5 @@ extern void fbcon_cfb2_clear(struct vc_data *conp, struct display *p, int sy,
extern void fbcon_cfb2_putc(struct vc_data *conp, struct display *p, int c,
int yy, int xx);
extern void fbcon_cfb2_putcs(struct vc_data *conp, struct display *p,
- const char *s, int count, int yy, int xx);
+ const unsigned short *s, int count, int yy, int xx);
extern void fbcon_cfb2_revc(struct display *p, int xx, int yy);
diff --git a/drivers/video/fbcon-cfb24.c b/drivers/video/fbcon-cfb24.c
index 2a95a28cf..49c023ef3 100644
--- a/drivers/video/fbcon-cfb24.c
+++ b/drivers/video/fbcon-cfb24.c
@@ -9,6 +9,7 @@
* more details.
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/console.h>
@@ -19,9 +20,6 @@
#include "fbcon-cfb24.h"
-#warning Remove this warning after the test cycle was finalized
-
-
/*
* 24 bpp packed pixels
*/
@@ -40,29 +38,56 @@ void fbcon_cfb24_bmove(struct display *p, int sy, int sx, int dy, int dx,
int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
u8 *src, *dst;
- if (sx == 0 && dx == 0 && width * 24 == bytes)
+ if (sx == 0 && dx == 0 && width * p->fontwidth * 3 == bytes) {
mymemmove(p->screen_base + dy * linesize,
p->screen_base + sy * linesize,
height * linesize);
- else if (dy < sy || (dy == sy && dx < sx)) {
- src = p->screen_base + sy * linesize + sx * 24;
- dst = p->screen_base + dy * linesize + dx * 24;
- for (rows = height * p->fontheight ; rows-- ;) {
- mymemmove(dst, src, width * 24);
+ return;
+ }
+ if (p->fontwidthlog) {
+ sx <<= p->fontwidthlog;
+ dx <<= p->fontwidthlog;
+ width <<= p->fontwidthlog;
+ } else {
+ sx *= p->fontwidth;
+ dx *= p->fontwidth;
+ width *= p->fontwidth;
+ }
+ sx *= 3; dx *= 3; width *= 3;
+ if (dy < sy || (dy == sy && dx < sx)) {
+ src = p->screen_base + sy * linesize + sx;
+ dst = p->screen_base + dy * linesize + dx;
+ for (rows = height * p->fontheight; rows--;) {
+ mymemmove(dst, src, width);
src += bytes;
dst += bytes;
}
} else {
- src = p->screen_base + (sy+height) * linesize + sx * 24 - bytes;
- dst = p->screen_base + (dy+height) * linesize + dx * 24 - bytes;
- for (rows = height * p->fontheight ; rows-- ;) {
- mymemmove(dst, src, width * 24);
+ src = p->screen_base + (sy+height) * linesize + sx - bytes;
+ dst = p->screen_base + (dy+height) * linesize + dx - bytes;
+ for (rows = height * p->fontheight; rows--;) {
+ mymemmove(dst, src, width);
src -= bytes;
dst -= bytes;
}
}
}
+static inline void store4pixels(u32 d1, u32 d2, u32 d3, u32 d4, u32 *dest)
+{
+#if defined(__BIG_ENDIAN)
+ *dest++ = (d1<<8) | (d2>>16);
+ *dest++ = (d2<<16) | (d3>>8);
+ *dest++ = (d3<<24) | d4;
+#elif defined(__LITTLE_ENDIAN)
+ *dest++ = (d1<<8) | (d2>>16);
+ *dest++ = (d2<<16) | (d3>>8);
+ *dest++ = (d3<<24) | d4;
+#else
+#error FIXME: No endianness??
+#endif
+}
+
void fbcon_cfb24_clear(struct vc_data *conp, struct display *p, int sy, int sx,
int height, int width)
{
@@ -70,112 +95,139 @@ void fbcon_cfb24_clear(struct vc_data *conp, struct display *p, int sy, int sx,
int bytes = p->next_line, lines = height * p->fontheight, rows, i;
u32 bgx;
- dest = p->screen_base + sy * p->fontheight * bytes + sx * 24;
+ dest = p->screen_base + sy * p->fontheight * bytes + sx * p->fontwidth * 3;
bgx = fbcon_cfb24_cmap[attr_bgcol_ec(p, conp)];
- if (sx == 0 && width * 24 == bytes)
- for (i = 0 ; i < lines * width ; i++) {
- ((u32 *)dest)[0] = bgx;
- ((u32 *)dest)[1] = bgx;
- ((u32 *)dest)[2] = bgx;
- ((u32 *)dest)[3] = bgx;
- ((u32 *)dest)[4] = bgx;
- ((u32 *)dest)[5] = bgx;
- dest += 24;
+ width *= p->fontwidth/4;
+ if (sx == 0 && width * 12 == bytes)
+ for (i = 0; i < lines * width; i++) {
+ store4pixels(bgx, bgx, bgx, bgx, (u32 *)dest);
+ dest += 12;
}
else {
dest0 = dest;
- for (rows = lines; rows-- ; dest0 += bytes) {
+ for (rows = lines; rows--; dest0 += bytes) {
dest = dest0;
- for (i = 0 ; i < width ; i++) {
- ((u32 *)dest)[0] = bgx;
- ((u32 *)dest)[1] = bgx;
- ((u32 *)dest)[2] = bgx;
- ((u32 *)dest)[3] = bgx;
- ((u32 *)dest)[4] = bgx;
- ((u32 *)dest)[5] = bgx;
- dest += 24;
+ for (i = 0; i < width; i++) {
+ store4pixels(bgx, bgx, bgx, bgx, (u32 *)dest);
+ dest += 12;
}
}
}
}
-static inline void store4pixels(u32 d1, u32 d2, u32 d3, u32 d4, u32 *dest)
-{
-#if defined(__BIG_ENDIAN)
- *dest++ = (d1<<8) | (d2>>16);
- *dest++ = (d2<<16) | (d3>>8);
- *dest++ = (d3<<24) | d4;
-#elif defined(__LITTLE_ENDIAN)
-#error Please add support for little endian byteorder
-#else
-#error FIXME: No endianness??
-#endif
-}
-
void fbcon_cfb24_putc(struct vc_data *conp, struct display *p, int c, int yy,
int xx)
{
- u8 *dest, *cdat;
+ u8 *dest, *cdat, bits;
int bytes = p->next_line, rows;
- u32 eorx, fgx, bgx;
-
- c &= 0xff;
+ u32 eorx, fgx, bgx, d1, d2, d3, d4;
- dest = p->screen_base + yy * p->fontheight * bytes + xx * 24;
- cdat = p->fontdata + c * p->fontheight;
+ dest = p->screen_base + yy * p->fontheight * bytes + xx * p->fontwidth * 3;
+ if (p->fontwidth <= 8)
+ cdat = p->fontdata + (c & p->charmask) * p->fontheight;
+ else
+ cdat = p->fontdata + ((c & p->charmask) * p->fontheight << 1);
- fgx = fbcon_cfb24_cmap[attr_fgcol(p, conp)];
- bgx = fbcon_cfb24_cmap[attr_bgcol(p, conp)];
+ fgx = fbcon_cfb24_cmap[attr_fgcol(p, c)];
+ bgx = fbcon_cfb24_cmap[attr_bgcol(p, c)];
eorx = fgx ^ bgx;
- for (rows = p->fontheight ; rows-- ; dest += bytes) {
- u8 bits = *cdat++;
- u32 d1, d2, d3, d4;
+ for (rows = p->fontheight; rows--; dest += bytes) {
+ bits = *cdat++;
d1 = (-(bits >> 7) & eorx) ^ bgx;
d2 = (-(bits >> 6 & 1) & eorx) ^ bgx;
d3 = (-(bits >> 5 & 1) & eorx) ^ bgx;
d4 = (-(bits >> 4 & 1) & eorx) ^ bgx;
store4pixels(d1, d2, d3, d4, (u32 *)dest);
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (p->fontwidth < 8)
+ continue;
+#endif
d1 = (-(bits >> 3 & 1) & eorx) ^ bgx;
d2 = (-(bits >> 2 & 1) & eorx) ^ bgx;
d3 = (-(bits >> 1 & 1) & eorx) ^ bgx;
d4 = (-(bits & 1) & eorx) ^ bgx;
store4pixels(d1, d2, d3, d4, (u32 *)(dest+12));
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (p->fontwidth < 12)
+ continue;
+ bits = *cdat++;
+ d1 = (-(bits >> 7) & eorx) ^ bgx;
+ d2 = (-(bits >> 6 & 1) & eorx) ^ bgx;
+ d3 = (-(bits >> 5 & 1) & eorx) ^ bgx;
+ d4 = (-(bits >> 4 & 1) & eorx) ^ bgx;
+ store4pixels(d1, d2, d3, d4, (u32 *)(dest+24));
+ if (p->fontwidth < 16)
+ continue;
+ d1 = (-(bits >> 3 & 1) & eorx) ^ bgx;
+ d2 = (-(bits >> 2 & 1) & eorx) ^ bgx;
+ d3 = (-(bits >> 1 & 1) & eorx) ^ bgx;
+ d4 = (-(bits & 1) & eorx) ^ bgx;
+ store4pixels(d1, d2, d3, d4, (u32 *)(dest+32));
+#endif
}
}
-void fbcon_cfb24_putcs(struct vc_data *conp, struct display *p, const char *s,
- int count, int yy, int xx)
+void fbcon_cfb24_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int yy, int xx)
{
- u8 *cdat, c, *dest, *dest0;
+ u8 *cdat, *dest, *dest0, bits;
+ u16 c;
int rows, bytes = p->next_line;
- u32 eorx, fgx, bgx;
+ u32 eorx, fgx, bgx, d1, d2, d3, d4;
- dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 24;
- fgx = fbcon_cfb24_cmap[attr_fgcol(p, conp)];
- bgx = fbcon_cfb24_cmap[attr_bgcol(p, conp)];
+ dest0 = p->screen_base + yy * p->fontheight * bytes + xx * p->fontwidth * 3;
+ fgx = fbcon_cfb24_cmap[attr_fgcol(p, *s)];
+ bgx = fbcon_cfb24_cmap[attr_bgcol(p, *s)];
eorx = fgx ^ bgx;
while (count--) {
- c = *s++;
+ c = *s++ & p->charmask;
+#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
cdat = p->fontdata + c * p->fontheight;
-
- for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
- u8 bits = *cdat++;
- u32 d1, d2, d3, d4;
+#else
+ if (p->fontwidth <= 8)
+ cdat = p->fontdata + c * p->fontheight;
+
+ else
+ cdat = p->fontdata + (c * p->fontheight << 1);
+#endif
+ for (rows = p->fontheight, dest = dest0; rows--; dest += bytes) {
+ bits = *cdat++;
d1 = (-(bits >> 7) & eorx) ^ bgx;
d2 = (-(bits >> 6 & 1) & eorx) ^ bgx;
d3 = (-(bits >> 5 & 1) & eorx) ^ bgx;
d4 = (-(bits >> 4 & 1) & eorx) ^ bgx;
store4pixels(d1, d2, d3, d4, (u32 *)dest);
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (p->fontwidth < 8)
+ continue;
+#endif
d1 = (-(bits >> 3 & 1) & eorx) ^ bgx;
d2 = (-(bits >> 2 & 1) & eorx) ^ bgx;
d3 = (-(bits >> 1 & 1) & eorx) ^ bgx;
d4 = (-(bits & 1) & eorx) ^ bgx;
store4pixels(d1, d2, d3, d4, (u32 *)(dest+12));
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (p->fontwidth < 12)
+ continue;
+ bits = *cdat++;
+ d1 = (-(bits >> 7) & eorx) ^ bgx;
+ d2 = (-(bits >> 6 & 1) & eorx) ^ bgx;
+ d3 = (-(bits >> 5 & 1) & eorx) ^ bgx;
+ d4 = (-(bits >> 4 & 1) & eorx) ^ bgx;
+ store4pixels(d1, d2, d3, d4, (u32 *)(dest+24));
+ if (p->fontwidth < 16)
+ continue;
+ d1 = (-(bits >> 3 & 1) & eorx) ^ bgx;
+ d2 = (-(bits >> 2 & 1) & eorx) ^ bgx;
+ d3 = (-(bits >> 1 & 1) & eorx) ^ bgx;
+ d4 = (-(bits & 1) & eorx) ^ bgx;
+ store4pixels(d1, d2, d3, d4, (u32 *)(dest+32));
+#endif
}
- dest0 += 24;
+ dest0 += p->fontwidth*3;
}
}
@@ -184,14 +236,60 @@ void fbcon_cfb24_revc(struct display *p, int xx, int yy)
u8 *dest;
int bytes = p->next_line, rows;
- dest = p->screen_base + yy * p->fontheight * bytes + xx * 24;
- for (rows = p->fontheight ; rows-- ; dest += bytes) {
- ((u32 *)dest)[0] ^= 0xffffffff;
- ((u32 *)dest)[1] ^= 0xffffffff;
- ((u32 *)dest)[2] ^= 0xffffffff;
- ((u32 *)dest)[3] ^= 0xffffffff;
- ((u32 *)dest)[4] ^= 0xffffffff;
+ dest = p->screen_base + yy * p->fontheight * bytes + xx * p->fontwidth * 3;
+ for (rows = p->fontheight; rows--; dest += bytes) {
+#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
+ ((u32 *)dest)[3] ^= 0xffffffff; ((u32 *)dest)[4] ^= 0xffffffff;
((u32 *)dest)[5] ^= 0xffffffff;
+ ((u32 *)dest)[0] ^= 0xffffffff; ((u32 *)dest)[1] ^= 0xffffffff;
+ ((u32 *)dest)[2] ^= 0xffffffff;
+#else
+ switch (p->fontwidth) {
+ case 16:
+ ((u32 *)dest)[9] ^= 0xffffffff; ((u32 *)dest)[10] ^= 0xffffffff;
+ ((u32 *)dest)[11] ^= 0xffffffff; /* FALL THROUGH */
+ case 12:
+ ((u32 *)dest)[6] ^= 0xffffffff; ((u32 *)dest)[7] ^= 0xffffffff;
+ ((u32 *)dest)[8] ^= 0xffffffff; /* FALL THROUGH */
+ case 8:
+ ((u32 *)dest)[3] ^= 0xffffffff; ((u32 *)dest)[4] ^= 0xffffffff;
+ ((u32 *)dest)[5] ^= 0xffffffff; /* FALL THROUGH */
+ case 4:
+ ((u32 *)dest)[0] ^= 0xffffffff; ((u32 *)dest)[1] ^= 0xffffffff;
+ ((u32 *)dest)[2] ^= 0xffffffff;
+ }
+#endif
+ }
+}
+
+void fbcon_cfb24_clear_margins(struct vc_data *conp, struct display *p)
+{
+ u8 *dest0, *dest;
+ int bytes = p->next_line;
+ u32 bgx;
+ int i, j;
+
+ unsigned int right_start = conp->vc_cols*p->fontwidth;
+ unsigned int right_width = p->var.xres_virtual-right_start;
+ unsigned int bottom_start = conp->vc_rows*p->fontheight;
+ unsigned int bottom_width = p->var.yres_virtual-bottom_start;
+
+ bgx = fbcon_cfb24_cmap[attr_bgcol_ec(p, conp)];
+
+ if (right_width) {
+ dest0 = p->screen_base+right_start*3;
+ for (i = 0; i < bottom_start; i++, dest0 += bytes)
+ for (j = 0, dest = dest0; j < right_width/4; j++) {
+ store4pixels(bgx, bgx, bgx, bgx, (u32 *)dest);
+ dest += 12;
+ }
+ }
+ if (bottom_width) {
+ dest = p->screen_base+bottom_start*bytes;
+ for (i = 0; i < bytes*bottom_width/12; i++) {
+ store4pixels(bgx, bgx, bgx, bgx, (u32 *)dest);
+ dest += 12;
+ }
}
}
@@ -202,10 +300,22 @@ void fbcon_cfb24_revc(struct display *p, int xx, int yy)
struct display_switch fbcon_cfb24 = {
fbcon_cfb24_setup, fbcon_cfb24_bmove, fbcon_cfb24_clear, fbcon_cfb24_putc,
- fbcon_cfb24_putcs, fbcon_cfb24_revc
+ fbcon_cfb24_putcs, fbcon_cfb24_revc, NULL, NULL, fbcon_cfb24_clear_margins,
+ FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
};
+#ifdef MODULE
+int init_module(void)
+{
+ return 0;
+}
+
+void cleanup_module(void)
+{}
+#endif /* MODULE */
+
+
/*
* Visible symbols for modules
*/
diff --git a/drivers/video/fbcon-cfb24.h b/drivers/video/fbcon-cfb24.h
index bd672ab20..83cee1209 100644
--- a/drivers/video/fbcon-cfb24.h
+++ b/drivers/video/fbcon-cfb24.h
@@ -2,6 +2,18 @@
* 24 bpp packed pixel (cfb24)
*/
+#include <linux/config.h>
+
+#ifdef MODULE
+#if defined(CONFIG_FBCON_CFB24) || defined(CONFIG_FBCON_CFB24_MODULE)
+#define FBCON_HAS_CFB24
+#endif
+#else
+#if defined(CONFIG_FBCON_CFB24)
+#define FBCON_HAS_CFB24
+#endif
+#endif
+
extern struct display_switch fbcon_cfb24;
extern u32 fbcon_cfb24_cmap[16];
extern void fbcon_cfb24_setup(struct display *p);
@@ -12,5 +24,6 @@ extern void fbcon_cfb24_clear(struct vc_data *conp, struct display *p, int sy,
extern void fbcon_cfb24_putc(struct vc_data *conp, struct display *p, int c,
int yy, int xx);
extern void fbcon_cfb24_putcs(struct vc_data *conp, struct display *p,
- const char *s, int count, int yy, int xx);
+ const unsigned short *s, int count, int yy, int xx);
extern void fbcon_cfb24_revc(struct display *p, int xx, int yy);
+extern void fbcon_cfb24_clear_margins(struct vc_data *conp, struct display *p);
diff --git a/drivers/video/fbcon-cfb32.c b/drivers/video/fbcon-cfb32.c
index cedc04814..1a1c48bcf 100644
--- a/drivers/video/fbcon-cfb32.c
+++ b/drivers/video/fbcon-cfb32.c
@@ -9,6 +9,7 @@
* more details.
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/console.h>
@@ -37,23 +38,34 @@ void fbcon_cfb32_bmove(struct display *p, int sy, int sx, int dy, int dx,
int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
u8 *src, *dst;
- if (sx == 0 && dx == 0 && width * 32 == bytes)
+ if (sx == 0 && dx == 0 && width * p->fontwidth * 4 == bytes) {
mymemmove(p->screen_base + dy * linesize,
p->screen_base + sy * linesize,
height * linesize);
- else if (dy < sy || (dy == sy && dx < sx)) {
- src = p->screen_base + sy * linesize + sx * 32;
- dst = p->screen_base + dy * linesize + dx * 32;
- for (rows = height * p->fontheight ; rows-- ;) {
- mymemmove(dst, src, width * 32);
+ return;
+ }
+ if (p->fontwidthlog) {
+ sx <<= p->fontwidthlog+2;
+ dx <<= p->fontwidthlog+2;
+ width <<= p->fontwidthlog+2;
+ } else {
+ sx *= p->fontwidth*4;
+ dx *= p->fontwidth*4;
+ width *= p->fontwidth*4;
+ }
+ if (dy < sy || (dy == sy && dx < sx)) {
+ src = p->screen_base + sy * linesize + sx;
+ dst = p->screen_base + dy * linesize + dx;
+ for (rows = height * p->fontheight; rows--;) {
+ mymemmove(dst, src, width);
src += bytes;
dst += bytes;
}
} else {
- src = p->screen_base + (sy+height) * linesize + sx * 32 - bytes;
- dst = p->screen_base + (dy+height) * linesize + dx * 32 - bytes;
- for (rows = height * p->fontheight ; rows-- ;) {
- mymemmove(dst, src, width * 32);
+ src = p->screen_base + (sy+height) * linesize + sx - bytes;
+ dst = p->screen_base + (dy+height) * linesize + dx - bytes;
+ for (rows = height * p->fontheight; rows--;) {
+ mymemmove(dst, src, width);
src -= bytes;
dst -= bytes;
}
@@ -67,36 +79,29 @@ void fbcon_cfb32_clear(struct vc_data *conp, struct display *p, int sy, int sx,
int bytes = p->next_line, lines = height * p->fontheight, rows, i;
u32 bgx;
- dest = p->screen_base + sy * p->fontheight * bytes + sx * 32;
+ dest = p->screen_base + sy * p->fontheight * bytes + sx * p->fontwidth * 4;
bgx = fbcon_cfb32_cmap[attr_bgcol_ec(p, conp)];
- if (sx == 0 && width * 32 == bytes)
- for (i = 0 ; i < lines * width ; i++) {
+ width *= p->fontwidth/4;
+ if (sx == 0 && width * 16 == bytes)
+ for (i = 0; i < lines * width; i++) {
((u32 *)dest)[0] = bgx;
((u32 *)dest)[1] = bgx;
((u32 *)dest)[2] = bgx;
((u32 *)dest)[3] = bgx;
- ((u32 *)dest)[4] = bgx;
- ((u32 *)dest)[5] = bgx;
- ((u32 *)dest)[6] = bgx;
- ((u32 *)dest)[7] = bgx;
- dest += 32;
+ dest += 16;
}
else {
dest0 = dest;
- for (rows = lines; rows-- ; dest0 += bytes) {
+ for (rows = lines; rows--; dest0 += bytes) {
dest = dest0;
- for (i = 0 ; i < width ; i++) {
+ for (i = 0; i < width; i++) {
((u32 *)dest)[0] = bgx;
((u32 *)dest)[1] = bgx;
((u32 *)dest)[2] = bgx;
((u32 *)dest)[3] = bgx;
- ((u32 *)dest)[4] = bgx;
- ((u32 *)dest)[5] = bgx;
- ((u32 *)dest)[6] = bgx;
- ((u32 *)dest)[7] = bgx;
- dest += 32;
+ dest += 16;
}
}
}
@@ -105,59 +110,108 @@ void fbcon_cfb32_clear(struct vc_data *conp, struct display *p, int sy, int sx,
void fbcon_cfb32_putc(struct vc_data *conp, struct display *p, int c, int yy,
int xx)
{
- u8 *dest, *cdat;
+ u8 *dest, *cdat, bits;
int bytes = p->next_line, rows;
u32 eorx, fgx, bgx;
- c &= 0xff;
-
- dest = p->screen_base + yy * p->fontheight * bytes + xx * 32;
- cdat = p->fontdata + c * p->fontheight;
-
- fgx = fbcon_cfb32_cmap[attr_fgcol(p, conp)];
- bgx = fbcon_cfb32_cmap[attr_bgcol(p, conp)];
+ dest = p->screen_base + yy * p->fontheight * bytes + xx * p->fontwidth * 4;
+#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
+ cdat = p->fontdata + (c & p->charmask) * p->fontheight;
+#else
+ if (p->fontwidth <= 8)
+ cdat = p->fontdata + (c & p->charmask) * p->fontheight;
+ else
+ cdat = p->fontdata + ((c & p->charmask) * p->fontheight << 1);
+#endif
+ fgx = fbcon_cfb32_cmap[attr_fgcol(p, c)];
+ bgx = fbcon_cfb32_cmap[attr_bgcol(p, c)];
eorx = fgx ^ bgx;
- for (rows = p->fontheight ; rows-- ; dest += bytes) {
- u8 bits = *cdat++;
+ for (rows = p->fontheight; rows--; dest += bytes) {
+ bits = *cdat++;
((u32 *)dest)[0] = (-(bits >> 7) & eorx) ^ bgx;
((u32 *)dest)[1] = (-(bits >> 6 & 1) & eorx) ^ bgx;
((u32 *)dest)[2] = (-(bits >> 5 & 1) & eorx) ^ bgx;
((u32 *)dest)[3] = (-(bits >> 4 & 1) & eorx) ^ bgx;
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (p->fontwidth < 8)
+ continue;
+#endif
((u32 *)dest)[4] = (-(bits >> 3 & 1) & eorx) ^ bgx;
((u32 *)dest)[5] = (-(bits >> 2 & 1) & eorx) ^ bgx;
((u32 *)dest)[6] = (-(bits >> 1 & 1) & eorx) ^ bgx;
((u32 *)dest)[7] = (-(bits & 1) & eorx) ^ bgx;
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (p->fontwidth < 12)
+ continue;
+ bits = *cdat++;
+ ((u32 *)dest)[8] = (-(bits >> 7) & eorx) ^ bgx;
+ ((u32 *)dest)[9] = (-(bits >> 6 & 1) & eorx) ^ bgx;
+ ((u32 *)dest)[10] = (-(bits >> 5 & 1) & eorx) ^ bgx;
+ ((u32 *)dest)[11] = (-(bits >> 4 & 1) & eorx) ^ bgx;
+ if (p->fontwidth < 16)
+ continue;
+ ((u32 *)dest)[12] = (-(bits >> 3 & 1) & eorx) ^ bgx;
+ ((u32 *)dest)[13] = (-(bits >> 2 & 1) & eorx) ^ bgx;
+ ((u32 *)dest)[14] = (-(bits >> 1 & 1) & eorx) ^ bgx;
+ ((u32 *)dest)[15] = (-(bits & 1) & eorx) ^ bgx;
+#endif
}
}
-void fbcon_cfb32_putcs(struct vc_data *conp, struct display *p, const char *s,
- int count, int yy, int xx)
+void fbcon_cfb32_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int yy, int xx)
{
- u8 *cdat, c, *dest, *dest0;
+ u8 *cdat, *dest, *dest0, bits;
+ u16 c;
int rows, bytes = p->next_line;
u32 eorx, fgx, bgx;
- dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 32;
- fgx = fbcon_cfb32_cmap[attr_fgcol(p, conp)];
- bgx = fbcon_cfb32_cmap[attr_bgcol(p, conp)];
+ dest0 = p->screen_base + yy * p->fontheight * bytes + xx * p->fontwidth * 4;
+ fgx = fbcon_cfb32_cmap[attr_fgcol(p, *s)];
+ bgx = fbcon_cfb32_cmap[attr_bgcol(p, *s)];
eorx = fgx ^ bgx;
while (count--) {
- c = *s++;
+ c = *s++ & p->charmask;
+#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
cdat = p->fontdata + c * p->fontheight;
-
- for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
- u8 bits = *cdat++;
+#else
+ if (p->fontwidth <= 8)
+ cdat = p->fontdata + c * p->fontheight;
+ else
+ cdat = p->fontdata + (c * p->fontheight << 1);
+#endif
+ for (rows = p->fontheight, dest = dest0; rows--; dest += bytes) {
+ bits = *cdat++;
((u32 *)dest)[0] = (-(bits >> 7) & eorx) ^ bgx;
((u32 *)dest)[1] = (-(bits >> 6 & 1) & eorx) ^ bgx;
((u32 *)dest)[2] = (-(bits >> 5 & 1) & eorx) ^ bgx;
((u32 *)dest)[3] = (-(bits >> 4 & 1) & eorx) ^ bgx;
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (p->fontwidth < 8)
+ continue;
+#endif
((u32 *)dest)[4] = (-(bits >> 3 & 1) & eorx) ^ bgx;
((u32 *)dest)[5] = (-(bits >> 2 & 1) & eorx) ^ bgx;
((u32 *)dest)[6] = (-(bits >> 1 & 1) & eorx) ^ bgx;
((u32 *)dest)[7] = (-(bits & 1) & eorx) ^ bgx;
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (p->fontwidth < 12)
+ continue;
+ bits = *cdat++;
+ ((u32 *)dest)[8] = (-(bits >> 7) & eorx) ^ bgx;
+ ((u32 *)dest)[9] = (-(bits >> 6 & 1) & eorx) ^ bgx;
+ ((u32 *)dest)[10] = (-(bits >> 5 & 1) & eorx) ^ bgx;
+ ((u32 *)dest)[11] = (-(bits >> 4 & 1) & eorx) ^ bgx;
+ if (p->fontwidth < 16)
+ continue;
+ ((u32 *)dest)[12] = (-(bits >> 3 & 1) & eorx) ^ bgx;
+ ((u32 *)dest)[13] = (-(bits >> 2 & 1) & eorx) ^ bgx;
+ ((u32 *)dest)[14] = (-(bits >> 1 & 1) & eorx) ^ bgx;
+ ((u32 *)dest)[15] = (-(bits & 1) & eorx) ^ bgx;
+#endif
}
- dest0 += 32;
+ dest0 += p->fontwidth*4;
}
}
@@ -166,16 +220,61 @@ void fbcon_cfb32_revc(struct display *p, int xx, int yy)
u8 *dest;
int bytes = p->next_line, rows;
- dest = p->screen_base + yy * p->fontheight * bytes + xx * 32;
- for (rows = p->fontheight ; rows-- ; dest += bytes) {
- ((u32 *)dest)[0] ^= 0xffffffff;
- ((u32 *)dest)[1] ^= 0xffffffff;
- ((u32 *)dest)[2] ^= 0xffffffff;
- ((u32 *)dest)[3] ^= 0xffffffff;
- ((u32 *)dest)[4] ^= 0xffffffff;
- ((u32 *)dest)[5] ^= 0xffffffff;
- ((u32 *)dest)[6] ^= 0xffffffff;
- ((u32 *)dest)[7] ^= 0xffffffff;
+ dest = p->screen_base + yy * p->fontheight * bytes + xx * p->fontwidth * 4;
+ for (rows = p->fontheight; rows--; dest += bytes) {
+#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
+ ((u32 *)dest)[4] ^= 0xffffffff; ((u32 *)dest)[5] ^= 0xffffffff;
+ ((u32 *)dest)[6] ^= 0xffffffff; ((u32 *)dest)[7] ^= 0xffffffff;
+ ((u32 *)dest)[0] ^= 0xffffffff; ((u32 *)dest)[1] ^= 0xffffffff;
+ ((u32 *)dest)[2] ^= 0xffffffff; ((u32 *)dest)[3] ^= 0xffffffff;
+#else
+ switch (p->fontwidth) {
+ case 16:
+ ((u32 *)dest)[12] ^= 0xffffffff; ((u32 *)dest)[13] ^= 0xffffffff;
+ ((u32 *)dest)[14] ^= 0xffffffff; ((u32 *)dest)[15] ^= 0xffffffff;
+ /* FALL THROUGH */
+ case 12:
+ ((u32 *)dest)[8] ^= 0xffffffff; ((u32 *)dest)[9] ^= 0xffffffff;
+ ((u32 *)dest)[10] ^= 0xffffffff; ((u32 *)dest)[11] ^= 0xffffffff;
+ /* FALL THROUGH */
+ case 8:
+ ((u32 *)dest)[4] ^= 0xffffffff; ((u32 *)dest)[5] ^= 0xffffffff;
+ ((u32 *)dest)[6] ^= 0xffffffff; ((u32 *)dest)[7] ^= 0xffffffff;
+ /* FALL THROUGH */
+ case 4:
+ ((u32 *)dest)[0] ^= 0xffffffff; ((u32 *)dest)[1] ^= 0xffffffff;
+ ((u32 *)dest)[2] ^= 0xffffffff; ((u32 *)dest)[3] ^= 0xffffffff;
+ /* FALL THROUGH */
+ }
+#endif
+ }
+}
+
+void fbcon_cfb32_clear_margins(struct vc_data *conp, struct display *p)
+{
+ u8 *dest0;
+ u32 *dest;
+ int bytes = p->next_line;
+ u32 bgx;
+ int i, j;
+
+ unsigned int right_start = conp->vc_cols*p->fontwidth;
+ unsigned int right_width = p->var.xres_virtual-right_start;
+ unsigned int bottom_start = conp->vc_rows*p->fontheight;
+ unsigned int bottom_width = p->var.yres_virtual-bottom_start;
+
+ bgx = fbcon_cfb32_cmap[attr_bgcol_ec(p, conp)];
+
+ if (right_width) {
+ dest0 = p->screen_base+right_start*4;
+ for (i = 0; i < bottom_start; i++, dest0 += bytes)
+ for (j = 0, dest = (u32 *)dest0; j < right_width; j++)
+ *dest++ = bgx;
+ }
+ if (bottom_width) {
+ dest = (u32 *)(p->screen_base+bottom_start*bytes);
+ for (i = 0; i < bytes*bottom_width/4; i++)
+ *dest++ = bgx;
}
}
@@ -186,10 +285,22 @@ void fbcon_cfb32_revc(struct display *p, int xx, int yy)
struct display_switch fbcon_cfb32 = {
fbcon_cfb32_setup, fbcon_cfb32_bmove, fbcon_cfb32_clear, fbcon_cfb32_putc,
- fbcon_cfb32_putcs, fbcon_cfb32_revc
+ fbcon_cfb32_putcs, fbcon_cfb32_revc, NULL, NULL, fbcon_cfb32_clear_margins,
+ FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
};
+#ifdef MODULE
+int init_module(void)
+{
+ return 0;
+}
+
+void cleanup_module(void)
+{}
+#endif /* MODULE */
+
+
/*
* Visible symbols for modules
*/
diff --git a/drivers/video/fbcon-cfb32.h b/drivers/video/fbcon-cfb32.h
index 1f74141c2..500528b04 100644
--- a/drivers/video/fbcon-cfb32.h
+++ b/drivers/video/fbcon-cfb32.h
@@ -2,6 +2,18 @@
* 32 bpp packed pixel (cfb32)
*/
+#include <linux/config.h>
+
+#ifdef MODULE
+#if defined(CONFIG_FBCON_CFB32) || defined(CONFIG_FBCON_CFB32_MODULE)
+#define FBCON_HAS_CFB32
+#endif
+#else
+#if defined(CONFIG_FBCON_CFB32)
+#define FBCON_HAS_CFB32
+#endif
+#endif
+
extern struct display_switch fbcon_cfb32;
extern u32 fbcon_cfb32_cmap[16];
extern void fbcon_cfb32_setup(struct display *p);
@@ -12,5 +24,6 @@ extern void fbcon_cfb32_clear(struct vc_data *conp, struct display *p, int sy,
extern void fbcon_cfb32_putc(struct vc_data *conp, struct display *p, int c,
int yy, int xx);
extern void fbcon_cfb32_putcs(struct vc_data *conp, struct display *p,
- const char *s, int count, int yy, int xx);
+ const unsigned short *s, int count, int yy, int xx);
extern void fbcon_cfb32_revc(struct display *p, int xx, int yy);
+extern void fbcon_cfb32_clear_margins(struct vc_data *conp, struct display *p);
diff --git a/drivers/video/fbcon-cfb4.c b/drivers/video/fbcon-cfb4.c
index 8df065695..4d3f196bf 100644
--- a/drivers/video/fbcon-cfb4.c
+++ b/drivers/video/fbcon-cfb4.c
@@ -32,10 +32,20 @@
*/
static u16 nibbletab_cfb4[] = {
+#if defined(__BIG_ENDIAN)
0x0000,0x000f,0x00f0,0x00ff,
0x0f00,0x0f0f,0x0ff0,0x0fff,
0xf000,0xf00f,0xf0f0,0xf0ff,
0xff00,0xff0f,0xfff0,0xffff
+#elif defined(__LITTLE_ENDIAN)
+ 0x0000,0xf000,0x0f00,0xff00,
+ 0x00f0,0xf0f0,0x0ff0,0xfff0,
+ 0x000f,0xf00f,0x0f0f,0xff0f,
+ 0x00ff,0xf0ff,0x0fff,0xffff
+#else
+#error FIXME: No endianness??
+#endif
+
};
void fbcon_cfb4_setup(struct display *p)
@@ -120,13 +130,11 @@ void fbcon_cfb4_putc(struct vc_data *conp, struct display *p, int c, int yy,
int bytes=p->next_line,rows;
u32 eorx,fgx,bgx;
- c &= 0xff;
-
dest = p->screen_base + yy * p->fontheight * bytes + xx * 4;
- cdat = p->fontdata + c * p->fontheight;
+ cdat = p->fontdata + (c & p->charmask) * p->fontheight;
- fgx=15;/*attr_fgcol(p,conp)&0x0F;*/
- bgx=attr_bgcol(p,conp)&0x0F;
+ fgx=15;/*attr_fgcol(p,c);*/
+ bgx=attr_bgcol(p,c);
fgx |= (fgx << 4);
fgx |= (fgx << 8);
bgx |= (bgx << 4);
@@ -141,16 +149,17 @@ void fbcon_cfb4_putc(struct vc_data *conp, struct display *p, int c, int yy,
}
}
-void fbcon_cfb4_putcs(struct vc_data *conp, struct display *p, const char *s,
- int count, int yy, int xx)
+void fbcon_cfb4_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int yy, int xx)
{
- u8 *cdat, c, *dest, *dest0;
+ u8 *cdat, *dest, *dest0;
+ u16 c;
int rows,bytes=p->next_line;
u32 eorx, fgx, bgx;
dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 4;
- fgx=15/*attr_fgcol(p,conp)*/;
- bgx=attr_bgcol(p,conp);
+ fgx=15/*attr_fgcol(p,*s)*/;
+ bgx=attr_bgcol(p,*s);
fgx |= (fgx << 4);
fgx |= (fgx << 8);
fgx |= (fgx << 16);
@@ -159,7 +168,7 @@ void fbcon_cfb4_putcs(struct vc_data *conp, struct display *p, const char *s,
bgx |= (bgx << 16);
eorx = fgx ^ bgx;
while (count--) {
- c = *s++;
+ c = *s++ & p->charmask;
cdat = p->fontdata + c * p->fontheight;
for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
@@ -190,10 +199,21 @@ void fbcon_cfb4_revc(struct display *p, int xx, int yy)
struct display_switch fbcon_cfb4 = {
fbcon_cfb4_setup, fbcon_cfb4_bmove, fbcon_cfb4_clear, fbcon_cfb4_putc,
- fbcon_cfb4_putcs, fbcon_cfb4_revc
+ fbcon_cfb4_putcs, fbcon_cfb4_revc, NULL, NULL, NULL, FONTWIDTH(8)
};
+#ifdef MODULE
+int init_module(void)
+{
+ return 0;
+}
+
+void cleanup_module(void)
+{}
+#endif /* MODULE */
+
+
/*
* Visible symbols for modules
*/
diff --git a/drivers/video/fbcon-cfb4.h b/drivers/video/fbcon-cfb4.h
index 6fe3bc5a4..df08288cd 100644
--- a/drivers/video/fbcon-cfb4.h
+++ b/drivers/video/fbcon-cfb4.h
@@ -2,6 +2,18 @@
* 4 bpp packed pixel (cfb4)
*/
+#include <linux/config.h>
+
+#ifdef MODULE
+#if defined(CONFIG_FBCON_CFB4) || defined(CONFIG_FBCON_CFB4_MODULE)
+#define FBCON_HAS_CFB4
+#endif
+#else
+#if defined(CONFIG_FBCON_CFB4)
+#define FBCON_HAS_CFB4
+#endif
+#endif
+
extern struct display_switch fbcon_cfb4;
extern void fbcon_cfb4_setup(struct display *p);
extern void fbcon_cfb4_bmove(struct display *p, int sy, int sx, int dy, int dx,
@@ -11,5 +23,5 @@ extern void fbcon_cfb4_clear(struct vc_data *conp, struct display *p, int sy,
extern void fbcon_cfb4_putc(struct vc_data *conp, struct display *p, int c,
int yy, int xx);
extern void fbcon_cfb4_putcs(struct vc_data *conp, struct display *p,
- const char *s, int count, int yy, int xx);
+ const unsigned short *s, int count, int yy, int xx);
extern void fbcon_cfb4_revc(struct display *p, int xx, int yy);
diff --git a/drivers/video/fbcon-cfb8.c b/drivers/video/fbcon-cfb8.c
index dcd3ebd97..b4de49b3b 100644
--- a/drivers/video/fbcon-cfb8.c
+++ b/drivers/video/fbcon-cfb8.c
@@ -9,6 +9,7 @@
* more details.
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/console.h>
@@ -41,7 +42,7 @@ static u32 nibbletab_cfb8[] = {
void fbcon_cfb8_setup(struct display *p)
{
- p->next_line = p->var.xres_virtual;
+ p->next_line = p->line_length ? p->line_length : p->var.xres_virtual;
p->next_plane = 0;
}
@@ -51,23 +52,30 @@ void fbcon_cfb8_bmove(struct display *p, int sy, int sx, int dy, int dx,
int bytes = p->next_line, linesize = bytes * p->fontheight, rows;
u8 *src,*dst;
- if (sx == 0 && dx == 0 && width * 8 == bytes)
+ if (sx == 0 && dx == 0 && width * p->fontwidth == bytes) {
mymemmove(p->screen_base + dy * linesize,
p->screen_base + sy * linesize,
height * linesize);
- else if (dy < sy || (dy == sy && dx < sx)) {
- src = p->screen_base + sy * linesize + sx * 8;
- dst = p->screen_base + dy * linesize + dx * 8;
+ return;
+ }
+ if (p->fontwidthlog) {
+ sx <<= p->fontwidthlog; dx <<= p->fontwidthlog; width <<= p->fontwidthlog;
+ } else {
+ sx *= p->fontwidth; dx *= p->fontwidth; width *= p->fontwidth;
+ }
+ if (dy < sy || (dy == sy && dx < sx)) {
+ src = p->screen_base + sy * linesize + sx;
+ dst = p->screen_base + dy * linesize + dx;
for (rows = height * p->fontheight ; rows-- ;) {
- mymemmove(dst, src, width * 8);
+ mymemmove(dst, src, width);
src += bytes;
dst += bytes;
}
} else {
- src = p->screen_base + (sy+height) * linesize + sx * 8 - bytes;
- dst = p->screen_base + (dy+height) * linesize + dx * 8 - bytes;
+ src = p->screen_base + (sy+height) * linesize + sx - bytes;
+ dst = p->screen_base + (dy+height) * linesize + dx - bytes;
for (rows = height * p->fontheight ; rows-- ;) {
- mymemmove(dst, src, width * 8);
+ mymemmove(dst, src, width);
src -= bytes;
dst -= bytes;
}
@@ -77,32 +85,20 @@ void fbcon_cfb8_bmove(struct display *p, int sy, int sx, int dy, int dx,
void fbcon_cfb8_clear(struct vc_data *conp, struct display *p, int sy, int sx,
int height, int width)
{
- u8 *dest0,*dest;
- int bytes=p->next_line,lines=height * p->fontheight, rows, i;
- u32 bgx;
+ u8 *dest;
+ int bytes=p->next_line,lines=height * p->fontheight, rows;
+ u8 bgx;
- dest = p->screen_base + sy * p->fontheight * bytes + sx * 8;
+ dest = p->screen_base + sy * p->fontheight * bytes + sx * p->fontwidth;
bgx=attr_bgcol_ec(p,conp);
- bgx |= (bgx << 8);
- bgx |= (bgx << 16);
- if (sx == 0 && width * 8 == bytes)
- for (i = 0 ; i < lines * width ; i++) {
- ((u32 *)dest)[0]=bgx;
- ((u32 *)dest)[1]=bgx;
- dest+=8;
- }
+ if (sx == 0 && p->fontwidth == 8 && width * 8 == bytes)
+ memset(dest, bgx, lines * width * p->fontwidth);
else {
- dest0=dest;
- for (rows = lines; rows-- ; dest0 += bytes) {
- dest=dest0;
- for (i = 0 ; i < width ; i++) {
- ((u32 *)dest)[0]=bgx;
- ((u32 *)dest)[1]=bgx;
- dest+=8;
- }
- }
+ width *= p->fontwidth;
+ for (rows = lines; rows-- ; dest += bytes)
+ memset(dest, bgx, width);
}
}
@@ -113,50 +109,110 @@ void fbcon_cfb8_putc(struct vc_data *conp, struct display *p, int c, int yy,
int bytes=p->next_line,rows;
u32 eorx,fgx,bgx;
- c &= 0xff;
-
- dest = p->screen_base + yy * p->fontheight * bytes + xx * 8;
- cdat = p->fontdata + c * p->fontheight;
+ dest = p->screen_base + yy * p->fontheight * bytes + xx * p->fontwidth;
+ if (p->fontwidth <= 8)
+ cdat = p->fontdata + (c & p->charmask) * p->fontheight;
+ else
+ cdat = p->fontdata + ((c & p->charmask) * p->fontheight << 1);
- fgx=attr_fgcol(p,conp);
- bgx=attr_bgcol(p,conp);
+ fgx=attr_fgcol(p,c);
+ bgx=attr_bgcol(p,c);
fgx |= (fgx << 8);
fgx |= (fgx << 16);
bgx |= (bgx << 8);
bgx |= (bgx << 16);
eorx = fgx ^ bgx;
- for (rows = p->fontheight ; rows-- ; dest += bytes) {
- ((u32 *)dest)[0]= (nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx;
- ((u32 *)dest)[1]= (nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx;
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ switch (p->fontwidth) {
+ case 4:
+ for (rows = p->fontheight ; rows-- ; dest += bytes)
+ ((u32 *)dest)[0]= (nibbletab_cfb8[*cdat++ >> 4] & eorx) ^ bgx;
+ break;
+ case 8:
+#endif
+ for (rows = p->fontheight ; rows-- ; dest += bytes) {
+ ((u32 *)dest)[0]= (nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx;
+ ((u32 *)dest)[1]= (nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx;
+ }
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ break;
+ case 12:
+ case 16:
+ for (rows = p->fontheight ; rows-- ; dest += bytes) {
+ ((u32 *)dest)[0]= (nibbletab_cfb8[*(u16 *)cdat >> 12] & eorx) ^ bgx;
+ ((u32 *)dest)[1]= (nibbletab_cfb8[(*(u16 *)cdat >> 8) & 0xf] & eorx) ^ bgx;
+ ((u32 *)dest)[2]= (nibbletab_cfb8[(*(u16 *)cdat >> 4) & 0xf] & eorx) ^ bgx;
+ if (p->fontwidth == 16)
+ ((u32 *)dest)[3]= (nibbletab_cfb8[*cdat & 0xf] & eorx) ^ bgx;
+ cdat += 2;
+ }
+ break;
}
+#endif
}
-void fbcon_cfb8_putcs(struct vc_data *conp, struct display *p, const char *s,
- int count, int yy, int xx)
+void fbcon_cfb8_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int yy, int xx)
{
- u8 *cdat, c, *dest, *dest0;
+ u8 *cdat, *dest, *dest0;
+ u16 c;
int rows,bytes=p->next_line;
u32 eorx, fgx, bgx;
- dest0 = p->screen_base + yy * p->fontheight * bytes + xx * 8;
- fgx=attr_fgcol(p,conp);
- bgx=attr_bgcol(p,conp);
+ dest0 = p->screen_base + yy * p->fontheight * bytes + xx * p->fontwidth;
+ fgx=attr_fgcol(p,*s);
+ bgx=attr_bgcol(p,*s);
fgx |= (fgx << 8);
fgx |= (fgx << 16);
bgx |= (bgx << 8);
bgx |= (bgx << 16);
eorx = fgx ^ bgx;
- while (count--) {
- c = *s++;
- cdat = p->fontdata + c * p->fontheight;
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ switch (p->fontwidth) {
+ case 4:
+ while (count--) {
+ c = *s++ & p->charmask;
+ cdat = p->fontdata + c * p->fontheight;
- for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
- ((u32 *)dest)[0]= (nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx;
- ((u32 *)dest)[1]= (nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx;
- }
- dest0+=8;
+ for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes)
+ ((u32 *)dest)[0]= (nibbletab_cfb8[*cdat++ >> 4] & eorx) ^ bgx;
+ dest0+=4;
+ }
+ break;
+ case 8:
+#endif
+ while (count--) {
+ c = *s++ & p->charmask;
+ cdat = p->fontdata + c * p->fontheight;
+
+ for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+ ((u32 *)dest)[0]= (nibbletab_cfb8[*cdat >> 4] & eorx) ^ bgx;
+ ((u32 *)dest)[1]= (nibbletab_cfb8[*cdat++ & 0xf] & eorx) ^ bgx;
+ }
+ dest0+=8;
+ }
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ break;
+ case 12:
+ case 16:
+ while (count--) {
+ c = *s++ & p->charmask;
+ cdat = p->fontdata + (c * p->fontheight << 1);
+
+ for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
+ ((u32 *)dest)[0]= (nibbletab_cfb8[*(u16 *)cdat >> 12] & eorx) ^ bgx;
+ ((u32 *)dest)[1]= (nibbletab_cfb8[(*(u16 *)cdat >> 8) & 0xf] & eorx) ^ bgx;
+ ((u32 *)dest)[2]= (nibbletab_cfb8[(*(u16 *)cdat >> 4) & 0xf] & eorx) ^ bgx;
+ if (p->fontwidth == 16)
+ ((u32 *)dest)[3]= (nibbletab_cfb8[*cdat & 0xf] & eorx) ^ bgx;
+ cdat += 2;
+ }
+ dest0+=p->fontwidth;
+ }
+ break;
}
+#endif
}
void fbcon_cfb8_revc(struct display *p, int xx, int yy)
@@ -164,11 +220,44 @@ void fbcon_cfb8_revc(struct display *p, int xx, int yy)
u8 *dest;
int bytes=p->next_line, rows;
- dest = p->screen_base + yy * p->fontheight * bytes + xx * 8;
+ dest = p->screen_base + yy * p->fontheight * bytes + xx * p->fontwidth;
for (rows = p->fontheight ; rows-- ; dest += bytes) {
- ((u32 *)dest)[0] ^= 0x0f0f0f0f;
- ((u32 *)dest)[1] ^= 0x0f0f0f0f;
+#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
+ ((u32 *)dest)[1] ^= 0x0f0f0f0f;
+ ((u32 *)dest)[0] ^= 0x0f0f0f0f;
+#else
+ switch (p->fontwidth) {
+ case 16: ((u32 *)dest)[3] ^= 0x0f0f0f0f; /* FALL THROUGH */
+ case 12: ((u32 *)dest)[2] ^= 0x0f0f0f0f; /* FALL THROUGH */
+ case 8: ((u32 *)dest)[1] ^= 0x0f0f0f0f; /* FALL THROUGH */
+ case 4: ((u32 *)dest)[0] ^= 0x0f0f0f0f; /* FALL THROUGH */
+ default: break;
+ }
+#endif
+ }
+}
+
+void fbcon_cfb8_clear_margins(struct vc_data *conp, struct display *p)
+{
+ u8 *dest;
+ int bytes=p->next_line;
+ u8 bgx;
+ int i;
+
+ unsigned int right_start = conp->vc_cols*p->fontwidth;
+ unsigned int right_width = p->var.xres_virtual-right_start;
+ unsigned int bottom_start = conp->vc_rows*p->fontheight;
+ unsigned int bottom_width = p->var.yres_virtual-bottom_start;
+
+ bgx=attr_bgcol_ec(p,conp);
+
+ if (right_width) {
+ dest = p->screen_base+right_start;
+ for (i = 0; i < bottom_start; i++, dest += bytes)
+ memset(dest, bgx, right_width);
}
+ if (bottom_width)
+ memset(p->screen_base+bottom_start*bytes, bgx, bytes*bottom_width);
}
@@ -178,10 +267,22 @@ void fbcon_cfb8_revc(struct display *p, int xx, int yy)
struct display_switch fbcon_cfb8 = {
fbcon_cfb8_setup, fbcon_cfb8_bmove, fbcon_cfb8_clear, fbcon_cfb8_putc,
- fbcon_cfb8_putcs, fbcon_cfb8_revc
+ fbcon_cfb8_putcs, fbcon_cfb8_revc, NULL, NULL, fbcon_cfb8_clear_margins,
+ FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
};
+#ifdef MODULE
+int init_module(void)
+{
+ return 0;
+}
+
+void cleanup_module(void)
+{}
+#endif /* MODULE */
+
+
/*
* Visible symbols for modules
*/
diff --git a/drivers/video/fbcon-cfb8.h b/drivers/video/fbcon-cfb8.h
index 4c0ffec99..e1d8170ed 100644
--- a/drivers/video/fbcon-cfb8.h
+++ b/drivers/video/fbcon-cfb8.h
@@ -2,6 +2,18 @@
* 8 bpp packed pixel (cfb8)
*/
+#include <linux/config.h>
+
+#ifdef MODULE
+#if defined(CONFIG_FBCON_CFB8) || defined(CONFIG_FBCON_CFB8_MODULE)
+#define FBCON_HAS_CFB8
+#endif
+#else
+#if defined(CONFIG_FBCON_CFB8)
+#define FBCON_HAS_CFB8
+#endif
+#endif
+
extern struct display_switch fbcon_cfb8;
extern void fbcon_cfb8_setup(struct display *p);
extern void fbcon_cfb8_bmove(struct display *p, int sy, int sx, int dy, int dx,
@@ -11,5 +23,6 @@ extern void fbcon_cfb8_clear(struct vc_data *conp, struct display *p, int sy,
extern void fbcon_cfb8_putc(struct vc_data *conp, struct display *p, int c,
int yy, int xx);
extern void fbcon_cfb8_putcs(struct vc_data *conp, struct display *p,
- const char *s, int count, int yy, int xx);
+ const unsigned short *s, int count, int yy, int xx);
extern void fbcon_cfb8_revc(struct display *p, int xx, int yy);
+extern void fbcon_cfb8_clear_margins(struct vc_data *conp, struct display *p);
diff --git a/drivers/video/fbcon-ilbm.c b/drivers/video/fbcon-ilbm.c
index 82f9982f6..b87a1d10c 100644
--- a/drivers/video/fbcon-ilbm.c
+++ b/drivers/video/fbcon-ilbm.c
@@ -102,12 +102,10 @@ void fbcon_ilbm_putc(struct vc_data *conp, struct display *p, int c, int yy,
u8 d;
int fg0, bg0, fg, bg;
- c &= 0xff;
-
dest = p->screen_base+yy*p->fontheight*p->next_line+xx;
- cdat = p->fontdata+c*p->fontheight;
- fg0 = attr_fgcol(p,conp);
- bg0 = attr_bgcol(p,conp);
+ cdat = p->fontdata+(c&p->charmask)*p->fontheight;
+ fg0 = attr_fgcol(p,c);
+ bg0 = attr_bgcol(p,c);
for (rows = p->fontheight; rows--;) {
d = *cdat++;
@@ -146,22 +144,22 @@ void fbcon_ilbm_putc(struct vc_data *conp, struct display *p, int c, int yy,
* -- Geert
*/
-void fbcon_ilbm_putcs(struct vc_data *conp, struct display *p, const char *s,
- int count, int yy, int xx)
+void fbcon_ilbm_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int yy, int xx)
{
u8 *dest0, *dest, *cdat1, *cdat2, *cdat3, *cdat4;
u_int rows, i;
- u8 c1, c2, c3, c4;
+ u16 c1, c2, c3, c4;
u32 d;
int fg0, bg0, fg, bg;
dest0 = p->screen_base+yy*p->fontheight*p->next_line+xx;
- fg0 = attr_fgcol(p,conp);
- bg0 = attr_bgcol(p,conp);
+ fg0 = attr_fgcol(p,*s);
+ bg0 = attr_bgcol(p,*s);
while (count--)
if (xx&3 || count < 3) { /* Slow version */
- c1 = *s++;
+ c1 = *s++ & p->charmask;
dest = dest0++;
xx++;
@@ -187,10 +185,10 @@ void fbcon_ilbm_putcs(struct vc_data *conp, struct display *p, const char *s,
}
}
} else { /* Fast version */
- c1 = s[0];
- c2 = s[1];
- c3 = s[2];
- c4 = s[3];
+ c1 = s[0] & p->charmask;
+ c2 = s[1] & p->charmask;
+ c3 = s[2] & p->charmask;
+ c4 = s[3] & p->charmask;
dest = dest0;
cdat1 = p->fontdata+c1*p->fontheight;
@@ -201,7 +199,7 @@ void fbcon_ilbm_putcs(struct vc_data *conp, struct display *p, const char *s,
#if defined(__BIG_ENDIAN)
d = *cdat1++<<24 | *cdat2++<<16 | *cdat3++<<8 | *cdat4++;
#elif defined(__LITTLE_ENDIAN)
- d = *cdat1++ | *cdat2++<<8 | *cdat3++<<16 | *cdat4++<<32);
+ d = *cdat1++ | *cdat2++<<8 | *cdat3++<<16 | *cdat4++<<24;
#else
#error FIXME: No endianness??
#endif
@@ -262,10 +260,21 @@ void fbcon_ilbm_revc(struct display *p, int xx, int yy)
struct display_switch fbcon_ilbm = {
fbcon_ilbm_setup, fbcon_ilbm_bmove, fbcon_ilbm_clear, fbcon_ilbm_putc,
- fbcon_ilbm_putcs, fbcon_ilbm_revc
+ fbcon_ilbm_putcs, fbcon_ilbm_revc, NULL, NULL, NULL, FONTWIDTH(8)
};
+#ifdef MODULE
+int init_module(void)
+{
+ return 0;
+}
+
+void cleanup_module(void)
+{}
+#endif /* MODULE */
+
+
/*
* Visible symbols for modules
*/
diff --git a/drivers/video/fbcon-ilbm.h b/drivers/video/fbcon-ilbm.h
index e2434c7d1..13292f287 100644
--- a/drivers/video/fbcon-ilbm.h
+++ b/drivers/video/fbcon-ilbm.h
@@ -2,6 +2,18 @@
* Amiga interleaved bitplanes (ilbm)
*/
+#include <linux/config.h>
+
+#ifdef MODULE
+#if defined(CONFIG_FBCON_ILBM) || defined(CONFIG_FBCON_ILBM_MODULE)
+#define FBCON_HAS_ILBM
+#endif
+#else
+#if defined(CONFIG_FBCON_ILBM)
+#define FBCON_HAS_ILBM
+#endif
+#endif
+
extern struct display_switch fbcon_ilbm;
extern void fbcon_ilbm_setup(struct display *p);
extern void fbcon_ilbm_bmove(struct display *p, int sy, int sx, int dy, int dx,
@@ -11,5 +23,5 @@ extern void fbcon_ilbm_clear(struct vc_data *conp, struct display *p, int sy,
extern void fbcon_ilbm_putc(struct vc_data *conp, struct display *p, int c,
int yy, int xx);
extern void fbcon_ilbm_putcs(struct vc_data *conp, struct display *p,
- const char *s, int count, int yy, int xx);
+ const unsigned short *s, int count, int yy, int xx);
extern void fbcon_ilbm_revc(struct display *p, int xx, int yy);
diff --git a/drivers/video/fbcon-iplan2p2.c b/drivers/video/fbcon-iplan2p2.c
index adef5819d..3cd8ab81e 100644
--- a/drivers/video/fbcon-iplan2p2.c
+++ b/drivers/video/fbcon-iplan2p2.c
@@ -1,7 +1,7 @@
/*
- * linux/drivers/video/iplan2p2.c -- Low level frame buffer operations for
- * interleaved bitplanes à la Atari (2
- * planes, 2 bytes interleave)
+ * linux/drivers/video/fbcon-iplan2p2.c -- Low level frame buffer operations
+ * for interleaved bitplanes à la Atari (2
+ * planes, 2 bytes interleave)
*
* Created 5 Apr 1997 by Geert Uytterhoeven
*
@@ -10,11 +10,11 @@
* more details.
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/console.h>
#include <linux/string.h>
-#include <linux/config.h>
#include <linux/fb.h>
#include <asm/byteorder.h>
@@ -52,7 +52,7 @@ static inline void movepw(u8 *d, u16 val)
}
/* Sets the bytes in the visible column at d, height h, to the value
- * val for a 2 plane screen. The the bis of the color in 'color' are
+ * val for a 2 plane screen. The bits of the color in 'color' are
* moved (8 times) to the respective bytes. This means:
*
* for(h times; d += bpr)
@@ -306,13 +306,11 @@ void fbcon_iplan2p2_putc(struct vc_data *conp, struct display *p, int c,
int bytes = p->next_line;
u16 eorx, fgx, bgx, fdx;
- c &= 0xff;
-
dest = p->screen_base + yy * p->fontheight * bytes + (xx>>1)*4 + (xx & 1);
- cdat = p->fontdata + (c * p->fontheight);
+ cdat = p->fontdata + (c & p->charmask) * p->fontheight;
- fgx = expand2w(COLOR_2P(attr_fgcol(p,conp)));
- bgx = expand2w(COLOR_2P(attr_bgcol(p,conp)));
+ fgx = expand2w(COLOR_2P(attr_fgcol(p,c)));
+ bgx = expand2w(COLOR_2P(attr_bgcol(p,c)));
eorx = fgx ^ bgx;
for (rows = p->fontheight ; rows-- ; dest += bytes) {
@@ -322,22 +320,23 @@ void fbcon_iplan2p2_putc(struct vc_data *conp, struct display *p, int c,
}
void fbcon_iplan2p2_putcs(struct vc_data *conp, struct display *p,
- const char *s, int count, int yy, int xx)
+ const unsigned short *s, int count, int yy, int xx)
{
u8 *dest, *dest0;
- u8 *cdat, c;
+ u8 *cdat;
+ u16 c;
int rows;
int bytes;
u16 eorx, fgx, bgx, fdx;
bytes = p->next_line;
dest0 = p->screen_base + yy * p->fontheight * bytes + (xx>>1)*4 + (xx & 1);
- fgx = expand2w(COLOR_2P(attr_fgcol(p,conp)));
- bgx = expand2w(COLOR_2P(attr_bgcol(p,conp)));
+ fgx = expand2w(COLOR_2P(attr_fgcol(p,*s)));
+ bgx = expand2w(COLOR_2P(attr_bgcol(p,*s)));
eorx = fgx ^ bgx;
while (count--) {
- c = *s++;
+ c = *s++ & p->charmask;
cdat = p->fontdata + (c * p->fontheight);
for (rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
@@ -376,10 +375,22 @@ void fbcon_iplan2p2_revc(struct display *p, int xx, int yy)
struct display_switch fbcon_iplan2p2 = {
fbcon_iplan2p2_setup, fbcon_iplan2p2_bmove, fbcon_iplan2p2_clear,
- fbcon_iplan2p2_putc, fbcon_iplan2p2_putcs, fbcon_iplan2p2_revc
+ fbcon_iplan2p2_putc, fbcon_iplan2p2_putcs, fbcon_iplan2p2_revc, NULL,
+ NULL, NULL, FONTWIDTH(8)
};
+#ifdef MODULE
+int init_module(void)
+{
+ return 0;
+}
+
+void cleanup_module(void)
+{}
+#endif /* MODULE */
+
+
/*
* Visible symbols for modules
*/
diff --git a/drivers/video/fbcon-iplan2p2.h b/drivers/video/fbcon-iplan2p2.h
index ae18a1b32..07b5a0d31 100644
--- a/drivers/video/fbcon-iplan2p2.h
+++ b/drivers/video/fbcon-iplan2p2.h
@@ -2,6 +2,18 @@
* Atari interleaved bitplanes (2 planes) (iplan2p2)
*/
+#include <linux/config.h>
+
+#ifdef MODULE
+#if defined(CONFIG_FBCON_IPLAN2P2) || defined(CONFIG_FBCON_IPLAN2P2_MODULE)
+#define FBCON_HAS_IPLAN2P2
+#endif
+#else
+#if defined(CONFIG_FBCON_IPLAN2P2)
+#define FBCON_HAS_IPLAN2P2
+#endif
+#endif
+
extern struct display_switch fbcon_iplan2p2;
extern void fbcon_iplan2p2_setup(struct display *p);
extern void fbcon_iplan2p2_bmove(struct display *p, int sy, int sx, int dy,
@@ -11,5 +23,5 @@ extern void fbcon_iplan2p2_clear(struct vc_data *conp, struct display *p,
extern void fbcon_iplan2p2_putc(struct vc_data *conp, struct display *p, int c,
int yy, int xx);
extern void fbcon_iplan2p2_putcs(struct vc_data *conp, struct display *p,
- const char *s, int count, int yy, int xx);
+ const unsigned short *s, int count, int yy, int xx);
extern void fbcon_iplan2p2_revc(struct display *p, int xx, int yy);
diff --git a/drivers/video/fbcon-iplan2p4.c b/drivers/video/fbcon-iplan2p4.c
index b299701c4..4bd21c366 100644
--- a/drivers/video/fbcon-iplan2p4.c
+++ b/drivers/video/fbcon-iplan2p4.c
@@ -1,7 +1,7 @@
/*
- * linux/drivers/video/iplan2p4.c -- Low level frame buffer operations for
- * interleaved bitplanes à la Atari (4
- * planes, 2 bytes interleave)
+ * linux/drivers/video/fbcon-iplan2p4.c -- Low level frame buffer operations
+ * for interleaved bitplanes à la Atari (4
+ * planes, 2 bytes interleave)
*
* Created 5 Apr 1997 by Geert Uytterhoeven
*
@@ -10,11 +10,11 @@
* more details.
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/console.h>
#include <linux/string.h>
-#include <linux/config.h>
#include <linux/fb.h>
#include <asm/byteorder.h>
@@ -46,7 +46,7 @@ static inline void movepl(u8 *d, u32 val)
}
/* Sets the bytes in the visible column at d, height h, to the value
- * val for a 4 plane screen. The the bis of the color in 'color' are
+ * val for a 4 plane screen. The bits of the color in 'color' are
* moved (8 times) to the respective bytes. This means:
*
* for(h times; d += bpr)
@@ -316,13 +316,11 @@ void fbcon_iplan2p4_putc(struct vc_data *conp, struct display *p, int c,
int bytes = p->next_line;
u32 eorx, fgx, bgx, fdx;
- c &= 0xff;
-
dest = p->screen_base + yy * p->fontheight * bytes + (xx>>1)*8 + (xx & 1);
- cdat = p->fontdata + (c * p->fontheight);
+ cdat = p->fontdata + (c & p->charmask) * p->fontheight;
- fgx = expand4l(attr_fgcol(p,conp));
- bgx = expand4l(attr_bgcol(p,conp));
+ fgx = expand4l(attr_fgcol(p,c));
+ bgx = expand4l(attr_bgcol(p,c));
eorx = fgx ^ bgx;
for(rows = p->fontheight ; rows-- ; dest += bytes) {
@@ -332,18 +330,19 @@ void fbcon_iplan2p4_putc(struct vc_data *conp, struct display *p, int c,
}
void fbcon_iplan2p4_putcs(struct vc_data *conp, struct display *p,
- const char *s, int count, int yy, int xx)
+ const unsigned short *s, int count, int yy, int xx)
{
u8 *dest, *dest0;
- u8 *cdat, c;
+ u8 *cdat;
+ u16 c;
int rows;
int bytes;
u32 eorx, fgx, bgx, fdx;
bytes = p->next_line;
dest0 = p->screen_base + yy * p->fontheight * bytes + (xx>>1)*8 + (xx & 1);
- fgx = expand4l(attr_fgcol(p,conp));
- bgx = expand4l(attr_bgcol(p,conp));
+ fgx = expand4l(attr_fgcol(p,*s));
+ bgx = expand4l(attr_bgcol(p,*s));
eorx = fgx ^ bgx;
while (count--) {
@@ -354,7 +353,7 @@ void fbcon_iplan2p4_putcs(struct vc_data *conp, struct display *p,
* cache :-(
*/
- c = *s++;
+ c = *s++ & p->charmask;
cdat = p->fontdata + (c * p->fontheight);
for(rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
@@ -396,10 +395,22 @@ void fbcon_iplan2p4_revc(struct display *p, int xx, int yy)
struct display_switch fbcon_iplan2p4 = {
fbcon_iplan2p4_setup, fbcon_iplan2p4_bmove, fbcon_iplan2p4_clear,
- fbcon_iplan2p4_putc, fbcon_iplan2p4_putcs, fbcon_iplan2p4_revc
+ fbcon_iplan2p4_putc, fbcon_iplan2p4_putcs, fbcon_iplan2p4_revc, NULL,
+ NULL, NULL, FONTWIDTH(8)
};
+#ifdef MODULE
+int init_module(void)
+{
+ return 0;
+}
+
+void cleanup_module(void)
+{}
+#endif /* MODULE */
+
+
/*
* Visible symbols for modules
*/
diff --git a/drivers/video/fbcon-iplan2p4.h b/drivers/video/fbcon-iplan2p4.h
index ae3b38494..6d501a58e 100644
--- a/drivers/video/fbcon-iplan2p4.h
+++ b/drivers/video/fbcon-iplan2p4.h
@@ -2,6 +2,18 @@
* Atari interleaved bitplanes (4 planes) (iplan2p4)
*/
+#include <linux/config.h>
+
+#ifdef MODULE
+#if defined(CONFIG_FBCON_IPLAN2P4) || defined(CONFIG_FBCON_IPLAN2P4_MODULE)
+#define FBCON_HAS_IPLAN2P4
+#endif
+#else
+#if defined(CONFIG_FBCON_IPLAN2P4)
+#define FBCON_HAS_IPLAN2P4
+#endif
+#endif
+
extern struct display_switch fbcon_iplan2p4;
extern void fbcon_iplan2p4_setup(struct display *p);
extern void fbcon_iplan2p4_bmove(struct display *p, int sy, int sx, int dy,
@@ -11,5 +23,5 @@ extern void fbcon_iplan2p4_clear(struct vc_data *conp, struct display *p,
extern void fbcon_iplan2p4_putc(struct vc_data *conp, struct display *p, int c,
int yy, int xx);
extern void fbcon_iplan2p4_putcs(struct vc_data *conp, struct display *p,
- const char *s, int count, int yy, int xx);
+ const unsigned short *s, int count, int yy, int xx);
extern void fbcon_iplan2p4_revc(struct display *p, int xx, int yy);
diff --git a/drivers/video/fbcon-iplan2p8.c b/drivers/video/fbcon-iplan2p8.c
index 5ea15c26b..aa2f4d2f1 100644
--- a/drivers/video/fbcon-iplan2p8.c
+++ b/drivers/video/fbcon-iplan2p8.c
@@ -10,11 +10,11 @@
* more details.
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/tty.h>
#include <linux/console.h>
#include <linux/string.h>
-#include <linux/config.h>
#include <linux/fb.h>
#include <asm/byteorder.h>
@@ -348,13 +348,11 @@ void fbcon_iplan2p8_putc(struct vc_data *conp, struct display *p, int c,
int bytes = p->next_line;
u32 eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx;
- c &= 0xff;
-
dest = p->screen_base + yy * p->fontheight * bytes + (xx>>1)*16 + (xx & 1);
- cdat = p->fontdata + (c * p->fontheight);
+ cdat = p->fontdata + (c & p->charmask) * p->fontheight;
- expand8dl(attr_fgcol(p,conp), &fgx1, &fgx2);
- expand8dl(attr_bgcol(p,conp), &bgx1, &bgx2);
+ expand8dl(attr_fgcol(p,c), &fgx1, &fgx2);
+ expand8dl(attr_bgcol(p,c), &bgx1, &bgx2);
eorx1 = fgx1 ^ bgx1; eorx2 = fgx2 ^ bgx2;
for(rows = p->fontheight ; rows-- ; dest += bytes) {
@@ -364,10 +362,11 @@ void fbcon_iplan2p8_putc(struct vc_data *conp, struct display *p, int c,
}
void fbcon_iplan2p8_putcs(struct vc_data *conp, struct display *p,
- const char *s, int count, int yy, int xx)
+ const unsigned short *s, int count, int yy, int xx)
{
u8 *dest, *dest0;
- u8 *cdat, c;
+ u8 *cdat;
+ u16 c;
int rows;
int bytes;
u32 eorx1, eorx2, fgx1, fgx2, bgx1, bgx2, fdx;
@@ -376,8 +375,8 @@ void fbcon_iplan2p8_putcs(struct vc_data *conp, struct display *p,
dest0 = p->screen_base + yy * p->fontheight * bytes + (xx>>1)*16 +
(xx & 1);
- expand8dl(attr_fgcol(p,conp), &fgx1, &fgx2);
- expand8dl(attr_bgcol(p,conp), &bgx1, &bgx2);
+ expand8dl(attr_fgcol(p,*s), &fgx1, &fgx2);
+ expand8dl(attr_bgcol(p,*s), &bgx1, &bgx2);
eorx1 = fgx1 ^ bgx1; eorx2 = fgx2 ^ bgx2;
while (count--) {
@@ -389,7 +388,7 @@ void fbcon_iplan2p8_putcs(struct vc_data *conp, struct display *p,
* cache :-(
*/
- c = *s++;
+ c = *s++ & p->charmask;
cdat = p->fontdata + (c * p->fontheight);
for(rows = p->fontheight, dest = dest0; rows-- ; dest += bytes) {
@@ -433,10 +432,22 @@ void fbcon_iplan2p8_revc(struct display *p, int xx, int yy)
struct display_switch fbcon_iplan2p8 = {
fbcon_iplan2p8_setup, fbcon_iplan2p8_bmove, fbcon_iplan2p8_clear,
- fbcon_iplan2p8_putc, fbcon_iplan2p8_putcs, fbcon_iplan2p8_revc
+ fbcon_iplan2p8_putc, fbcon_iplan2p8_putcs, fbcon_iplan2p8_revc, NULL,
+ NULL, NULL, FONTWIDTH(8)
};
+#ifdef MODULE
+int init_module(void)
+{
+ return 0;
+}
+
+void cleanup_module(void)
+{}
+#endif /* MODULE */
+
+
/*
* Visible symbols for modules
*/
diff --git a/drivers/video/fbcon-iplan2p8.h b/drivers/video/fbcon-iplan2p8.h
index f2c46e229..ba298f84c 100644
--- a/drivers/video/fbcon-iplan2p8.h
+++ b/drivers/video/fbcon-iplan2p8.h
@@ -2,6 +2,18 @@
* Atari interleaved bitplanes (8 planes) (iplan2p8)
*/
+#include <linux/config.h>
+
+#ifdef MODULE
+#if defined(CONFIG_FBCON_IPLAN2P8) || defined(CONFIG_FBCON_IPLAN2P8_MODULE)
+#define FBCON_HAS_IPLAN2P8
+#endif
+#else
+#if defined(CONFIG_FBCON_IPLAN2P8)
+#define FBCON_HAS_IPLAN2P8
+#endif
+#endif
+
extern struct display_switch fbcon_iplan2p8;
extern void fbcon_iplan2p8_setup(struct display *p);
extern void fbcon_iplan2p8_bmove(struct display *p, int sy, int sx, int dy,
@@ -11,5 +23,5 @@ extern void fbcon_iplan2p8_clear(struct vc_data *conp, struct display *p,
extern void fbcon_iplan2p8_putc(struct vc_data *conp, struct display *p, int c,
int yy, int xx);
extern void fbcon_iplan2p8_putcs(struct vc_data *conp, struct display *p,
- const char *s, int count, int yy, int xx);
+ const unsigned short *s, int count, int yy, int xx);
extern void fbcon_iplan2p8_revc(struct display *p, int xx, int yy);
diff --git a/drivers/video/fbcon-mac.c b/drivers/video/fbcon-mac.c
index 5518e5def..a4bac8fae 100644
--- a/drivers/video/fbcon-mac.c
+++ b/drivers/video/fbcon-mac.c
@@ -90,11 +90,15 @@ void fbcon_mac_bmove(struct display *p, int sy, int sx, int dy, int dx,
w = (r&~7) - ((l+7)&~7);
dw = (dr&~7) - ((dl+7)&~7);
if (lo != dlo) {
- char err_str[256];
- unsigned long cnt;
+ unsigned char err_str[128];
+ unsigned short err_buf[256];
+ unsigned long cnt, len;
sprintf( err_str, "ERROR: Shift algorithm: sx=%d,sy=%d,dx=%d,dy=%d,w=%d,h=%d,bpp=%d",
sx,sy,dx,dy,width,height,p->var.bits_per_pixel);
- fbcon_mac_putcs(p->conp, p, err_str, strlen(err_str), 0, 0);
+ len = strlen(err_str);
+ for (cnt = 0; cnt < len; cnt++)
+ err_buf[cnt] = 0x700 | err_str[cnt];
+ fbcon_mac_putcs(p->conp, p, err_buf, len, 0, 0);
/* pause for the user */
for(cnt = 0; cnt < 50000; cnt++)
udelay(100);
@@ -191,7 +195,7 @@ void fbcon_mac_clear(struct vc_data *conp, struct display *p, int sy, int sx,
u8 *dest;
int l,r,t,b,w,lo,s;
- inverse = attr_reverse(p,conp);
+ inverse = attr_reverse(p,conp->vc_attr);
pixel = inverse ? PIXEL_WHITE_MAC : PIXEL_BLACK_MAC;
dest = (u8 *) (p->screen_base + sy * p->fontheight * p->next_line);
@@ -268,12 +272,10 @@ void fbcon_mac_putc(struct vc_data *conp, struct display *p, int c, int yy,
u8 d;
int j;
- c &= 0xff;
-
- cdat = p->fontdata+c*p->fontheight;
- bold = attr_bold(p,conp);
- ch_reverse = attr_reverse(p,conp);
- ch_underline = attr_underline(p,conp);
+ cdat = p->fontdata+(c&p->charmask)*p->fontheight;
+ bold = attr_bold(p,c);
+ ch_reverse = attr_reverse(p,c);
+ ch_underline = attr_underline(p,c);
for (rows = 0; rows < p->fontheight; rows++) {
d = *cdat++;
@@ -293,10 +295,10 @@ void fbcon_mac_putc(struct vc_data *conp, struct display *p, int c, int yy,
}
-void fbcon_mac_putcs(struct vc_data *conp, struct display *p, const char *s,
- int count, int yy, int xx)
+void fbcon_mac_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int yy, int xx)
{
- u8 c;
+ u16 c;
while (count--) {
c = *s++;
@@ -495,10 +497,21 @@ static int get_pixel_mac(struct display *p, int pixel_x, int pixel_y)
struct display_switch fbcon_mac = {
fbcon_mac_setup, fbcon_mac_bmove, fbcon_mac_clear, fbcon_mac_putc,
- fbcon_mac_putcs, fbcon_mac_revc
+ fbcon_mac_putcs, fbcon_mac_revc, NULL, NULL, NULL, FONTWIDTHRANGE(1,8)
};
+#ifdef MODULE
+int init_module(void)
+{
+ return 0;
+}
+
+void cleanup_module(void)
+{}
+#endif /* MODULE */
+
+
/*
* Visible symbols for modules
*/
diff --git a/drivers/video/fbcon-mac.h b/drivers/video/fbcon-mac.h
index 7e807cce9..62d2ae6d3 100644
--- a/drivers/video/fbcon-mac.h
+++ b/drivers/video/fbcon-mac.h
@@ -2,6 +2,18 @@
* Mac variable bpp packed pixels (mac)
*/
+#include <linux/config.h>
+
+#ifdef MODULE
+#if defined(CONFIG_FBCON_MAC) || defined(CONFIG_FBCON_MAC_MODULE)
+#define FBCON_HAS_MAC
+#endif
+#else
+#if defined(CONFIG_FBCON_MAC)
+#define FBCON_HAS_MAC
+#endif
+#endif
+
extern struct display_switch fbcon_mac;
extern void fbcon_mac_setup(struct display *p);
extern void fbcon_mac_bmove(struct display *p, int sy, int sx, int dy, int dx,
@@ -11,5 +23,5 @@ extern void fbcon_mac_clear(struct vc_data *conp, struct display *p, int sy,
extern void fbcon_mac_putc(struct vc_data *conp, struct display *p, int c,
int yy, int xx);
extern void fbcon_mac_putcs(struct vc_data *conp, struct display *p,
- const char *s, int count, int yy, int xx);
+ const unsigned short *s, int count, int yy, int xx);
extern void fbcon_mac_revc(struct display *p, int xx, int yy);
diff --git a/drivers/video/fbcon-mfb.c b/drivers/video/fbcon-mfb.c
index 60ef11221..b8f575859 100644
--- a/drivers/video/fbcon-mfb.c
+++ b/drivers/video/fbcon-mfb.c
@@ -70,13 +70,13 @@ void fbcon_mfb_clear(struct vc_data *conp, struct display *p, int sy, int sx,
dest = p->screen_base+sy*p->fontheight*p->next_line+sx;
if (sx == 0 && width == p->next_line) {
- if (attr_reverse(p,conp))
+ if (attr_reverse(p,conp->vc_attr))
mymemset(dest, height*p->fontheight*width);
else
mymemclear(dest, height*p->fontheight*width);
} else
for (rows = height*p->fontheight; rows--; dest += p->next_line)
- if (attr_reverse(p,conp))
+ if (attr_reverse(p,conp->vc_attr))
mymemset(dest, width);
else
mymemclear_small(dest, width);
@@ -89,13 +89,11 @@ void fbcon_mfb_putc(struct vc_data *conp, struct display *p, int c, int yy,
u_int rows, bold, revs, underl;
u8 d;
- c &= 0xff;
-
dest = p->screen_base+yy*p->fontheight*p->next_line+xx;
- cdat = p->fontdata+c*p->fontheight;
- bold = attr_bold(p,conp);
- revs = attr_reverse(p,conp);
- underl = attr_underline(p,conp);
+ cdat = p->fontdata+(c&p->charmask)*p->fontheight;
+ bold = attr_bold(p,c);
+ revs = attr_reverse(p,c);
+ underl = attr_underline(p,c);
for (rows = p->fontheight; rows--; dest += p->next_line) {
d = *cdat++;
@@ -109,20 +107,21 @@ void fbcon_mfb_putc(struct vc_data *conp, struct display *p, int c, int yy,
}
}
-void fbcon_mfb_putcs(struct vc_data *conp, struct display *p, const char *s,
- int count, int yy, int xx)
+void fbcon_mfb_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int yy, int xx)
{
u8 *dest, *dest0, *cdat;
u_int rows, bold, revs, underl;
- u8 c, d;
+ u8 d;
+ u16 c;
dest0 = p->screen_base+yy*p->fontheight*p->next_line+xx;
- bold = attr_bold(p,conp);
- revs = attr_reverse(p,conp);
- underl = attr_underline(p,conp);
+ bold = attr_bold(p,*s);
+ revs = attr_reverse(p,*s);
+ underl = attr_underline(p,*s);
while (count--) {
- c = *s++;
+ c = *s++ & p->charmask;
dest = dest0++;
cdat = p->fontdata+c*p->fontheight;
for (rows = p->fontheight; rows--; dest += p->next_line) {
@@ -155,10 +154,21 @@ void fbcon_mfb_revc(struct display *p, int xx, int yy)
struct display_switch fbcon_mfb = {
fbcon_mfb_setup, fbcon_mfb_bmove, fbcon_mfb_clear, fbcon_mfb_putc,
- fbcon_mfb_putcs, fbcon_mfb_revc
+ fbcon_mfb_putcs, fbcon_mfb_revc, NULL, NULL, NULL, FONTWIDTH(8)
};
+#ifdef MODULE
+int init_module(void)
+{
+ return 0;
+}
+
+void cleanup_module(void)
+{}
+#endif /* MODULE */
+
+
/*
* Visible symbols for modules
*/
diff --git a/drivers/video/fbcon-mfb.h b/drivers/video/fbcon-mfb.h
index b67d9f70e..77f312e31 100644
--- a/drivers/video/fbcon-mfb.h
+++ b/drivers/video/fbcon-mfb.h
@@ -2,6 +2,18 @@
* Monochrome (mfb)
*/
+#include <linux/config.h>
+
+#ifdef MODULE
+#if defined(CONFIG_FBCON_MFB) || defined(CONFIG_FBCON_MFB_MODULE)
+#define FBCON_HAS_MFB
+#endif
+#else
+#if defined(CONFIG_FBCON_MFB)
+#define FBCON_HAS_MFB
+#endif
+#endif
+
extern struct display_switch fbcon_mfb;
extern void fbcon_mfb_setup(struct display *p);
extern void fbcon_mfb_bmove(struct display *p, int sy, int sx, int dy, int dx,
@@ -11,5 +23,5 @@ extern void fbcon_mfb_clear(struct vc_data *conp, struct display *p, int sy,
extern void fbcon_mfb_putc(struct vc_data *conp, struct display *p, int c,
int yy, int xx);
extern void fbcon_mfb_putcs(struct vc_data *conp, struct display *p,
- const char *s, int count, int yy, int xx);
+ const unsigned short *s, int count, int yy, int xx);
extern void fbcon_mfb_revc(struct display *p, int xx, int yy);
diff --git a/drivers/video/fbcon-vga.c b/drivers/video/fbcon-vga.c
new file mode 100644
index 000000000..3ea8a5234
--- /dev/null
+++ b/drivers/video/fbcon-vga.c
@@ -0,0 +1,206 @@
+/*
+ * linux/drivers/video/fbcon-vga.c -- Low level frame buffer operations for
+ * VGA characters/attributes
+ *
+ * Created 28 Mar 1998 by Geert Uytterhoeven
+ * Monochrome attributes added May 1998 by Andrew Apted
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of this archive for
+ * more details.
+ */
+
+#include <linux/module.h>
+#include <linux/tty.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/fb.h>
+
+#include <asm/io.h>
+
+#include "fbcon.h"
+#include "fbcon-vga.h"
+
+
+ /*
+ * VGA screen access
+ */
+
+static inline void vga_writew(u16 val, u16 *addr)
+{
+#ifdef __powerpc__
+ st_le16(addr, val);
+#else
+ writew(val, (unsigned long)addr);
+#endif /* !__powerpc__ */
+}
+
+static inline u16 vga_readw(u16 *addr)
+{
+#ifdef __powerpc__
+ return ld_le16(addr);
+#else
+ return readw((unsigned long)addr);
+#endif /* !__powerpc__ */
+}
+
+static inline void vga_memsetw(void *s, u16 c, unsigned int count)
+{
+ u16 *addr = (u16 *)s;
+
+ while (count) {
+ count--;
+ vga_writew(c, addr++);
+ }
+}
+
+static inline void vga_memmovew(u16 *to, u16 *from, unsigned int count)
+{
+ if (to < from) {
+ while (count) {
+ count--;
+ vga_writew(vga_readw(from++), to++);
+ }
+ } else {
+ from += count;
+ to += count;
+ while (count) {
+ count--;
+ vga_writew(vga_readw(--from), --to);
+ }
+ }
+}
+
+
+ /*
+ * VGA characters/attributes
+ */
+
+static inline u16 fbcon_vga_attr(struct display *p,
+ unsigned short s)
+{
+ /* Underline and reverse-video are mutually exclusive on MDA.
+ * Since reverse-video is used for cursors and selected areas,
+ * it takes precedence.
+ */
+
+ return (attr_reverse(p, s) ? 0x7000 :
+ (attr_underline(p, s) ? 0x0100 : 0x0700)) |
+ (attr_bold(p, s) ? 0x0800 : 0) |
+ (attr_blink(p, s) ? 0x8000 : 0);
+}
+
+void fbcon_vga_setup(struct display *p)
+{
+ p->next_line = p->line_length;
+ p->next_plane = 0;
+}
+
+void fbcon_vga_bmove(struct display *p, int sy, int sx, int dy, int dx,
+ int height, int width)
+{
+ u16 *src, *dst;
+ int rows;
+
+ if (sx == 0 && dx == 0 && width == p->next_line/2) {
+ src = (u16 *)(p->screen_base+sy*p->next_line);
+ dst = (u16 *)(p->screen_base+dy*p->next_line);
+ vga_memmovew(dst, src, height*width);
+ } else if (dy < sy || (dy == sy && dx < sx)) {
+ src = (u16 *)(p->screen_base+sy*p->next_line+sx*2);
+ dst = (u16 *)(p->screen_base+dy*p->next_line+dx*2);
+ for (rows = height; rows-- ;) {
+ vga_memmovew(dst, src, width);
+ src += p->next_line/2;
+ dst += p->next_line/2;
+ }
+ } else {
+ src = (u16 *)(p->screen_base+(sy+height-1)*p->next_line+sx*2);
+ dst = (u16 *)(p->screen_base+(dy+height-1)*p->next_line+dx*2);
+ for (rows = height; rows-- ;) {
+ vga_memmovew(dst, src, width);
+ src -= p->next_line/2;
+ dst -= p->next_line/2;
+ }
+ }
+}
+
+void fbcon_vga_clear(struct vc_data *conp, struct display *p, int sy, int sx,
+ int height, int width)
+{
+ u16 *dest = (u16 *)(p->screen_base+sy*p->next_line+sx*2);
+ int rows;
+
+ if (sx == 0 && width*2 == p->next_line)
+ vga_memsetw(dest, conp->vc_video_erase_char, height*width);
+ else
+ for (rows = height; rows-- ; dest += p->next_line/2)
+ vga_memsetw(dest, conp->vc_video_erase_char, width);
+}
+
+void fbcon_vga_putc(struct vc_data *conp, struct display *p, int c, int y,
+ int x)
+{
+ u16 *dst = (u16 *)(p->screen_base+y*p->next_line+x*2);
+ if (conp->vc_can_do_color)
+ vga_writew(c, dst);
+ else
+ vga_writew(fbcon_vga_attr(p, c) | (c & 0xff), dst);
+}
+
+void fbcon_vga_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int y, int x)
+{
+ u16 *dst = (u16 *)(p->screen_base+y*p->next_line+x*2);
+ u16 sattr;
+ if (conp->vc_can_do_color)
+ while (count--)
+ vga_writew(*s++, dst++);
+ else {
+ sattr = fbcon_vga_attr(p, *s);
+ while (count--)
+ vga_writew(sattr | ((int) (*s++) & 0xff), dst++);
+ }
+}
+
+void fbcon_vga_revc(struct display *p, int x, int y)
+{
+ u16 *dst = (u16 *)(p->screen_base+y*p->next_line+x*2);
+ u16 val = vga_readw(dst);
+ val = (val & 0x88ff) | ((val<<4) & 0x7000) | ((val>>4) & 0x0700);
+ vga_writew(val, dst);
+}
+
+
+ /*
+ * `switch' for the low level operations
+ */
+
+struct display_switch fbcon_vga = {
+ fbcon_vga_setup, fbcon_vga_bmove, fbcon_vga_clear, fbcon_vga_putc,
+ fbcon_vga_putcs, fbcon_vga_revc, NULL, NULL, NULL, FONTWIDTH(8)
+};
+
+
+#ifdef MODULE
+int init_module(void)
+{
+ return 0;
+}
+
+void cleanup_module(void)
+{}
+#endif /* MODULE */
+
+
+ /*
+ * Visible symbols for modules
+ */
+
+EXPORT_SYMBOL(fbcon_vga);
+EXPORT_SYMBOL(fbcon_vga_setup);
+EXPORT_SYMBOL(fbcon_vga_bmove);
+EXPORT_SYMBOL(fbcon_vga_clear);
+EXPORT_SYMBOL(fbcon_vga_putc);
+EXPORT_SYMBOL(fbcon_vga_putcs);
+EXPORT_SYMBOL(fbcon_vga_revc);
diff --git a/drivers/video/fbcon-vga.h b/drivers/video/fbcon-vga.h
new file mode 100644
index 000000000..7d62e213c
--- /dev/null
+++ b/drivers/video/fbcon-vga.h
@@ -0,0 +1,27 @@
+ /*
+ * VGA characters/attributes
+ */
+
+#include <linux/config.h>
+
+#ifdef MODULE
+#if defined(CONFIG_FBCON_VGA) || defined(CONFIG_FBCON_VGA_MODULE)
+#define FBCON_HAS_VGA
+#endif
+#else
+#if defined(CONFIG_FBCON_VGA)
+#define FBCON_HAS_VGA
+#endif
+#endif
+
+extern struct display_switch fbcon_vga;
+extern void fbcon_vga_setup(struct display *p);
+extern void fbcon_vga_bmove(struct display *p, int sy, int sx, int dy, int dx,
+ int height, int width);
+extern void fbcon_vga_clear(struct vc_data *conp, struct display *p, int sy,
+ int sx, int height, int width);
+extern void fbcon_vga_putc(struct vc_data *conp, struct display *p, int c,
+ int yy, int xx);
+extern void fbcon_vga_putcs(struct vc_data *conp, struct display *p,
+ const unsigned short *s, int count, int yy, int xx);
+extern void fbcon_vga_revc(struct display *p, int xx, int yy);
diff --git a/drivers/video/fbcon.c b/drivers/video/fbcon.c
index a41bf081d..cdec5a29d 100644
--- a/drivers/video/fbcon.c
+++ b/drivers/video/fbcon.c
@@ -24,6 +24,11 @@
* Martin Schaller
* Andreas Schwab
*
+ * Hardware cursor support added by Emmanuel Marty (core@ggi-project.org)
+ * Smart redraw scrolling, arbitrary font width support, 512char font support
+ * added by
+ * Jakub Jelinek (jj@ultra.linux.cz)
+ *
*
* The low level operations for the various display memory organizations are
* now in separate source files.
@@ -35,11 +40,11 @@
* o ilbm Amiga interleaved bitplanes
* o iplan2p[248] Atari interleaved bitplanes
* o mfb Monochrome
+ * o vga VGA characters/attributes
*
* To do:
*
* - Implement 16 plane mode (iplan2p16)
- * - Hardware cursor
*
*
* This file is subject to the terms and conditions of the GNU General Public
@@ -49,7 +54,6 @@
#undef FBCONDEBUG
-#define SUPPORT_SCROLLBACK 0
#define FLASHING_CURSOR 1
#include <linux/config.h>
@@ -67,6 +71,7 @@
#include <linux/fb.h>
#include <linux/vt_kern.h>
#include <linux/selection.h>
+#include <linux/smp.h>
#include <linux/init.h>
#include <asm/irq.h>
@@ -82,10 +87,11 @@
#ifdef CONFIG_MAC
#include <asm/macints.h>
#endif
-#ifdef __mc68000__
+#if defined(__mc68000__) || defined(CONFIG_APUS)
#include <asm/machdep.h>
#include <asm/setup.h>
#endif
+#define INCLUDE_LINUX_LOGO_DATA
#include <asm/linux_logo.h>
#include "fbcon.h"
@@ -98,11 +104,21 @@
# define DPRINTK(fmt, args...)
#endif
-struct display fb_display[MAX_NR_CONSOLES];
+#define LOGO_H 80
+#define LOGO_W 80
+#define LOGO_LINE (LOGO_W/8)
+struct display fb_display[MAX_NR_CONSOLES];
+static int logo_lines;
+static int logo_shown = -1;
-/* ++Geert: Sorry, no hardware cursor support at the moment;
- use Atari alike software cursor */
+/*
+ * Emmanuel: fbcon will now use a hardware cursor if the
+ * low-level driver provides a non-NULL dispsw->cursor pointer,
+ * in which case the hardware should do blinking, etc.
+ *
+ * if dispsw->cursor is NULL, use Atari alike software cursor
+ */
#if FLASHING_CURSOR
static int cursor_drawn = 0;
@@ -119,13 +135,10 @@ static int vbl_cursor_cnt = 0;
static int cursor_on = 0;
static int cursor_blink_rate;
-static __inline__ int CURSOR_UNDRAWN(void)
+static __inline__ void CURSOR_UNDRAWN(void)
{
- int cursor_was_drawn;
vbl_cursor_cnt = 0;
- cursor_was_drawn = cursor_drawn;
cursor_drawn = 0;
- return(cursor_was_drawn);
}
#endif
@@ -133,10 +146,6 @@ static __inline__ int CURSOR_UNDRAWN(void)
* Scroll Method
*/
-#define SCROLL_YWRAP (0)
-#define SCROLL_YPAN (1)
-#define SCROLL_YMOVE (2)
-
#define divides(a, b) ((!(a) || (b)%(a)) ? 0 : 1)
@@ -144,49 +153,41 @@ static __inline__ int CURSOR_UNDRAWN(void)
* Interface used by the world
*/
-static unsigned long fbcon_startup(unsigned long kmem_start,
- const char **display_desc);
-static void fbcon_init(struct vc_data *conp);
+static const char *fbcon_startup(void);
+static void fbcon_init(struct vc_data *conp, int init);
static void fbcon_deinit(struct vc_data *conp);
static int fbcon_changevar(int con);
static void fbcon_clear(struct vc_data *conp, int sy, int sx, int height,
int width);
static void fbcon_putc(struct vc_data *conp, int c, int ypos, int xpos);
-static void fbcon_putcs(struct vc_data *conp, const char *s, int count,
+static void fbcon_putcs(struct vc_data *conp, const unsigned short *s, int count,
int ypos, int xpos);
static void fbcon_cursor(struct vc_data *conp, int mode);
-static void fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
+static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
int count);
static void fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
int height, int width);
static int fbcon_switch(struct vc_data *conp);
-static int fbcon_blank(int blank);
-static int fbcon_get_font(struct vc_data *conp, int *w, int *h, char *data);
-static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data);
+static int fbcon_blank(struct vc_data *conp, int blank);
+static int fbcon_font_op(struct vc_data *conp, struct console_font_op *op);
static int fbcon_set_palette(struct vc_data *conp, unsigned char *table);
-static int fbcon_scrolldelta(int lines);
-static int fbcon_set_mode(struct vc_data *conp, int mode);
+static int fbcon_scrolldelta(struct vc_data *conp, int lines);
/*
* Internal routines
*/
-static void fbcon_setup(int con, int setcol, int init);
+static void fbcon_setup(int con, int init, int logo);
static __inline__ int real_y(struct display *p, int ypos);
#if FLASHING_CURSOR
static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp);
#endif
static __inline__ void updatescrollmode(struct display *p);
-#if SUPPORT_SCROLLBACK
static __inline__ void ywrap_up(int unit, struct vc_data *conp,
struct display *p, int count);
static __inline__ void ywrap_down(int unit, struct vc_data *conp,
struct display *p, int count);
-#else
-static __inline__ void ywrap_up(int unit, struct display *p, int count);
-static __inline__ void ywrap_down(int unit, struct display *p, int count);
-#endif
static __inline__ void ypan_up(int unit, struct vc_data *conp,
struct display *p, int count);
static __inline__ void ypan_down(int unit, struct vc_data *conp,
@@ -232,21 +233,21 @@ static void cursor_timer_handler(unsigned long dev_addr)
static struct display_switch fbcon_dummy;
+/* NOTE: fbcon cannot be __initfunc: it may be called from take_over_console later */
-__initfunc(static unsigned long fbcon_startup(unsigned long kmem_start,
- const char **display_desc))
+static const char *fbcon_startup(void)
{
+ const char *display_desc = "frame buffer device";
int irqres = 1;
+ static int done = 0;
- /* Probe all frame buffer devices */
- kmem_start = probe_framebuffers(kmem_start);
-
- if (!num_registered_fb) {
- DPRINTK("no framebuffer registered\n");
- return kmem_start;
- }
-
- *display_desc = "frame buffer device";
+ /*
+ * If num_registered_fb is zero, this is a call for the dummy part.
+ * The frame buffer devices weren't initialized yet.
+ */
+ if (!num_registered_fb || done)
+ return display_desc;
+ done = 1;
#ifdef CONFIG_AMIGA
if (MACH_IS_AMIGA) {
@@ -302,6 +303,11 @@ __initfunc(static unsigned long fbcon_startup(unsigned long kmem_start,
}
#endif /* CONFIG_MAC */
+#if defined(__arm__) && defined(IRQ_VSYNCPULSE)
+ irqres = request_irq(IRQ_VSYNCPULSE, fbcon_vbl_handler, SA_SHIRQ,
+ "console/cursor", fbcon_vbl_handler);
+#endif
+
if (irqres) {
cursor_blink_rate = DEFAULT_CURSOR_BLINK_RATE;
cursor_timer.expires = jiffies+HZ/50;
@@ -310,14 +316,11 @@ __initfunc(static unsigned long fbcon_startup(unsigned long kmem_start,
add_timer(&cursor_timer);
}
- if (!console_show_logo)
- console_show_logo = fbcon_show_logo;
-
- return kmem_start;
+ return display_desc;
}
-static void fbcon_init(struct vc_data *conp)
+static void fbcon_init(struct vc_data *conp, int init)
{
int unit = conp->vc_num;
struct fb_info *info;
@@ -326,6 +329,9 @@ static void fbcon_init(struct vc_data *conp)
info = registered_fb[(int)con2fb_map[unit]];
info->changevar = &fbcon_changevar;
+ conp->vc_display_fg = &info->display_fg;
+ if (!info->display_fg)
+ info->display_fg = conp;
fb_display[unit] = *(info->disp); /* copy from default */
DPRINTK("mode: %s\n",info->modename);
DPRINTK("visual: %d\n",fb_display[unit].visual);
@@ -334,7 +340,7 @@ static void fbcon_init(struct vc_data *conp)
fb_display[unit].var.bits_per_pixel);
fb_display[unit].conp = conp;
fb_display[unit].fb_info = info;
- fbcon_setup(unit, 1, 1);
+ fbcon_setup(unit, init, !init);
}
@@ -351,13 +357,15 @@ static void fbcon_deinit(struct vc_data *conp)
static int fbcon_changevar(int con)
{
if (fb_display[con].conp)
- fbcon_setup(con, 1, 0);
- return(0);
+ fbcon_setup(con, 0, 0);
+ return 0;
}
static __inline__ void updatescrollmode(struct display *p)
{
+ if (p->scrollmode == SCROLL_YREDRAW)
+ return;
if (divides(p->ywrapstep, p->fontheight) &&
divides(p->fontheight, p->var.yres_virtual))
p->scrollmode = SCROLL_YWRAP;
@@ -368,21 +376,44 @@ static __inline__ void updatescrollmode(struct display *p)
p->scrollmode = SCROLL_YMOVE;
}
+static void fbcon_font_widths(struct display *p)
+{
+ int i;
+ p->fontwidthlog = 0;
+ for (i = 2; i <= 6; i++)
+ if (p->fontwidth == (1 << i))
+ p->fontwidthlog = i;
+ p->fontheightlog = 0;
+ for (i = 2; i <= 6; i++)
+ if (p->fontheight == (1 << i))
+ p->fontheightlog = i;
+}
+
+#define fontwidthvalid(p,w) ((p)->dispsw->fontwidthmask & FONTWIDTH(w))
-static void fbcon_setup(int con, int setcol, int init)
+static void fbcon_setup(int con, int init, int logo)
{
struct display *p = &fb_display[con];
struct vc_data *conp = p->conp;
int nr_rows, nr_cols;
+ int old_rows, old_cols;
+ unsigned short *save = NULL, *r, *q;
+ /* Only if not module */
+ extern int initmem_freed;
+ struct fbcon_font_desc *font;
+ if (con != fg_console || initmem_freed || p->type == FB_TYPE_TEXT)
+ logo = 0;
p->var.xoffset = p->var.yoffset = p->yscroll = 0; /* reset wrap/pan */
if (!p->fb_info->fontname[0] ||
- !findsoftfont(p->fb_info->fontname, &p->fontwidth, &p->fontheight,
- &p->fontdata) || p->fontwidth != 8)
- getdefaultfont(p->var.xres, p->var.yres, NULL, &p->fontwidth,
- &p->fontheight, &p->fontdata);
- if (p->fontwidth != 8) {
+ !(font = fbcon_find_font(p->fb_info->fontname)))
+ font = fbcon_get_default_font(p->var.xres, p->var.yres);
+ p->fontwidth = font->width;
+ p->fontheight = font->height;
+ p->fontdata = font->data;
+ fbcon_font_widths(p);
+ if (!fontwidthvalid(p,p->fontwidth)) {
#ifdef CONFIG_MAC
if (MACH_IS_MAC)
/* ++Geert: hack to make 6x11 fonts work on mac */
@@ -391,14 +422,58 @@ static void fbcon_setup(int con, int setcol, int init)
#endif
{
/* ++Geert: changed from panic() to `correct and continue' */
- printk(KERN_ERR "fbcon_setup: No support for fontwidth != 8");
+ printk(KERN_ERR "fbcon_setup: No support for fontwidth %d\n", p->fontwidth);
p->dispsw = &fbcon_dummy;
}
}
+ if (p->dispsw->set_font)
+ p->dispsw->set_font(p, p->fontwidth, p->fontheight);
updatescrollmode(p);
-
+
+ old_cols = conp->vc_cols;
+ old_rows = conp->vc_rows;
+
nr_cols = p->var.xres/p->fontwidth;
nr_rows = p->var.yres/p->fontheight;
+
+ if (logo) {
+ /* Need to make room for the logo */
+ int cnt;
+ int step;
+
+ logo_lines = (LOGO_H + p->fontheight - 1) / p->fontheight;
+ q = (unsigned short *)(conp->vc_origin + conp->vc_size_row * old_rows);
+ step = logo_lines * old_cols;
+ for (r = q - logo_lines * old_cols; r < q; r++)
+ if (*r != conp->vc_video_erase_char)
+ break;
+ if (r != q && nr_rows >= old_rows + logo_lines) {
+ save = kmalloc(logo_lines * nr_cols * 2, GFP_KERNEL);
+ if (save) {
+ int i = old_cols < nr_cols ? old_cols : nr_cols;
+ scr_memsetw(save, conp->vc_video_erase_char, logo_lines * nr_cols * 2);
+ r = q - step;
+ for (cnt = 0; cnt < logo_lines; cnt++, r += i)
+ scr_memcpyw(save + cnt * nr_cols, r, 2 * i);
+ r = q;
+ }
+ }
+ if (r == q) {
+ /* We can scroll screen down */
+ r = q - step - old_cols;
+ for (cnt = old_rows - logo_lines; cnt > 0; cnt--) {
+ scr_memcpyw(r + step, r, conp->vc_size_row);
+ r -= old_cols;
+ }
+ if (!save) {
+ conp->vc_y += logo_lines;
+ conp->vc_pos += logo_lines * conp->vc_size_row;
+ }
+ }
+ scr_memsetw((unsigned short *)conp->vc_origin, conp->vc_video_erase_char,
+ conp->vc_size_row * logo_lines);
+ }
+
/*
* ++guenther: console.c:vc_allocate() relies on initializing
* vc_{cols,rows}, but we must not set those if we are only
@@ -410,6 +485,10 @@ static void fbcon_setup(int con, int setcol, int init)
}
p->vrows = p->var.yres_virtual/p->fontheight;
conp->vc_can_do_color = p->var.bits_per_pixel != 1;
+ p->fgshift = 8;
+ p->bgshift = 12;
+ p->charmask = 0xff;
+ conp->vc_hi_font_mask = 0;
if (!p->dispsw) {
printk(KERN_WARNING "fbcon_setup: type %d (aux %d, depth %d) not "
@@ -418,13 +497,30 @@ static void fbcon_setup(int con, int setcol, int init)
}
p->dispsw->setup(p);
- if (setcol) {
- p->fgcol = p->var.bits_per_pixel > 2 ? 7 : (1<<p->var.bits_per_pixel)-1;
- p->bgcol = 0;
- }
+ p->fgcol = p->var.bits_per_pixel > 2 ? 7 : (1<<p->var.bits_per_pixel)-1;
+ p->bgcol = 0;
- if (!init)
+ if (!init) {
+ if (con == fg_console)
+ set_palette(); /* Unlike vgacon, we have to set palette before resize on directcolor,
+ so that it is drawn with correct colors */
vc_resize_con(nr_rows, nr_cols, con);
+ if (save) {
+ q = (unsigned short *)(conp->vc_origin + conp->vc_size_row * old_rows);
+ scr_memcpyw(q, save, logo_lines * nr_cols * 2);
+ conp->vc_y += logo_lines;
+ conp->vc_pos += logo_lines * conp->vc_size_row;
+ kfree(save);
+ }
+ if (con == fg_console)
+ update_screen(con); /* So that we set origin correctly */
+ }
+
+ if (logo) {
+ logo_shown = fg_console;
+ fbcon_show_logo(); /* This is protected above by initmem_freed */
+ conp->vc_top = logo_lines;
+ }
}
@@ -458,7 +554,7 @@ static __inline__ int real_y(struct display *p, int ypos)
int rows = p->vrows;
ypos += p->yscroll;
- return(ypos < rows ? ypos : ypos-rows);
+ return ypos < rows ? ypos : ypos-rows;
}
@@ -468,6 +564,7 @@ static void fbcon_clear(struct vc_data *conp, int sy, int sx, int height,
int unit = conp->vc_num;
struct display *p = &fb_display[unit];
u_int y_break;
+ int redraw_cursor = 0;
if (!p->can_soft_blank && console_blanked)
return;
@@ -476,8 +573,10 @@ static void fbcon_clear(struct vc_data *conp, int sy, int sx, int height,
return;
if ((sy <= p->cursor_y) && (p->cursor_y < sy+height) &&
- (sx <= p->cursor_x) && (p->cursor_x < sx+width))
+ (sx <= p->cursor_x) && (p->cursor_x < sx+width)) {
CURSOR_UNDRAWN();
+ redraw_cursor = 1;
+ }
/* Split blits that cross physical y_wrap boundary */
@@ -488,6 +587,9 @@ static void fbcon_clear(struct vc_data *conp, int sy, int sx, int height,
p->dispsw->clear(conp, p, real_y(p, sy+b), sx, height-b, width);
} else
p->dispsw->clear(conp, p, real_y(p, sy), sx, height, width);
+
+ if (redraw_cursor)
+ vbl_cursor_cnt = CURSOR_DRAW_DELAY;
}
@@ -495,30 +597,41 @@ static void fbcon_putc(struct vc_data *conp, int c, int ypos, int xpos)
{
int unit = conp->vc_num;
struct display *p = &fb_display[unit];
+ int redraw_cursor = 0;
if (!p->can_soft_blank && console_blanked)
return;
- if ((p->cursor_x == xpos) && (p->cursor_y == ypos))
+ if ((p->cursor_x == xpos) && (p->cursor_y == ypos)) {
CURSOR_UNDRAWN();
+ redraw_cursor = 1;
+ }
p->dispsw->putc(conp, p, c, real_y(p, ypos), xpos);
+
+ if (redraw_cursor)
+ vbl_cursor_cnt = CURSOR_DRAW_DELAY;
}
-static void fbcon_putcs(struct vc_data *conp, const char *s, int count,
+static void fbcon_putcs(struct vc_data *conp, const unsigned short *s, int count,
int ypos, int xpos)
{
int unit = conp->vc_num;
struct display *p = &fb_display[unit];
+ int redraw_cursor = 0;
if (!p->can_soft_blank && console_blanked)
return;
if ((p->cursor_y == ypos) && (xpos <= p->cursor_x) &&
- (p->cursor_x < (xpos + count)))
+ (p->cursor_x < (xpos + count))) {
CURSOR_UNDRAWN();
+ redraw_cursor = 1;
+ }
p->dispsw->putcs(conp, p, s, count, real_y(p, ypos), xpos);
+ if (redraw_cursor)
+ vbl_cursor_cnt = CURSOR_DRAW_DELAY;
}
@@ -527,26 +640,38 @@ static void fbcon_cursor(struct vc_data *conp, int mode)
int unit = conp->vc_num;
struct display *p = &fb_display[unit];
+ /* do we have a hardware cursor ? */
+ if (p->dispsw->cursor) {
+ p->cursor_x = conp->vc_x;
+ p->cursor_y = conp->vc_y;
+ p->dispsw->cursor(p, mode, p->cursor_x, real_y(p, p->cursor_y));
+ return;
+ }
+
/* Avoid flickering if there's no real change. */
if (p->cursor_x == conp->vc_x && p->cursor_y == conp->vc_y &&
(mode == CM_ERASE) == !cursor_on)
return;
- if (CURSOR_UNDRAWN ())
- p->dispsw->revc(p, p->cursor_x, real_y(p, p->cursor_y));
- p->cursor_x = conp->vc_x;
- p->cursor_y = conp->vc_y;
-
- switch (mode) {
- case CM_ERASE:
- cursor_on = 0;
- break;
- case CM_MOVE:
- case CM_DRAW:
- vbl_cursor_cnt = CURSOR_DRAW_DELAY;
- cursor_on = 1;
- break;
- }
+ cursor_on = 0;
+ if (cursor_drawn)
+ p->dispsw->revc(p, p->cursor_x, real_y(p, p->cursor_y));
+
+ p->cursor_x = conp->vc_x;
+ p->cursor_y = conp->vc_y;
+
+ switch (mode) {
+ case CM_ERASE:
+ cursor_drawn = 0;
+ break;
+ case CM_MOVE:
+ case CM_DRAW:
+ if (cursor_drawn)
+ p->dispsw->revc(p, p->cursor_x, real_y(p, p->cursor_y));
+ vbl_cursor_cnt = CURSOR_DRAW_DELAY;
+ cursor_on = 1;
+ break;
+ }
}
@@ -559,28 +684,21 @@ static void fbcon_vbl_handler(int irq, void *dummy, struct pt_regs *fp)
return;
if (vbl_cursor_cnt && --vbl_cursor_cnt == 0) {
- /* Here no check is possible for console changing. The console
- * switching code should set vbl_cursor_cnt to an appropriate value.
- */
p = &fb_display[fg_console];
- p->dispsw->revc(p, p->cursor_x, real_y(p, p->cursor_y));
+ if (p->dispsw->revc)
+ p->dispsw->revc(p, p->cursor_x, real_y(p, p->cursor_y));
cursor_drawn ^= 1;
vbl_cursor_cnt = cursor_blink_rate;
}
}
#endif
-#if SUPPORT_SCROLLBACK
+static int scrollback_phys_max = 0;
static int scrollback_max = 0;
static int scrollback_current = 0;
-#endif
-#if SUPPORT_SCROLLBACK
static __inline__ void ywrap_up(int unit, struct vc_data *conp,
struct display *p, int count)
-#else
-static __inline__ void ywrap_up(int unit, struct display *p, int count)
-#endif
{
p->yscroll += count;
if (p->yscroll >= p->vrows) /* Deal with wrap */
@@ -589,21 +707,15 @@ static __inline__ void ywrap_up(int unit, struct display *p, int count)
p->var.yoffset = p->yscroll*p->fontheight;
p->var.vmode |= FB_VMODE_YWRAP;
p->fb_info->updatevar(unit, p->fb_info);
-#if SUPPORT_SCROLLBACK
scrollback_max += count;
- if (scrollback_max > p->vrows-conp->vc_rows)
- scrollback_max = p->vrows-conp->vc_rows;
+ if (scrollback_max > scrollback_phys_max)
+ scrollback_max = scrollback_phys_max;
scrollback_current = 0;
-#endif
}
-#if SUPPORT_SCROLLBACK
static __inline__ void ywrap_down(int unit, struct vc_data *conp,
struct display *p, int count)
-#else
-static __inline__ void ywrap_down(int unit, struct display *p, int count)
-#endif
{
p->yscroll -= count;
if (p->yscroll < 0) /* Deal with wrap */
@@ -612,12 +724,10 @@ static __inline__ void ywrap_down(int unit, struct display *p, int count)
p->var.yoffset = p->yscroll*p->fontheight;
p->var.vmode |= FB_VMODE_YWRAP;
p->fb_info->updatevar(unit, p->fb_info);
-#if SUPPORT_SCROLLBACK
scrollback_max -= count;
if (scrollback_max < 0)
scrollback_max = 0;
scrollback_current = 0;
-#endif
}
@@ -625,15 +735,19 @@ static __inline__ void ypan_up(int unit, struct vc_data *conp,
struct display *p, int count)
{
p->yscroll += count;
- if (p->yscroll+conp->vc_rows > p->vrows) {
- p->dispsw->bmove(p, p->yscroll, 0, 0, 0, conp->vc_rows-count,
- conp->vc_cols);
- p->yscroll = 0;
+ if (p->yscroll > p->vrows-conp->vc_rows) {
+ p->dispsw->bmove(p, p->vrows-conp->vc_rows, 0, 0, 0,
+ conp->vc_rows, conp->vc_cols);
+ p->yscroll -= p->vrows-conp->vc_rows;
}
p->var.xoffset = 0;
p->var.yoffset = p->yscroll*p->fontheight;
p->var.vmode &= ~FB_VMODE_YWRAP;
p->fb_info->updatevar(unit, p->fb_info);
+ scrollback_max += count;
+ if (scrollback_max > scrollback_phys_max)
+ scrollback_max = scrollback_phys_max;
+ scrollback_current = 0;
}
@@ -642,33 +756,139 @@ static __inline__ void ypan_down(int unit, struct vc_data *conp,
{
p->yscroll -= count;
if (p->yscroll < 0) {
- p->yscroll = p->vrows-conp->vc_rows;
- p->dispsw->bmove(p, 0, 0, p->yscroll+count, 0, conp->vc_rows-count,
- conp->vc_cols);
+ p->dispsw->bmove(p, 0, 0, p->vrows-conp->vc_rows, 0,
+ conp->vc_rows, conp->vc_cols);
+ p->yscroll += p->vrows-conp->vc_rows;
}
p->var.xoffset = 0;
p->var.yoffset = p->yscroll*p->fontheight;
p->var.vmode &= ~FB_VMODE_YWRAP;
p->fb_info->updatevar(unit, p->fb_info);
+ scrollback_max -= count;
+ if (scrollback_max < 0)
+ scrollback_max = 0;
+ scrollback_current = 0;
+}
+
+
+static void fbcon_redraw(struct vc_data *conp, struct display *p,
+ int line, int count, int offset)
+{
+ unsigned short *d = (unsigned short *)
+ (conp->vc_origin + conp->vc_size_row * line);
+ unsigned short *s = d + offset;
+ while (count--) {
+ unsigned short *start = s;
+ unsigned short *le = (unsigned short *)
+ ((unsigned long)s + conp->vc_size_row);
+ unsigned short c;
+ int x = 0;
+ unsigned short attr = 1;
+
+ do {
+ c = scr_readw(s);
+ if (attr != (c & 0xff00)) {
+ attr = c & 0xff00;
+ if (s > start) {
+ p->dispsw->putcs(conp, p, start, s - start, line, x);
+ x += s - start;
+ start = s;
+ }
+ }
+ if (c == scr_readw(d)) {
+ if (s > start) {
+ p->dispsw->putcs(conp, p, start, s - start, line, x);
+ x += s - start + 1;
+ start = s + 1;
+ } else {
+ x++;
+ start++;
+ }
+ }
+ scr_writew(c, d);
+ s++;
+ d++;
+ } while (s < le);
+ if (s > start)
+ p->dispsw->putcs(conp, p, start, s - start, line, x);
+ if (offset > 0)
+ line++;
+ else {
+ line--;
+ /* NOTE: We subtract two lines from these pointers */
+ s -= conp->vc_size_row;
+ d -= conp->vc_size_row;
+ }
+ }
}
+/* This cannot be used together with ypan or ywrap */
+void fbcon_redraw_bmove(struct display *p, int sy, int sx, int dy, int dx, int h, int w)
+{
+ if (sy != dy)
+ panic("fbcon_redraw_bmove width sy != dy");
+ /* h will be always 1, but it does not matter if we are more generic */
+ while (h-- > 0) {
+ struct vc_data *conp = p->conp;
+ unsigned short *d = (unsigned short *)
+ (conp->vc_origin + conp->vc_size_row * dy + dx * 2);
+ unsigned short *s = d + (dx - sx);
+ unsigned short *start = d;
+ unsigned short *ls = d;
+ unsigned short *le = d + w;
+ unsigned short c;
+ int x = dx;
+ unsigned short attr = 1;
+
+ do {
+ c = scr_readw(d);
+ if (attr != (c & 0xff00)) {
+ attr = c & 0xff00;
+ if (d > start) {
+ p->dispsw->putcs(conp, p, start, d - start, dy, x);
+ x += d - start;
+ start = d;
+ }
+ }
+ if (s >= ls && s < le && c == scr_readw(s)) {
+ if (d > start) {
+ p->dispsw->putcs(conp, p, start, d - start, dy, x);
+ x += d - start + 1;
+ start = d + 1;
+ } else {
+ x++;
+ start++;
+ }
+ }
+ s++;
+ d++;
+ } while (d < le);
+ if (d > start)
+ p->dispsw->putcs(conp, p, start, d - start, dy, x);
+ sy++;
+ dy++;
+ }
+}
-static void fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
- int count)
+static int fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
+ int count)
{
int unit = conp->vc_num;
struct display *p = &fb_display[unit];
+ int is_txt = (p->type == FB_TYPE_TEXT);
if (!p->can_soft_blank && console_blanked)
- return;
+ return 0;
if (!count)
- return;
+ return 0;
fbcon_cursor(conp, CM_ERASE);
/*
* ++Geert: Only use ywrap/ypan if the console is in text mode
+ * ++Andrew: Only use ypan on hardware text mode when scrolling the
+ * whole screen (prevents flicker).
*/
switch (dir) {
@@ -682,11 +902,7 @@ static void fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
if (t > 0)
fbcon_bmove(conp, 0, 0, count, 0, t,
conp->vc_cols);
-#if SUPPORT_SCROLLBACK
ywrap_up(unit, conp, p, count);
-#else
- ywrap_up(unit, p, count);
-#endif
if (conp->vc_rows-b > 0)
fbcon_bmove(conp, b-count, 0, b, 0,
conp->vc_rows-b, conp->vc_cols);
@@ -697,7 +913,8 @@ static void fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
break;
case SCROLL_YPAN:
- if (b-t-count > 3*conp->vc_rows>>2) {
+ if (( is_txt && (b-t == conp->vc_rows)) ||
+ (!is_txt && (b-t-count > 3*conp->vc_rows>>2))) {
if (t > 0)
fbcon_bmove(conp, 0, 0, count, 0, t,
conp->vc_cols);
@@ -717,6 +934,15 @@ static void fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
p->dispsw->clear(conp, p, b-count, 0, count,
conp->vc_cols);
break;
+ case SCROLL_YREDRAW:
+ fbcon_redraw(conp, p, t, b-t-count, count*conp->vc_cols);
+ p->dispsw->clear(conp, p, b-count, 0, count,
+ conp->vc_cols);
+ scr_memsetw((unsigned short *)(conp->vc_origin +
+ conp->vc_size_row * (b-count)),
+ conp->vc_video_erase_char,
+ conp->vc_size_row * count);
+ return 1;
}
else {
fbcon_bmove(conp, t+count, 0, t, 0, b-t-count, conp->vc_cols);
@@ -734,11 +960,7 @@ static void fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
if (conp->vc_rows-b > 0)
fbcon_bmove(conp, b, 0, b-count, 0,
conp->vc_rows-b, conp->vc_cols);
-#if SUPPORT_SCROLLBACK
ywrap_down(unit, conp, p, count);
-#else
- ywrap_down(unit, p, count);
-#endif
if (t > 0)
fbcon_bmove(conp, count, 0, 0, 0, t,
conp->vc_cols);
@@ -749,7 +971,8 @@ static void fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
break;
case SCROLL_YPAN:
- if (b-t-count > 3*conp->vc_rows>>2) {
+ if (( is_txt && (b-t == conp->vc_rows)) ||
+ (!is_txt && (b-t-count > 3*conp->vc_rows>>2))) {
if (conp->vc_rows-b > 0)
fbcon_bmove(conp, b, 0, b-count, 0,
conp->vc_rows-b, conp->vc_cols);
@@ -768,6 +991,15 @@ static void fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
conp->vc_cols);
p->dispsw->clear(conp, p, t, 0, count, conp->vc_cols);
break;
+
+ case SCROLL_YREDRAW:
+ fbcon_redraw(conp, p, b - 1, b-t-count, -count*conp->vc_cols);
+ p->dispsw->clear(conp, p, t, 0, count, conp->vc_cols);
+ scr_memsetw((unsigned short *)(conp->vc_origin +
+ conp->vc_size_row * t),
+ conp->vc_video_erase_char,
+ conp->vc_size_row * count);
+ return 1;
}
else {
/*
@@ -791,6 +1023,7 @@ static void fbcon_scroll(struct vc_data *conp, int t, int b, int dir,
fbcon_clear(conp, 0, t, conp->vc_rows, count);
break;
}
+ return 0;
}
@@ -799,7 +1032,7 @@ static void fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
{
int unit = conp->vc_num;
struct display *p = &fb_display[unit];
-
+
if (!p->can_soft_blank && console_blanked)
return;
@@ -807,9 +1040,9 @@ static void fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
return;
if (((sy <= p->cursor_y) && (p->cursor_y < sy+height) &&
- (sx <= p->cursor_x) && (p->cursor_x < sx+width)) ||
- ((dy <= p->cursor_y) && (p->cursor_y < dy+height) &&
- (dx <= p->cursor_x) && (p->cursor_x < dx+width)))
+ (sx <= p->cursor_x) && (p->cursor_x < sx+width)) ||
+ ((dy <= p->cursor_y) && (p->cursor_y < dy+height) &&
+ (dx <= p->cursor_x) && (p->cursor_x < dx+width)))
fbcon_cursor(conp, CM_ERASE);
/* Split blits that cross physical y_wrap case.
@@ -822,7 +1055,6 @@ static void fbcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
fbcon_bmove_rec(p, sy, sx, dy, dx, height, width, p->vrows-p->yscroll);
}
-
static void fbcon_bmove_rec(struct display *p, int sy, int sx, int dy, int dx,
int height, int width, u_int y_break)
{
@@ -861,158 +1093,186 @@ static int fbcon_switch(struct vc_data *conp)
struct display *p = &fb_display[unit];
struct fb_info *info = p->fb_info;
- if (info && info->switch_con)
- (*info->switch_con)(conp->vc_num, info);
-#if SUPPORT_SCROLLBACK
+ if (logo_shown >= 0) {
+ struct vc_data *conp2 = vc_cons[logo_shown].d;
+
+ if (conp2->vc_top == logo_lines && conp2->vc_bottom == conp2->vc_rows)
+ conp2->vc_top = 0;
+ logo_shown = -1;
+ }
+ p->var.yoffset = p->yscroll*p->fontheight;
+ switch (p->scrollmode) {
+ case SCROLL_YWRAP:
+ scrollback_phys_max = p->vrows-conp->vc_rows;
+ break;
+ case SCROLL_YPAN:
+ scrollback_phys_max = p->vrows-2*conp->vc_rows;
+ if (scrollback_phys_max < 0)
+ scrollback_phys_max = 0;
+ break;
+ default:
+ scrollback_phys_max = 0;
+ break;
+ }
scrollback_max = 0;
scrollback_current = 0;
-#endif
- return(0);
+
+ if (info && info->switch_con)
+ (*info->switch_con)(conp->vc_num, info);
+ if (p->dispsw && p->dispsw->clear_margins)
+ p->dispsw->clear_margins(conp, p);
+ return 1;
}
-static int fbcon_blank(int blank)
+static int fbcon_blank(struct vc_data *conp, int blank)
{
- struct display *p = &fb_display[fg_console];
+ struct display *p = &fb_display[conp->vc_num];
struct fb_info *info = p->fb_info;
+ if (blank < 0) /* Entering graphics mode */
+ return 0;
+
fbcon_cursor(p->conp, blank ? CM_ERASE : CM_DRAW);
if (!p->can_soft_blank) {
if (blank) {
#ifdef CONFIG_MAC
- if (MACH_IS_MAC)
- mymemset(p->screen_base,
- p->var.xres_virtual*p->var.yres_virtual*
- p->var.bits_per_pixel>>3);
- else
+ if (MACH_IS_MAC) {
+ if (p->screen_base)
+ mymemset(p->screen_base,
+ p->var.xres_virtual*p->var.yres_virtual*
+ p->var.bits_per_pixel>>3);
+ } else
#endif
- if (p->visual == FB_VISUAL_MONO01)
- mymemset(p->screen_base,
- p->var.xres_virtual*p->var.yres_virtual*
- p->var.bits_per_pixel>>3);
- else
- mymemclear(p->screen_base,
- p->var.xres_virtual*p->var.yres_virtual*
- p->var.bits_per_pixel>>3);
- return(0);
+ if (p->visual == FB_VISUAL_MONO01) {
+ if (p->screen_base)
+ mymemset(p->screen_base,
+ p->var.xres_virtual*p->var.yres_virtual*
+ p->var.bits_per_pixel>>3);
+ } else
+ p->dispsw->clear(conp, p, 0, 0, p->conp->vc_rows, p->conp->vc_cols);
+ return 0;
} else {
/* Tell console.c that it has to restore the screen itself */
- return(1);
+ return 1;
}
}
(*info->blank)(blank, info);
- return(0);
+ return 0;
}
-static int fbcon_get_font(struct vc_data *conp, int *w, int *h, char *data)
+static inline int fbcon_get_font(int unit, struct console_font_op *op)
{
- int unit = conp->vc_num;
struct display *p = &fb_display[unit];
- int i, j, size, alloc;
-
- size = (p->fontwidth+7)/8 * p->fontheight * 256;
- alloc = (*w+7)/8 * *h * 256;
- *w = p->fontwidth;
- *h = p->fontheight;
+ u8 *data = op->data;
+ int i, j;
- if (alloc < size)
- /* allocation length not sufficient */
- return( -ENAMETOOLONG );
-
- for (i = 0; i < 256; i++)
- for (j = 0; j < p->fontheight; j++)
- data[i*32+j] = p->fontdata[i*p->fontheight+j];
- return( 0 );
+#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (p->fontwidth != 8) return -EINVAL;
+#endif
+ op->width = p->fontwidth;
+ op->height = p->fontheight;
+ op->charcount = (p->charmask == 0x1ff) ? 512 : 256;
+ if (!op->data) return 0;
+
+ if (op->width <= 8) {
+ for (i = 0; i < op->charcount; i++) {
+ for (j = 0; j < p->fontheight; j++)
+ *data++ = p->fontdata[i*p->fontheight+j];
+ data += 32 - p->fontheight;
+ }
+ }
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ else if (op->width <= 16) {
+ for (i = 0; i < op->charcount; i++) {
+ for (j = 0; j < p->fontheight; j++) {
+ *data++ = ((u16 *)p->fontdata)[i*p->fontheight+j] >> 8;
+ *data++ = ((u16 *)p->fontdata)[i*p->fontheight+j];
+ }
+ data += 2 * (32 - p->fontheight);
+ }
+ } else if (op->width <= 24) {
+ for (i = 0; i < op->charcount; i++) {
+ for (j = 0; j < p->fontheight; j++) {
+ *data++ = ((u32 *)p->fontdata)[i*p->fontheight+j] >> 24;
+ *data++ = ((u32 *)p->fontdata)[i*p->fontheight+j] >> 16;
+ *data++ = ((u32 *)p->fontdata)[i*p->fontheight+j] >> 8;
+ }
+ data += 3 * (32 - p->fontheight);
+ }
+ } else {
+ for (i = 0; i < op->charcount; i++) {
+ for (j = 0; j < p->fontheight; j++) {
+ *data++ = ((u32 *)p->fontdata)[i*p->fontheight+j] >> 24;
+ *data++ = ((u32 *)p->fontdata)[i*p->fontheight+j] >> 16;
+ *data++ = ((u32 *)p->fontdata)[i*p->fontheight+j] >> 8;
+ *data++ = ((u32 *)p->fontdata)[i*p->fontheight+j];
+ }
+ data += 4 * (32 - p->fontheight);
+ }
+ }
+#endif
+ return 0;
}
#define REFCOUNT(fd) (((int *)(fd))[-1])
+#define FNTSIZE(fd) (((int *)(fd))[-2])
+#define FNTCHARCNT(fd) (((int *)(fd))[-3])
+#define FNTSUM(fd) (((int *)(fd))[-4])
-static int fbcon_set_font(struct vc_data *conp, int w, int h, char *data)
+static int fbcon_do_set_font(int unit, struct console_font_op *op, u8 *data, int userfont)
{
- int unit = conp->vc_num;
struct display *p = &fb_display[unit];
- int i, j, size, userspace = 1, resize;
- char *old_data = NULL, *new_data;
-
- if (w < 0)
- w = p->fontwidth;
- if (h < 0)
- h = p->fontheight;
-
- if (w == 0) {
- /* engage predefined font, name in 'data' */
- char name[MAX_FONT_NAME+1];
-
- if ((i = verify_area( VERIFY_READ, (void *)data, MAX_FONT_NAME )))
- return i;
- copy_from_user( name, data, MAX_FONT_NAME );
- name[sizeof(name)-1] = 0;
-
- if (!findsoftfont( name, &w, &h, (u8 **)&data ))
- return( -ENOENT );
- userspace = 0;
- } else if (w == 1) {
- /* copy font from some other console in 'h'*/
- struct display *op;
-
- if (h < 0 || !vc_cons_allocated( h ))
- return( -ENOTTY );
- if (h == unit)
- return( 0 ); /* nothing to do */
- op = &fb_display[h];
- if (op->fontdata == p->fontdata)
- return( 0 ); /* already the same font... */
-
- resize = (op->fontwidth != p->fontwidth) ||
- (op->fontheight != p->fontheight);
- if (p->userfont)
- old_data = p->fontdata;
- p->fontdata = op->fontdata;
- w = p->fontwidth = op->fontwidth;
- h = p->fontheight = op->fontheight;
- if ((p->userfont = op->userfont))
- REFCOUNT(p->fontdata)++; /* increment usage counter */
- goto activate;
+ int resize;
+ int w = op->width;
+ int h = op->height;
+ int cnt;
+ char *old_data = NULL;
+
+ if (!fontwidthvalid(p,w)) {
+ if (userfont)
+ kfree(data);
+ return -ENXIO;
}
- if (w != 8)
- /* Currently only fontwidth == 8 supported */
- return( -ENXIO );
-
resize = (w != p->fontwidth) || (h != p->fontheight);
- size = (w+7)/8 * h * 256;
-
if (p->userfont)
- old_data = p->fontdata;
-
- if (userspace) {
- if (!(new_data = kmalloc( sizeof(int)+size, GFP_USER )))
- return( -ENOMEM );
- new_data += sizeof(int);
- REFCOUNT(new_data) = 1; /* usage counter */
-
- for (i = 0; i < 256; i++)
- for (j = 0; j < h; j++)
- new_data[i*h+j] = data[i*32+j];
-
- p->fontdata = new_data;
- p->userfont = 1;
- } else {
- p->fontdata = data;
- p->userfont = 0;
- }
+ old_data = p->fontdata;
+ if (userfont)
+ cnt = FNTCHARCNT(data);
+ else
+ cnt = 256;
+ p->fontdata = data;
+ if ((p->userfont = userfont))
+ REFCOUNT(data)++;
p->fontwidth = w;
p->fontheight = h;
+ if (p->conp->vc_hi_font_mask && cnt == 256) {
+ p->conp->vc_hi_font_mask = 0;
+ p->conp->vc_complement_mask >>= 1;
+ p->fgshift--;
+ p->bgshift--;
+ p->charmask = 0xff;
+ } else if (!p->conp->vc_hi_font_mask && cnt == 512) {
+ p->conp->vc_hi_font_mask = 0x100;
+ p->conp->vc_complement_mask <<= 1;
+ p->fgshift++;
+ p->bgshift++;
+ p->charmask = 0x1ff;
+ }
+ fbcon_font_widths(p);
-activate:
if (resize) {
/* reset wrap/pan */
p->var.xoffset = p->var.yoffset = p->yscroll = 0;
- /* Adjust the virtual screen-size to fontheight*rows */
- p->var.yres_virtual = (p->var.yres/h)*h;
+ if (!p->dispsw->set_font ||
+ !p->dispsw->set_font(p, p->fontwidth, p->fontheight)) {
+ /* Adjust the virtual screen-size to fontheight*rows */
+ p->var.yres_virtual = (p->var.yres/h)*h;
+ }
p->vrows = p->var.yres_virtual/h;
updatescrollmode(p);
vc_resize_con( p->var.yres/h, p->var.xres/w, unit );
@@ -1020,9 +1280,159 @@ activate:
update_screen( unit );
if (old_data && (--REFCOUNT(old_data) == 0))
- kfree( old_data - sizeof(int) );
+ kfree( old_data - 4*sizeof(int) );
- return( 0 );
+ return 0;
+}
+
+static inline int fbcon_copy_font(int unit, struct console_font_op *op)
+{
+ struct display *od, *p = &fb_display[unit];
+ int h = op->height;
+
+ if (h < 0 || !vc_cons_allocated( h ))
+ return -ENOTTY;
+ if (h == unit)
+ return 0; /* nothing to do */
+ od = &fb_display[h];
+ if (od->fontdata == p->fontdata)
+ return 0; /* already the same font... */
+ op->width = od->fontwidth;
+ op->height = od->fontheight;
+ return fbcon_do_set_font(unit, op, od->fontdata, od->userfont);
+}
+
+static inline int fbcon_set_font(int unit, struct console_font_op *op)
+{
+ int w = op->width;
+ int h = op->height;
+ int size = h;
+ int i, j, k;
+ u8 *new_data, *data = op->data, c, *p;
+ u32 d;
+
+#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
+ if (w != 8)
+ return -EINVAL;
+#endif
+
+ if (w > 32 || (op->charcount != 256 && op->charcount != 512))
+ return -EINVAL;
+
+ if (w > 8) {
+ if (w <= 16)
+ size *= 2;
+ else
+ size *= 4;
+ }
+ size *= op->charcount;
+
+ if (!(new_data = kmalloc( 4*sizeof(int)+size, GFP_USER )))
+ return -ENOMEM;
+ new_data += 4*sizeof(int);
+ FNTSIZE(new_data) = size;
+ FNTCHARCNT(new_data) = op->charcount;
+ REFCOUNT(new_data) = 0; /* usage counter */
+ k = 0;
+ p = data;
+ if (w <= 8) {
+ for (i = 0; i < op->charcount; i++) {
+ for (j = 0; j < h; j++) {
+ c = *p++;
+ k += c;
+ new_data[i*h+j] = c;
+ }
+ p += 32 - h;
+ }
+ }
+#ifndef CONFIG_FBCON_FONTWIDTH8_ONLY
+ else if (w <= 16) {
+ for (i = 0; i < op->charcount; i++) {
+ for (j = 0; j < h; j++) {
+ d = (p[0] << 8) | p[1];
+ p += 2;
+ k += d;
+ ((u16 *)new_data)[i*h+j] = d;
+ }
+ p += 2*(32 - h);
+ }
+ } else {
+ for (i = 0; i < op->charcount; i++) {
+ for (j = 0; j < h; j++) {
+ if (w <= 24) {
+ d = (p[0] << 24) |
+ (p[1] << 16) |
+ (p[2] << 8);
+ p += 3;
+ } else {
+ d = (p[0] << 24) |
+ (p[1] << 16) |
+ (p[2] << 8) |
+ p[3];
+ p += 4;
+ }
+ k += d;
+ ((u32 *)new_data)[i*h+j] = d;
+ }
+ if (w <= 24)
+ p += 3*(32 - h);
+ else
+ p += 4*(32 - h);
+ }
+ }
+#endif
+ FNTSUM(new_data) = k;
+ /* Check if the same font is on some other console already */
+ for (i = 0; i < MAX_NR_CONSOLES; i++) {
+ if (fb_display[i].userfont &&
+ fb_display[i].fontdata &&
+ FNTSUM(fb_display[i].fontdata) == k &&
+ FNTSIZE(fb_display[i].fontdata) == size &&
+ !memcmp(fb_display[i].fontdata, new_data, size)) {
+ kfree(new_data - 4*sizeof(int));
+ new_data = fb_display[i].fontdata;
+ break;
+ }
+ }
+ return fbcon_do_set_font(unit, op, new_data, 1);
+}
+
+static inline int fbcon_set_def_font(int unit, struct console_font_op *op)
+{
+ char name[MAX_FONT_NAME];
+ struct fbcon_font_desc *f;
+ struct display *p = &fb_display[unit];
+
+ if (!op->data)
+ f = fbcon_get_default_font(p->var.xres, p->var.yres);
+ else if (strncpy_from_user(name, op->data, MAX_FONT_NAME-1) < 0)
+ return -EFAULT;
+ else {
+ name[MAX_FONT_NAME-1] = 0;
+ if (!(f = fbcon_find_font(name)))
+ return -ENOENT;
+ }
+ op->width = f->width;
+ op->height = f->height;
+ return fbcon_do_set_font(unit, op, f->data, 0);
+}
+
+static int fbcon_font_op(struct vc_data *conp, struct console_font_op *op)
+{
+ int unit = conp->vc_num;
+
+ switch (op->op) {
+ case KD_FONT_OP_SET:
+ return fbcon_set_font(unit, op);
+ case KD_FONT_OP_GET:
+ return fbcon_get_font(unit, op);
+ case KD_FONT_OP_SET_DEFAULT:
+ return fbcon_set_def_font(unit, op);
+ case KD_FONT_OP_COPY:
+ return fbcon_copy_font(unit, op);
+ default:
+ return -ENOSYS;
+ }
}
static u16 palette_red[16];
@@ -1041,7 +1451,7 @@ static int fbcon_set_palette(struct vc_data *conp, unsigned char *table)
u8 val;
if (!conp->vc_can_do_color || (!p->can_soft_blank && console_blanked))
- return(-EINVAL);
+ return -EINVAL;
for (i = j = 0; i < 16; i++) {
k = table[i];
val = conp->vc_palette[j++];
@@ -1051,65 +1461,61 @@ static int fbcon_set_palette(struct vc_data *conp, unsigned char *table)
val = conp->vc_palette[j++];
palette_blue[k] = (val<<8)|val;
}
- palette_cmap.len = 1<<p->var.bits_per_pixel;
- if (palette_cmap.len > 16)
+ if (p->var.bits_per_pixel <= 4)
+ palette_cmap.len = 1<<p->var.bits_per_pixel;
+ else
palette_cmap.len = 16;
+ palette_cmap.start = 0;
return p->fb_info->fbops->fb_set_cmap(&palette_cmap, 1, unit, p->fb_info);
}
-static int fbcon_scrolldelta(int lines)
+static int fbcon_scrolldelta(struct vc_data *conp, int lines)
{
-#if SUPPORT_SCROLLBACK
- int unit = fg_console; /* xxx */
- struct display *p = &fb_display[unit];
- int offset;
-
- if (!p->can_soft_blank && console_blanked ||
- vt_cons[unit]->vc_mode != KD_TEXT || !lines ||
- p->scrollmode != SCROLL_YWRAP)
- return 0;
+ int unit, offset, limit, scrollback_old;
+ struct display *p;
- fbcon_cursor(conp, CM_ERASE);
+ if (!scrollback_phys_max)
+ return -ENOSYS;
+ scrollback_old = scrollback_current;
scrollback_current -= lines;
if (scrollback_current < 0)
scrollback_current = 0;
else if (scrollback_current > scrollback_max)
scrollback_current = scrollback_max;
+ if (scrollback_current == scrollback_old)
+ return 0;
+
+ unit = fg_console;
+ p = &fb_display[unit];
+ if (!p->can_soft_blank &&
+ (console_blanked || vt_cons[unit]->vc_mode != KD_TEXT || !lines))
+ return 0;
+ fbcon_cursor(conp, CM_ERASE);
offset = p->yscroll-scrollback_current;
+ limit = p->vrows;
+ switch (p->scrollmode) {
+ case SCROLL_YWRAP:
+ p->var.vmode |= FB_VMODE_YWRAP;
+ break;
+ case SCROLL_YPAN:
+ limit -= conp->vc_rows;
+ p->var.vmode &= ~FB_VMODE_YWRAP;
+ break;
+ }
if (offset < 0)
- offset += p->vrows;
- else if (offset > p->vrows)
- offset -= p->vrows;
- p->var.vmode |= FB_VMODE_YWRAP;
+ offset += limit;
+ else if (offset >= limit)
+ offset -= limit;
p->var.xoffset = 0;
p->var.yoffset = offset*p->fontheight;
p->fb_info->updatevar(unit, p->fb_info);
-#else
- return -ENOSYS;
-#endif
-}
-
-
- /*
- * Switch between `text' (emulated and accelerated) and `graphics'
- * (unaccelerated text) mode
- */
-
-static int fbcon_set_mode(struct vc_data *conp, int mode)
-{
- struct display *p = &fb_display[conp->vc_num];
- struct fb_ops *ops = p->fb_info->fbops;
-
- return ops->fb_set_mode ? ops->fb_set_mode(mode, p->fb_info) : 0;
+ if (!offset)
+ fbcon_cursor(conp, CM_DRAW);
+ return 0;
}
-
-#define LOGO_H 80
-#define LOGO_W 80
-#define LOGO_LINE (LOGO_W/8)
-
__initfunc(static int fbcon_show_logo( void ))
{
struct display *p = &fb_display[fg_console]; /* draw to vt in foreground */
@@ -1118,17 +1524,25 @@ __initfunc(static int fbcon_show_logo( void ))
unsigned char *fb = p->screen_base;
unsigned char *logo;
unsigned char *dst, *src;
- int i, j, n, x1, y1;
+ int i, j, n, x1, y1, x;
int logo_depth, done = 0;
-
- /* Set colors if visual is PSEUDOCOLOR and we have enough colors */
- if (p->visual == FB_VISUAL_PSEUDOCOLOR && depth >= 4) {
- int first_col = depth >= 8 ? 32 : depth > 4 ? 16 : 0;
- int num_cols = depth >= 8 ? LINUX_LOGO_COLORS : 16;
+
+ /* Return if the frame buffer is not mapped */
+ if (!fb)
+ return 0;
+
+ /* Set colors if visual is PSEUDOCOLOR and we have enough colors, or for
+ * TRUECOLOR */
+ if ((p->visual == FB_VISUAL_PSEUDOCOLOR && depth >= 4) ||
+ p->visual == FB_VISUAL_TRUECOLOR) {
+ int is_truecolor = (p->visual == FB_VISUAL_TRUECOLOR);
+ int use_256 = (!is_truecolor && depth >= 8) ||
+ (is_truecolor && depth >= 24);
+ int first_col = use_256 ? 32 : depth > 4 ? 16 : 0;
+ int num_cols = use_256 ? LINUX_LOGO_COLORS : 16;
unsigned char *red, *green, *blue;
- int old_cmap_len;
- if (depth >= 8) {
+ if (use_256) {
red = linux_logo_red;
green = linux_logo_green;
blue = linux_logo_blue;
@@ -1139,11 +1553,6 @@ __initfunc(static int fbcon_show_logo( void ))
blue = linux_logo16_blue;
}
- /* dirty trick to avoid setcmap calling kmalloc which isn't
- * initialized yet... */
- old_cmap_len = fb_display[fg_console].cmap.len;
- fb_display[fg_console].cmap.len = 1 << depth;
-
for( i = 0; i < num_cols; i += n ) {
n = num_cols - i;
if (n > 16)
@@ -1159,9 +1568,8 @@ __initfunc(static int fbcon_show_logo( void ))
p->fb_info->fbops->fb_set_cmap(&palette_cmap, 1, fg_console,
p->fb_info);
}
- fb_display[fg_console].cmap.len = old_cmap_len;
}
-
+
if (depth >= 8) {
logo = linux_logo;
logo_depth = 8;
@@ -1175,191 +1583,215 @@ __initfunc(static int fbcon_show_logo( void ))
logo_depth = 1;
}
+ for (x = 0; x < smp_num_cpus * (LOGO_W + 8) &&
+ x < p->var.xres - (LOGO_W + 8); x += (LOGO_W + 8)) {
+
#if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || \
- defined(CONFIG_FBCON_CFB32)
- if (p->visual == FB_VISUAL_TRUECOLOR) {
- unsigned int val; /* max. depth 32! */
- int bdepth;
- int redshift, greenshift, blueshift;
+ defined(CONFIG_FBCON_CFB32) || defined(CONFIG_FB_SBUS)
+ if (p->visual == FB_VISUAL_TRUECOLOR) {
+ unsigned int val; /* max. depth 32! */
+ int bdepth;
+ int redshift, greenshift, blueshift;
- /* Bug: Doesn't obey msb_right ... (who needs that?) */
- redshift = p->var.red.offset;
- greenshift = p->var.green.offset;
- blueshift = p->var.blue.offset;
+ /* Bug: Doesn't obey msb_right ... (who needs that?) */
+ redshift = p->var.red.offset;
+ greenshift = p->var.green.offset;
+ blueshift = p->var.blue.offset;
+
+ if (depth >= 24 && (depth % 8) == 0) {
+ /* have at least 8 bits per color */
+ src = logo;
+ bdepth = depth/8;
+ for( y1 = 0; y1 < LOGO_H; y1++ ) {
+ dst = fb + y1*line + x*bdepth;
+ for( x1 = 0; x1 < LOGO_W; x1++, src++ ) {
+ val = (*src << redshift) |
+ (*src << greenshift) |
+ (*src << blueshift);
+#ifdef __LITTLE_ENDIAN
+ for( i = 0; i < bdepth; ++i )
+#else
+ for( i = bdepth-1; i >= 0; --i )
+#endif
+ *dst++ = val >> (i*8);
+ }
+ }
+ }
+ else if (depth >= 15 && depth <= 23) {
+ /* have 5..7 bits per color, using 16 color image */
+ unsigned int pix;
+ src = linux_logo16;
+ bdepth = (depth+7)/8;
+ for( y1 = 0; y1 < LOGO_H; y1++ ) {
+ dst = fb + y1*line + x*bdepth;
+ for( x1 = 0; x1 < LOGO_W/2; x1++, src++ ) {
+ pix = (*src >> 4) | 0x10; /* upper nibble */
+ val = (pix << redshift) |
+ (pix << greenshift) |
+ (pix << blueshift);
+ for( i = 0; i < bdepth; ++i )
+ *dst++ = val >> (i*8);
+ pix = (*src & 0x0f) | 0x10; /* lower nibble */
+ val = (pix << redshift) |
+ (pix << greenshift) |
+ (pix << blueshift);
+ for( i = bdepth-1; i >= 0; --i )
+ *dst++ = val >> (i*8);
+ }
+ }
+ }
+ done = 1;
+ }
+#endif
+#if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || \
+ defined(CONFIG_FBCON_CFB32) || defined(CONFIG_FB_SBUS)
+ if ((depth % 8 == 0) && (p->visual == FB_VISUAL_DIRECTCOLOR)) {
+ /* Modes without color mapping, needs special data transformation... */
+ unsigned int val; /* max. depth 32! */
+ int bdepth = depth/8;
+ unsigned char mask[9] = { 0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff };
+ unsigned char redmask, greenmask, bluemask;
+ int redshift, greenshift, blueshift;
+
+ /* Bug: Doesn't obey msb_right ... (who needs that?) */
+ redmask = mask[p->var.red.length < 8 ? p->var.red.length : 8];
+ greenmask = mask[p->var.green.length < 8 ? p->var.green.length : 8];
+ bluemask = mask[p->var.blue.length < 8 ? p->var.blue.length : 8];
+ redshift = p->var.red.offset - (8-p->var.red.length);
+ greenshift = p->var.green.offset - (8-p->var.green.length);
+ blueshift = p->var.blue.offset - (8-p->var.blue.length);
- if (depth >= 24 && (depth % 8) == 0) {
- /* have at least 8 bits per color */
src = logo;
- bdepth = depth/8;
for( y1 = 0; y1 < LOGO_H; y1++ ) {
- dst = fb + y1*line;
+ dst = fb + y1*line + x*bdepth;
for( x1 = 0; x1 < LOGO_W; x1++, src++ ) {
- val = ((linux_logo_red[*src] & redmask) << redshift) |
- ((linux_logo_green[*src] & greenmask) << greenshift) |
- ((linux_logo_blue[*src] & bluemask) << blueshift);
- for( i = bdepth-1; i >= 0; --i )
- *dst++ = val >> (i*8);
- }
- }
- }
- else if (depth >= 15 && depth <= 23) {
- /* have 5..7 bits per color, using 16 color image */
- unsigned int pix;
- src = linux_logo16;
- bdepth = (depth+7)/8;
- for( y1 = 0; y1 < LOGO_H; y1++ ) {
- dst = fb + y1*line;
- for( x1 = 0; x1 < LOGO_W/2; x1++, src++ ) {
- pix = (*src >> 4) | 0x10; /* upper nibble */
- val = (pix << redshift) |
- (pix << greenshift) |
- (pix << blueshift);
+ val = ((linux_logo_red[*src-32] & redmask) << redshift) |
+ ((linux_logo_green[*src-32] & greenmask) << greenshift) |
+ ((linux_logo_blue[*src-32] & bluemask) << blueshift);
+#ifdef __LITTLE_ENDIAN
for( i = 0; i < bdepth; ++i )
- *dst++ = val >> (i*8);
- pix = (*src & 0x0f) | 0x10; /* lower nibble */
- val = (pix << redshift) |
- (pix << greenshift) |
- (pix << blueshift);
+#else
for( i = bdepth-1; i >= 0; --i )
+#endif
*dst++ = val >> (i*8);
}
}
+ done = 1;
}
-
- done = 1;
- }
#endif
-#if defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || \
- defined(CONFIG_FBCON_CFB32)
- if ((depth % 8 == 0) && (p->visual == FB_VISUAL_DIRECTCOLOR)) {
- /* Modes without color mapping, needs special data transformation... */
- unsigned int val; /* max. depth 32! */
- int bdepth = depth/8;
- unsigned char mask[9] = { 0,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff };
- unsigned char redmask, greenmask, bluemask;
- int redshift, greenshift, blueshift;
-
- /* Bug: Doesn't obey msb_right ... (who needs that?) */
- redmask = mask[p->var.red.length < 8 ? p->var.red.length : 8];
- greenmask = mask[p->var.green.length < 8 ? p->var.green.length : 8];
- bluemask = mask[p->var.blue.length < 8 ? p->var.blue.length : 8];
- redshift = p->var.red.offset - (8-p->var.red.length);
- greenshift = p->var.green.offset - (8-p->var.green.length);
- blueshift = p->var.blue.offset - (8-p->var.blue.length);
-
- src = logo;
- for( y1 = 0; y1 < LOGO_H; y1++ ) {
- dst = fb + y1*line;
- for( x1 = 0; x1 < LOGO_W; x1++, src++ ) {
- val = ((linux_logo_red[*src] & redmask) << redshift) |
- ((linux_logo_green[*src] & greenmask) << greenshift) |
- ((linux_logo_blue[*src] & bluemask) << blueshift);
- for( i = 0; i < bdepth; ++i )
- *dst++ = val >> (i*8);
- }
- }
+#if defined(CONFIG_FBCON_CFB8) || defined(CONFIG_FB_SBUS)
+ if (depth == 8 && p->type == FB_TYPE_PACKED_PIXELS) {
+ /* depth 8 or more, packed, with color registers */
- done = 1;
- }
-#endif
-#if defined(CONFIG_FBCON_CFB8)
- if (depth == 8 && p->type == FB_TYPE_PACKED_PIXELS) {
- /* depth 8 or more, packed, with color registers */
-
- src = logo;
- for( y1 = 0; y1 < LOGO_H; y1++ ) {
- dst = fb + y1*line;
- for( x1 = 0; x1 < LOGO_W; x1++ ) {
- *dst++ = *src++;
+ src = logo;
+ for( y1 = 0; y1 < LOGO_H; y1++ ) {
+ dst = fb + y1*line + x;
+ for( x1 = 0; x1 < LOGO_W; x1++ )
+ *dst++ = *src++;
}
+ done = 1;
}
-
- done = 1;
- }
#endif
#if defined(CONFIG_FBCON_AFB) || defined(CONFIG_FBCON_ILBM) || \
defined(CONFIG_FBCON_IPLAN2P2) || defined(CONFIG_FBCON_IPLAN2P4) || \
defined(CONFIG_FBCON_IPLAN2P8)
- if (depth >= 2 && (p->type == FB_TYPE_PLANES ||
- p->type == FB_TYPE_INTERLEAVED_PLANES)) {
- /* planes (normal or interleaved), with color registers */
- int bit;
- unsigned char val, mask;
- int plane = p->next_plane;
-
- /* for support of Atari interleaved planes */
+ if (depth >= 2 && (p->type == FB_TYPE_PLANES ||
+ p->type == FB_TYPE_INTERLEAVED_PLANES)) {
+ /* planes (normal or interleaved), with color registers */
+ int bit;
+ unsigned char val, mask;
+ int plane = p->next_plane;
+
+ /* for support of Atari interleaved planes */
#define MAP_X(x) (plane > line ? x : (x & ~1)*depth + (x & 1))
- /* extract a bit from the source image */
+ /* extract a bit from the source image */
#define BIT(p,pix,bit) (p[pix*logo_depth/8] & \
(1 << ((8-((pix*logo_depth)&7)-logo_depth) + bit)))
- src = logo;
- for( y1 = 0; y1 < LOGO_H; y1++ ) {
- for( x1 = 0; x1 < LOGO_LINE; x1++, src += logo_depth ) {
- dst = fb + y1*line + MAP_X(x1);
- for( bit = 0; bit < logo_depth; bit++ ) {
- val = 0;
- for( mask = 0x80, i = 0; i < 8; mask >>= 1, i++ ) {
- if (BIT( src, i, bit ))
- val |= mask;
+ src = logo;
+ for( y1 = 0; y1 < LOGO_H; y1++ ) {
+ for( x1 = 0; x1 < LOGO_LINE; x1++, src += logo_depth ) {
+ dst = fb + y1*line + MAP_X(x1);
+ for( bit = 0; bit < logo_depth; bit++ ) {
+ val = 0;
+ for( mask = 0x80, i = 0; i < 8; mask >>= 1, i++ ) {
+ if (BIT( src, i, bit ))
+ val |= mask;
+ }
+ *dst = val;
+ dst += plane;
}
- *dst = val;
- dst += plane;
}
}
- }
- /* fill remaining planes
- * special case for logo_depth == 4: we used color registers 16..31,
- * so fill plane 4 with 1 bits instead of 0 */
- if (depth > logo_depth) {
- for( y1 = 0; y1 < LOGO_H; y1++ ) {
- for( x1 = 0; x1 < LOGO_LINE; x1++ ) {
- dst = fb + y1*line + MAP_X(x1) + logo_depth*plane;
- for( i = logo_depth; i < depth; i++, dst += plane )
- *dst = (i == logo_depth && logo_depth == 4)
- ? 0xff : 0x00;
+ /* fill remaining planes
+ * special case for logo_depth == 4: we used color registers 16..31,
+ * so fill plane 4 with 1 bits instead of 0 */
+ if (depth > logo_depth) {
+ for( y1 = 0; y1 < LOGO_H; y1++ ) {
+ for( x1 = 0; x1 < LOGO_LINE; x1++ ) {
+ dst = fb + y1*line + MAP_X(x1) + logo_depth*plane;
+ for( i = logo_depth; i < depth; i++, dst += plane )
+ *dst = (i == logo_depth && logo_depth == 4)
+ ? 0xff : 0x00;
+ }
}
}
+ done = 1;
+ break;
}
-
- done = 1;
- }
#endif
#if defined(CONFIG_FBCON_MFB) || defined(CONFIG_FBCON_AFB) || \
defined(CONFIG_FBCON_ILBM)
- if (depth == 1) {
- /* monochrome */
- unsigned char inverse = p->inverse ? 0x00 : 0xff;
-
- /* can't use simply memcpy because need to apply inverse */
- for( y1 = 0; y1 < LOGO_H; y1++ ) {
- src = logo + y1*LOGO_LINE;
- dst = fb + y1*line;
- for( x1 = 0; x1 < LOGO_LINE; ++x1 )
- *dst++ = *src++ ^ inverse;
- }
- done = 1;
- }
+ if (depth == 1 && (p->type == FB_TYPE_PACKED_PIXELS ||
+ p->type == FB_TYPE_PLANES ||
+ p->type == FB_TYPE_INTERLEAVED_PLANES)) {
+
+ /* monochrome */
+ unsigned char inverse = p->inverse ? 0x00 : 0xff;
+
+ /* can't use simply memcpy because need to apply inverse */
+ for( y1 = 0; y1 < LOGO_H; y1++ ) {
+ src = logo + y1*LOGO_LINE + x/8;
+ dst = fb + y1*line;
+ for( x1 = 0; x1 < LOGO_LINE; ++x1 )
+ *dst++ = *src++ ^ inverse;
+ }
+ done = 1;
+ }
#endif
+ }
+
/* Modes not yet supported: packed pixels with depth != 8 (does such a
* thing exist in reality?) */
- return( done ? LOGO_H/p->fontheight + 1 : 0 );
+ return done ? (LOGO_H + p->fontheight - 1) / p->fontheight : 0 ;
}
-
-
/*
* The console `switch' structure for the frame buffer based console
*/
-
+
struct consw fb_con = {
- fbcon_startup, fbcon_init, fbcon_deinit, fbcon_clear, fbcon_putc,
- fbcon_putcs, fbcon_cursor, fbcon_scroll, fbcon_bmove, fbcon_switch,
- fbcon_blank, fbcon_get_font, fbcon_set_font, fbcon_set_palette,
- fbcon_scrolldelta, fbcon_set_mode
+ con_startup: fbcon_startup,
+ con_init: fbcon_init,
+ con_deinit: fbcon_deinit,
+ con_clear: fbcon_clear,
+ con_putc: fbcon_putc,
+ con_putcs: fbcon_putcs,
+ con_cursor: fbcon_cursor,
+ con_scroll: fbcon_scroll,
+ con_bmove: fbcon_bmove,
+ con_switch: fbcon_switch,
+ con_blank: fbcon_blank,
+ con_font_op: fbcon_font_op,
+ con_set_palette: fbcon_set_palette,
+ con_scrolldelta: fbcon_scrolldelta,
+ con_set_origin: NULL,
+ con_save_screen: NULL,
+ con_build_attr: NULL,
+ con_invert_region: NULL,
};
@@ -1376,6 +1808,7 @@ static struct display_switch fbcon_dummy = {
(void *)fbcon_dummy_op, /* fbcon_dummy_putc */
(void *)fbcon_dummy_op, /* fbcon_dummy_putcs */
(void *)fbcon_dummy_op, /* fbcon_dummy_revc */
+ NULL, /* fbcon_dummy_cursor */
};
@@ -1384,3 +1817,4 @@ static struct display_switch fbcon_dummy = {
*/
EXPORT_SYMBOL(fb_display);
+EXPORT_SYMBOL(fbcon_redraw_bmove);
diff --git a/drivers/video/fbcon.h b/drivers/video/fbcon.h
index 4868b7730..98091ba0c 100644
--- a/drivers/video/fbcon.h
+++ b/drivers/video/fbcon.h
@@ -11,6 +11,7 @@
#ifndef __VIDEO_FBCON_H
#define __VIDEO_FBCON_H
+#include <linux/config.h>
#include <linux/console_struct.h>
@@ -26,31 +27,63 @@ struct display_switch {
int height, int width);
void (*putc)(struct vc_data *conp, struct display *p, int c, int yy,
int xx);
- void (*putcs)(struct vc_data *conp, struct display *p, const char *s,
+ void (*putcs)(struct vc_data *conp, struct display *p, const unsigned short *s,
int count, int yy, int xx);
void (*revc)(struct display *p, int xx, int yy);
+ void (*cursor)(struct display *p, int mode, int xx, int yy);
+ int (*set_font)(struct display *p, int width, int height);
+ void (*clear_margins)(struct vc_data *conp, struct display *p);
+ unsigned int fontwidthmask; /* 1 at (1 << (width - 1)) if width is supported */
};
+#ifdef CONFIG_FBCON_FONTWIDTH8_ONLY
+
+/* fontwidth w is supported by dispsw */
+#define FONTWIDTH(w) (1 << ((8) - 1))
+/* fontwidths w1-w2 inclusive are supported by dispsw */
+#define FONTWIDTHRANGE(w1,w2) FONTWIDTH(8)
+
+#else
+
+/* fontwidth w is supported by dispsw */
+#define FONTWIDTH(w) (1 << ((w) - 1))
+/* fontwidths w1-w2 inclusive are supported by dispsw */
+#define FONTWIDTHRANGE(w1,w2) (FONTWIDTH(w2+1) - FONTWIDTH(w1))
+
+#endif
/*
* Attribute Decoding
*/
/* Color */
-#define attr_fgcol(p,conp) \
- (((conp)->vc_attr >> ((p)->inverse ? 4 : 0)) & 0x0f)
-#define attr_bgcol(p,conp) \
- (((conp)->vc_attr >> ((p)->inverse ? 0 : 4)) & 0x0f)
+#define attr_fgcol(p,s) \
+ (((s) >> ((p)->fgshift)) & 0x0f)
+#define attr_bgcol(p,s) \
+ (((s) >> ((p)->bgshift)) & 0x0f)
#define attr_bgcol_ec(p,conp) \
- (((conp)->vc_video_erase_char >> ((p)->inverse ? 8 : 12)) & 0x0f)
+ (((conp)->vc_video_erase_char >> ((p)->bgshift)) & 0x0f)
/* Monochrome */
-#define attr_bold(p,conp) \
- (((conp)->vc_attr & 3) == 2)
-#define attr_reverse(p,conp) \
- (((conp)->vc_attr & 8) ^ ((p)->inverse ? 8 : 0))
-#define attr_underline(p,conp) \
- (((conp)->vc_attr) & 4)
+#define attr_bold(p,s) \
+ ((s) & 0x200)
+#define attr_reverse(p,s) \
+ (((s) & 0x800) ^ ((p)->inverse ? 0x800 : 0))
+#define attr_underline(p,s) \
+ ((s) & 0x400)
+#define attr_blink(p,s) \
+ ((s) & 0x8000)
+
+ /*
+ * Scroll Method
+ */
+
+#define SCROLL_YWRAP (0)
+#define SCROLL_YPAN (1)
+#define SCROLL_YMOVE (2)
+#define SCROLL_YREDRAW (3)
+
+extern void fbcon_redraw_bmove(struct display *, int, int, int, int, int, int);
/* ================================================================= */
@@ -317,6 +350,54 @@ static __inline__ void *mymemset(void *s, size_t count)
return(memset(s, 255, count));
}
+#ifdef __i386__
+static __inline__ void fast_memmove(void *d, const void *s, size_t count)
+{
+ if (d < s) {
+__asm__ __volatile__ (
+ "cld\n\t"
+ "shrl $1,%%ecx\n\t"
+ "jnc 1f\n\t"
+ "movsb\n"
+ "1:\tshrl $1,%%ecx\n\t"
+ "jnc 2f\n\t"
+ "movsw\n"
+ "2:\trep\n\t"
+ "movsl"
+ : /* no output */
+ :"c"(count),"D"((long)d),"S"((long)s)
+ :"cx","di","si","memory");
+ } else {
+__asm__ __volatile__ (
+ "std\n\t"
+ "shrl $1,%%ecx\n\t"
+ "jnc 1f\n\t"
+ "movb 3(%%esi),%%al\n\t"
+ "movb %%al,3(%%edi)\n\t"
+ "decl %%esi\n\t"
+ "decl %%edi\n"
+ "1:\tshrl $1,%%ecx\n\t"
+ "jnc 2f\n\t"
+ "movw 2(%%esi),%%ax\n\t"
+ "movw %%ax,2(%%edi)\n\t"
+ "decl %%esi\n\t"
+ "decl %%edi\n\t"
+ "decl %%esi\n\t"
+ "decl %%edi\n"
+ "2:\trep\n\t"
+ "movsl"
+ : /* no output */
+ :"c"(count),"D"(count-4+(long)d),"S"(count-4+(long)s)
+ :"ax","cx","di","si","memory");
+ }
+}
+
+static __inline__ void *mymemmove(char *dst, const char *src, size_t size)
+{
+ fast_memmove(dst, src, size);
+ return dst;
+}
+#else
static __inline__ void *mymemmove(void *d, const void *s, size_t count)
{
return(memmove(d, s, count));
@@ -326,6 +407,7 @@ static __inline__ void fast_memmove(char *dst, const char *src, size_t size)
{
memmove(dst, src, size);
}
+#endif /* !i386 */
#endif /* !m68k */
diff --git a/drivers/video/fbgen.c b/drivers/video/fbgen.c
index 730438d16..3ff647980 100644
--- a/drivers/video/fbgen.c
+++ b/drivers/video/fbgen.c
@@ -17,45 +17,8 @@
#include <asm/uaccess.h>
-
static int currcon = 0;
-static struct display disp;
-
-
- /*
- * `Generic' versions of the frame buffer device operations
- */
-
-extern int fbgen_get_fix(struct fb_fix_screeninfo *fix, int con,
- struct fb_info *info);
-extern int fbgen_get_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-extern int fbgen_set_var(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-extern int fbgen_get_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info);
-extern int fbgen_set_cmap(struct fb_cmap *cmap, int kspc, int con,
- struct fb_info *info);
-extern int fbgen_pan_display(struct fb_var_screeninfo *var, int con,
- struct fb_info *info);
-extern int fbgen_ioctl(struct inode *inode, struct file *file,
- unsigned int cmd, unsigned long arg, int con,
- struct fb_info *info);
-
-
- /*
- * Helper functions
- */
-
-int fbgen_do_set_var(struct fb_var_screeninfo *var, int isactive,
- struct fb_info_gen *info);
-void fbgen_set_disp(int con, struct fb_info_gen *info);
-void fbgen_install_cmap(int con, struct fb_info_gen *info);
-int fbgen_update_var(int con, struct fb_info *info);
-int fbgen_switch(int con, struct fb_info *info);
-void fbgen_blank(int blank, struct fb_info *info);
-
/* ---- `Generic' versions of the frame buffer device operations ----------- */
@@ -156,9 +119,10 @@ int fbgen_get_cmap(struct fb_cmap *cmap, int kspc, int con,
else
if (fb_display[con].cmap.len) /* non default colormap ? */
fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
- else
- fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
- cmap, kspc ? 0 : 2);
+ else {
+ int size = fb_display[con].var.bits_per_pixel == 16 ? 64 : 256;
+ fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
+ }
return 0;
}
@@ -175,8 +139,8 @@ int fbgen_set_cmap(struct fb_cmap *cmap, int kspc, int con,
int err;
if (!fb_display[con].cmap.len) { /* no colormap allocated ? */
- if ((err = fb_alloc_cmap(&fb_display[con].cmap,
- 1 << fb_display[con].var.bits_per_pixel, 0)))
+ int size = fb_display[con].var.bits_per_pixel == 16 ? 64 : 256;
+ if ((err = fb_alloc_cmap(&fb_display[con].cmap, size, 0)))
return err;
}
if (con == currcon) /* current console ? */
@@ -272,7 +236,7 @@ void fbgen_set_disp(int con, struct fb_info_gen *info)
if (con >= 0)
display = &fb_display[con];
else
- display = &disp; /* used during initialization */
+ display = info->info.disp; /* used during initialization */
if (con == -1)
fbhw->get_par(&par, info);
@@ -314,9 +278,11 @@ void fbgen_install_cmap(int con, struct fb_info_gen *info)
if (fb_display[con].cmap.len)
fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
fbhw->setcolreg, &info->info);
- else
- fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
- &fb_display[con].var, 1, fbhw->setcolreg, &info->info);
+ else {
+ int size = fb_display[con].var.bits_per_pixel == 16 ? 64 : 256;
+ fb_set_cmap(fb_default_cmap(size), &fb_display[con].var, 1,
+ fbhw->setcolreg, &info->info);
+ }
}
diff --git a/drivers/video/font.h b/drivers/video/font.h
index b020fcdc9..ab4385b17 100644
--- a/drivers/video/font.h
+++ b/drivers/video/font.h
@@ -13,21 +13,37 @@
#include <linux/types.h>
-
- /*
- * Find a font with a specific name
- */
-
-extern int findsoftfont(char *name, int *width, int *height, u_char *data[]);
-
-
- /*
- * Get the default font for a specific screen size
- */
-
-extern void getdefaultfont(int xres, int yres, char *name[], int *width,
- int *height, u_char *data[]);
-
+struct fbcon_font_desc {
+ int idx;
+ char *name;
+ int width, height;
+ void *data;
+ int pref;
+};
+
+#define VGA8x8_IDX 0
+#define VGA8x16_IDX 1
+#define PEARL8x8_IDX 2
+#define VGA6x11_IDX 3
+#define SUN8x16_IDX 4
+#define SUN12x22_IDX 5
+#define ACORN8x8_IDX 6
+
+extern struct fbcon_font_desc font_vga_8x8,
+ font_vga_8x16,
+ font_pearl_8x8,
+ font_vga_6x11,
+ font_sun_8x16,
+ font_sun_12x22,
+ font_acorn_8x8;
+
+/* Find a font with a specific name */
+
+extern struct fbcon_font_desc *fbcon_find_font(char *name);
+
+/* Get the default font for a specific screen size */
+
+extern struct fbcon_font_desc *fbcon_get_default_font(int xres, int yres);
/* Max. length for the name of a predefined font */
#define MAX_FONT_NAME 32
diff --git a/drivers/video/font_6x11.c b/drivers/video/font_6x11.c
index ebfe24258..88a20e09e 100644
--- a/drivers/video/font_6x11.c
+++ b/drivers/video/font_6x11.c
@@ -4,14 +4,11 @@
/* */
/**********************************************/
-#define FONTDATAMAX (11*256)
-
-char fontname_6x11[] = "ProFont6x11";
+#include "font.h"
-int fontheight_6x11 = 11;
-int fontwidth_6x11 = 6;
+#define FONTDATAMAX (11*256)
-unsigned char fontdata_6x11[FONTDATAMAX] = {
+static unsigned char fontdata_6x11[FONTDATAMAX] = {
/* 0 0x00 '^A' */
0x00, /* 00000000 */
@@ -3343,3 +3340,12 @@ unsigned char fontdata_6x11[FONTDATAMAX] = {
};
+
+struct fbcon_font_desc font_vga_6x11 = {
+ VGA6x11_IDX,
+ "ProFont6x11",
+ 6,
+ 11,
+ fontdata_6x11,
+ -2000 /* Try avoiding this font if possible unless on MAC */
+};
diff --git a/drivers/video/font_8x16.c b/drivers/video/font_8x16.c
index 59801b438..26a34bce7 100644
--- a/drivers/video/font_8x16.c
+++ b/drivers/video/font_8x16.c
@@ -4,14 +4,11 @@
/* */
/**********************************************/
-#define FONTDATAMAX 4096
-
-char fontname_8x16[] = "VGA8x16";
+#include "font.h"
-int fontheight_8x16 = 16;
-int fontwidth_8x16 = 8;
+#define FONTDATAMAX 4096
-unsigned char fontdata_8x16[FONTDATAMAX] = {
+static unsigned char fontdata_8x16[FONTDATAMAX] = {
/* 0 0x00 '^@' */
0x00, /* 00000000 */
@@ -4623,3 +4620,12 @@ unsigned char fontdata_8x16[FONTDATAMAX] = {
};
+
+struct fbcon_font_desc font_vga_8x16 = {
+ VGA8x16_IDX,
+ "VGA8x16",
+ 8,
+ 16,
+ fontdata_8x16,
+ 0
+};
diff --git a/drivers/video/font_8x8.c b/drivers/video/font_8x8.c
index 72a6c3f8f..ff0701a68 100644
--- a/drivers/video/font_8x8.c
+++ b/drivers/video/font_8x8.c
@@ -4,14 +4,11 @@
/* */
/**********************************************/
-#define FONTDATAMAX 2048
-
-char fontname_8x8[] = "VGA8x8";
+#include "font.h"
-int fontheight_8x8 = 8;
-int fontwidth_8x8 = 8;
+#define FONTDATAMAX 2048
-unsigned char fontdata_8x8[FONTDATAMAX] = {
+static unsigned char fontdata_8x8[FONTDATAMAX] = {
/* 0 0x00 '^@' */
0x00, /* 00000000 */
@@ -2575,3 +2572,12 @@ unsigned char fontdata_8x8[FONTDATAMAX] = {
};
+
+struct fbcon_font_desc font_vga_8x8 = {
+ VGA8x8_IDX,
+ "VGA8x8",
+ 8,
+ 8,
+ fontdata_8x8,
+ 0
+};
diff --git a/drivers/video/font_acorn_8x8.c b/drivers/video/font_acorn_8x8.c
new file mode 100644
index 000000000..41acfd5f6
--- /dev/null
+++ b/drivers/video/font_acorn_8x8.c
@@ -0,0 +1,277 @@
+/* Acorn-like font definition, with PC graphics characters */
+
+#include <linux/config.h>
+
+#include "font.h"
+
+static unsigned char acorndata_8x8[] = {
+/* 00 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^@ */
+/* 01 */ 0x7e, 0x81, 0xa5, 0x81, 0xbd, 0x99, 0x81, 0x7e, /* ^A */
+/* 02 */ 0x7e, 0xff, 0xbd, 0xff, 0xc3, 0xe7, 0xff, 0x7e, /* ^B */
+/* 03 */ 0x6c, 0xfe, 0xfe, 0xfe, 0x7c, 0x38, 0x10, 0x00, /* ^C */
+/* 04 */ 0x10, 0x38, 0x7c, 0xfe, 0x7c, 0x38, 0x10, 0x00, /* ^D */
+/* 05 */ 0x00, 0x18, 0x3c, 0xe7, 0xe7, 0x3c, 0x18, 0x00, /* ^E */
+/* 06 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 07 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 08 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 09 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0A */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0B */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0D */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0E */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 0F */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 10 */ 0x00, 0x60, 0x78, 0x7e, 0x7e, 0x78, 0x60, 0x00, /* |> */
+/* 11 */ 0x00, 0x06, 0x1e, 0x7e, 0x7e, 0x1e, 0x06, 0x00, /* <| */
+/* 12 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 13 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 14 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 15 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 16 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 17 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 18 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 19 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 1A */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 1B */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 1C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 1D */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 1E */ 0x00, 0x18, 0x18, 0x3c, 0x3c, 0x7e, 0x7e, 0x00, /* /\ */
+/* 1F */ 0x00, 0x7e, 0x7e, 0x3c, 0x3c, 0x18, 0x18, 0x00, /* \/ */
+/* 20 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* */
+/* 21 */ 0x18, 0x3c, 0x3c, 0x18, 0x18, 0x00, 0x18, 0x00, /* ! */
+/* 22 */ 0x6C, 0x6C, 0x6C, 0x00, 0x00, 0x00, 0x00, 0x00, /* " */
+/* 23 */ 0x36, 0x36, 0x7F, 0x36, 0x7F, 0x36, 0x36, 0x00, /* # */
+/* 24 */ 0x0C, 0x3F, 0x68, 0x3E, 0x0B, 0x7E, 0x18, 0x00, /* $ */
+/* 25 */ 0x60, 0x66, 0x0C, 0x18, 0x30, 0x66, 0x06, 0x00, /* % */
+/* 26 */ 0x38, 0x6C, 0x6C, 0x38, 0x6D, 0x66, 0x3B, 0x00, /* & */
+/* 27 */ 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, /* ' */
+/* 28 */ 0x0C, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00, /* ( */
+/* 29 */ 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00, /* ) */
+/* 2A */ 0x00, 0x18, 0x7E, 0x3C, 0x7E, 0x18, 0x00, 0x00, /* * */
+/* 2B */ 0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00, /* + */
+/* 2C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x30, /* , */
+/* 2D */ 0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, /* - */
+/* 2E */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00, /* . */
+/* 2F */ 0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00, /* / */
+/* 30 */ 0x3C, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x3C, 0x00, /* 0 */
+/* 31 */ 0x18, 0x38, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, /* 1 */
+/* 32 */ 0x3C, 0x66, 0x06, 0x0C, 0x18, 0x30, 0x7E, 0x00, /* 2 */
+/* 33 */ 0x3C, 0x66, 0x06, 0x1C, 0x06, 0x66, 0x3C, 0x00, /* 3 */
+/* 34 */ 0x0C, 0x1C, 0x3C, 0x6C, 0x7E, 0x0C, 0x0C, 0x00, /* 4 */
+/* 35 */ 0x7E, 0x60, 0x7C, 0x06, 0x06, 0x66, 0x3C, 0x00, /* 5 */
+/* 36 */ 0x1C, 0x30, 0x60, 0x7C, 0x66, 0x66, 0x3C, 0x00, /* 6 */
+/* 37 */ 0x7E, 0x06, 0x0C, 0x18, 0x30, 0x30, 0x30, 0x00, /* 7 */
+/* 38 */ 0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00, /* 8 */
+/* 39 */ 0x3C, 0x66, 0x66, 0x3E, 0x06, 0x0C, 0x38, 0x00, /* 9 */
+/* 3A */ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00, /* : */
+/* 3B */ 0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x30, /* ; */
+/* 3C */ 0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x00, /* < */
+/* 3D */ 0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00, /* = */
+/* 3E */ 0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x00, /* > */
+/* 3F */ 0x3C, 0x66, 0x0C, 0x18, 0x18, 0x00, 0x18, 0x00, /* ? */
+/* 40 */ 0x3C, 0x66, 0x6E, 0x6A, 0x6E, 0x60, 0x3C, 0x00, /* @ */
+/* 41 */ 0x3C, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, /* A */
+/* 42 */ 0x7C, 0x66, 0x66, 0x7C, 0x66, 0x66, 0x7C, 0x00, /* B */
+/* 43 */ 0x3C, 0x66, 0x60, 0x60, 0x60, 0x66, 0x3C, 0x00, /* C */
+/* 44 */ 0x78, 0x6C, 0x66, 0x66, 0x66, 0x6C, 0x78, 0x00, /* D */
+/* 45 */ 0x7E, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x7E, 0x00, /* E */
+/* 46 */ 0x7E, 0x60, 0x60, 0x7C, 0x60, 0x60, 0x60, 0x00, /* F */
+/* 47 */ 0x3C, 0x66, 0x60, 0x6E, 0x66, 0x66, 0x3C, 0x00, /* G */
+/* 48 */ 0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00, /* H */
+/* 49 */ 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00, /* I */
+/* 4A */ 0x3E, 0x0C, 0x0C, 0x0C, 0x0C, 0x6C, 0x38, 0x00, /* J */
+/* 4B */ 0x66, 0x6C, 0x78, 0x70, 0x78, 0x6C, 0x66, 0x00, /* K */
+/* 4C */ 0x60, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7E, 0x00, /* L */
+/* 4D */ 0x63, 0x77, 0x7F, 0x6B, 0x6B, 0x63, 0x63, 0x00, /* M */
+/* 4E */ 0x66, 0x66, 0x76, 0x7E, 0x6E, 0x66, 0x66, 0x00, /* N */
+/* 4F */ 0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, /* O */
+/* 50 */ 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, 0x60, 0x00, /* P */
+/* 51 */ 0x3C, 0x66, 0x66, 0x66, 0x6A, 0x6C, 0x36, 0x00, /* Q */
+/* 52 */ 0x7C, 0x66, 0x66, 0x7C, 0x6C, 0x66, 0x66, 0x00, /* R */
+/* 53 */ 0x3C, 0x66, 0x60, 0x3C, 0x06, 0x66, 0x3C, 0x00, /* S */
+/* 54 */ 0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, /* T */
+/* 55 */ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00, /* U */
+/* 56 */ 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, /* V */
+/* 57 */ 0x63, 0x63, 0x6B, 0x6B, 0x7F, 0x77, 0x63, 0x00, /* W */
+/* 58 */ 0x66, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00, /* X */
+/* 59 */ 0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00, /* Y */
+/* 5A */ 0x7E, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x7E, 0x00, /* Z */
+/* 5B */ 0x7C, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7C, 0x00, /* [ */
+/* 5C */ 0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00, /* \ */
+/* 5D */ 0x3E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3E, 0x00, /* ] */
+/* 5E */ 0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ^ */
+/* 5F */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, /* _ */
+/* 60 */ 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ` */
+/* 61 */ 0x00, 0x00, 0x3C, 0x06, 0x3E, 0x66, 0x3E, 0x00, /* a */
+/* 62 */ 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x7C, 0x00, /* b */
+/* 63 */ 0x00, 0x00, 0x3C, 0x66, 0x60, 0x66, 0x3C, 0x00, /* c */
+/* 64 */ 0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x3E, 0x00, /* d */
+/* 65 */ 0x00, 0x00, 0x3C, 0x66, 0x7E, 0x60, 0x3C, 0x00, /* e */
+/* 66 */ 0x1C, 0x30, 0x30, 0x7C, 0x30, 0x30, 0x30, 0x00, /* f */
+/* 67 */ 0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x3C, /* g */
+/* 68 */ 0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00, /* h */
+/* 69 */ 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x3C, 0x00, /* i */
+/* 6A */ 0x18, 0x00, 0x38, 0x18, 0x18, 0x18, 0x18, 0x70, /* j */
+/* 6B */ 0x60, 0x60, 0x66, 0x6C, 0x78, 0x6C, 0x66, 0x00, /* k */
+/* 6C */ 0x38, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00, /* l */
+/* 6D */ 0x00, 0x00, 0x36, 0x7F, 0x6B, 0x6B, 0x63, 0x00, /* m */
+/* 6E */ 0x00, 0x00, 0x7C, 0x66, 0x66, 0x66, 0x66, 0x00, /* n */
+/* 6F */ 0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00, /* o */
+/* 70 */ 0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x60, /* p */
+/* 71 */ 0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x07, /* q */
+/* 72 */ 0x00, 0x00, 0x6C, 0x76, 0x60, 0x60, 0x60, 0x00, /* r */
+/* 73 */ 0x00, 0x00, 0x3E, 0x60, 0x3C, 0x06, 0x7C, 0x00, /* s */
+/* 74 */ 0x30, 0x30, 0x7C, 0x30, 0x30, 0x30, 0x1C, 0x00, /* t */
+/* 75 */ 0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x3E, 0x00, /* u */
+/* 76 */ 0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00, /* v */
+/* 77 */ 0x00, 0x00, 0x63, 0x6B, 0x6B, 0x7F, 0x36, 0x00, /* w */
+/* 78 */ 0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00, /* x */
+/* 79 */ 0x00, 0x00, 0x66, 0x66, 0x66, 0x3E, 0x06, 0x3C, /* y */
+/* 7A */ 0x00, 0x00, 0x7E, 0x0C, 0x18, 0x30, 0x7E, 0x00, /* z */
+/* 7B */ 0x0C, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0C, 0x00, /* { */
+/* 7C */ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00, /* | */
+/* 7D */ 0x30, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x30, 0x00, /* } */
+/* 7E */ 0x31, 0x6B, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, /* ~ */
+/* 7F */ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, /*  */
+/* 80 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 81 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 82 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 83 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 84 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 85 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 86 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 87 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 88 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 89 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 8A */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 8B */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 8C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 8D */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 8E */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 8F */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 90 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 91 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 92 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 93 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 94 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 95 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 96 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 97 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 98 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 99 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 9A */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 9B */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 9C */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 9D */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 9E */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* 9F */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A1 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A2 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A3 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A4 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A5 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A6 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A7 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* A9 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* AA */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* AB */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* AC */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* AD */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* AE */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* AF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* B0 */ 0x22, 0x88, 0x22, 0x88, 0x22, 0x88, 0x22, 0x88,
+/* B1 */ 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa,
+/* B2 */ 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77, 0xdd, 0x77,
+/* B3 */ 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
+/* B4 */ 0x18, 0x18, 0x18, 0xf8, 0x18, 0x18, 0x18, 0x18,
+/* B5 */ 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
+/* B6 */ 0x66, 0x66, 0x66, 0xe6, 0x66, 0x66, 0x66, 0x66,
+/* B7 */ 0x00, 0x00, 0x00, 0xfe, 0x66, 0x66, 0x66, 0x66,
+/* B8 */ 0x00, 0x00, 0xf8, 0x18, 0xf8, 0x18, 0x18, 0x18,
+/* B9 */ 0x66, 0x66, 0xe6, 0x06, 0xe6, 0x66, 0x66, 0x66,
+/* BA */ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66,
+/* BB */ 0x00, 0x00, 0xfe, 0x06, 0xe6, 0x66, 0x66, 0x66,
+/* BC */ 0x66, 0x66, 0xe6, 0x06, 0xfe, 0x00, 0x00, 0x00,
+/* BD */ 0x66, 0x66, 0x66, 0xfe, 0x00, 0x00, 0x00, 0x00,
+/* BE */ 0x18, 0x18, 0xf8, 0x18, 0xf8, 0x00, 0x00, 0x00,
+/* BF */ 0x00, 0x00, 0x00, 0xf8, 0x18, 0x18, 0x18, 0x18,
+/* C0 */ 0x18, 0x18, 0x18, 0x1f, 0x00, 0x00, 0x00, 0x00,
+/* C1 */ 0x18, 0x18, 0x18, 0xff, 0x00, 0x00, 0x00, 0x00,
+/* C2 */ 0x00, 0x00, 0x00, 0xff, 0x18, 0x18, 0x18, 0x18,
+/* C3 */ 0x18, 0x18, 0x18, 0x1f, 0x18, 0x18, 0x18, 0x18,
+/* C4 */ 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00,
+/* C5 */ 0x18, 0x18, 0x18, 0xff, 0x18, 0x18, 0x18, 0x18,
+/* C6 */ 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
+/* C7 */ 0x66, 0x66, 0x66, 0x67, 0x66, 0x66, 0x66, 0x66,
+/* C8 */ 0x66, 0x66, 0x67, 0x60, 0x7f, 0x00, 0x00, 0x00,
+/* C9 */ 0x00, 0x00, 0x7f, 0x60, 0x67, 0x66, 0x66, 0x66,
+/* CA */ 0x66, 0x66, 0xe7, 0x00, 0xff, 0x00, 0x00, 0x00,
+/* CB */ 0x00, 0x00, 0xff, 0x00, 0xe7, 0x66, 0x66, 0x66,
+/* CC */ 0x66, 0x66, 0x67, 0x60, 0x67, 0x66, 0x66, 0x66,
+/* CD */ 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
+/* CE */ 0x66, 0x66, 0xe7, 0x00, 0xe7, 0x66, 0x66, 0x66,
+/* CF */ 0x18, 0x18, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
+/* D0 */ 0x66, 0x66, 0x66, 0xff, 0x00, 0x00, 0x00, 0x00,
+/* D1 */ 0x00, 0x00, 0xff, 0x00, 0xff, 0x18, 0x18, 0x18,
+/* D2 */ 0x00, 0x00, 0x00, 0xff, 0x66, 0x66, 0x66, 0x66,
+/* D3 */ 0x66, 0x66, 0x66, 0x7f, 0x00, 0x00, 0x00, 0x00,
+/* D4 */ 0x18, 0x18, 0x1f, 0x18, 0x1f, 0x00, 0x00, 0x00,
+/* D5 */ 0x00, 0x00, 0x1f, 0x18, 0x1f, 0x18, 0x18, 0x18,
+/* D6 */ 0x00, 0x00, 0x00, 0x7f, 0x66, 0x66, 0x66, 0x66,
+/* D7 */ 0x66, 0x66, 0x66, 0xff, 0x66, 0x66, 0x66, 0x66,
+/* D8 */ 0x18, 0x18, 0xff, 0x18, 0xff, 0x18, 0x18, 0x18,
+/* D9 */ 0x18, 0x18, 0x18, 0xf8, 0x00, 0x00, 0x00, 0x00,
+/* DA */ 0x00, 0x00, 0x00, 0x1f, 0x18, 0x18, 0x18, 0x18,
+/* DB */ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+/* DC */ 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
+/* DD */ 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0, 0xf0,
+/* DE */ 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
+/* DF */ 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
+/* E0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E1 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E2 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E3 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E4 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E5 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E6 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E7 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* E9 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* EA */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* EB */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* EC */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* ED */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* EE */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* EF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F0 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F1 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F2 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F3 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F4 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F5 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F6 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F7 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F8 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* F9 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* FA */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* FB */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* FC */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* FD */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* FE */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+/* FF */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
+};
+
+struct fbcon_font_desc font_acorn_8x8 = {
+ ACORN8x8_IDX,
+ "Acorn8x8",
+ 8,
+ 8,
+ acorndata_8x8,
+#ifdef CONFIG_ARCH_ACORN
+ 20
+#else
+ 0
+#endif
+};
diff --git a/drivers/video/pearl_8x8.c b/drivers/video/font_pearl_8x8.c
index a48c702d2..1f4e40fa6 100644
--- a/drivers/video/pearl_8x8.c
+++ b/drivers/video/font_pearl_8x8.c
@@ -9,14 +9,11 @@
/* */
/**********************************************/
-#define FONTDATAMAX 2048
-
-char fontname_pearl8x8[] = "PEARL8x8";
+#include "font.h"
-int fontheight_pearl8x8 = 8;
-int fontwidth_pearl8x8 = 8;
+#define FONTDATAMAX 2048
-unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
+static unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
/* 0 0x00 '^@' */
0x00, /* 00000000 */
@@ -2580,3 +2577,11 @@ unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
};
+struct fbcon_font_desc font_pearl_8x8 = {
+ PEARL8x8_IDX,
+ "PEARL8x8",
+ 8,
+ 8,
+ fontdata_pearl8x8,
+ 2
+};
diff --git a/drivers/video/font_sun12x22.c b/drivers/video/font_sun12x22.c
new file mode 100644
index 000000000..837e04203
--- /dev/null
+++ b/drivers/video/font_sun12x22.c
@@ -0,0 +1,6220 @@
+#include "font.h"
+
+#define FONTDATAMAX 5632
+
+static unsigned short fontdata_sun12x22[FONTDATAMAX] = {
+
+ /* 0 0x00 '^@' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 1 0x01 '^A' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 2 0x02 '^B' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 3 0x03 '^C' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 4 0x04 '^D' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 5 0x05 '^E' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 6 0x06 '^F' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 7 0x07 '^G' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 8 0x08 '^H' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 9 0x09 '^I' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 10 0x0a '^J' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 11 0x0b '^K' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 12 0x0c '^L' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 13 0x0d '^M' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 14 0x0e '^N' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 15 0x0f '^O' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 16 0x10 '^P' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 17 0x11 '^Q' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 18 0x12 '^R' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 19 0x13 '^S' */
+ 0x0000, /* 000000000000 */
+ 0x3180, /* 001100011000 */
+ 0x3180, /* 001100011000 */
+ 0x3180, /* 001100011000 */
+ 0x3180, /* 001100011000 */
+ 0x3180, /* 001100011000 */
+ 0x3180, /* 001100011000 */
+ 0x3180, /* 001100011000 */
+ 0x3180, /* 001100011000 */
+ 0x3180, /* 001100011000 */
+ 0x3180, /* 001100011000 */
+ 0x3180, /* 001100011000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3180, /* 001100011000 */
+ 0x3180, /* 001100011000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 20 0x14 '^T' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1ff0, /* 000111111111 */
+ 0x3cc0, /* 001111001100 */
+ 0x7cc0, /* 011111001100 */
+ 0x7cc0, /* 011111001100 */
+ 0x7cc0, /* 011111001100 */
+ 0x3cc0, /* 001111001100 */
+ 0x1cc0, /* 000111001100 */
+ 0x0cc0, /* 000011001100 */
+ 0x0cc0, /* 000011001100 */
+ 0x0cc0, /* 000011001100 */
+ 0x0cc0, /* 000011001100 */
+ 0x0cc0, /* 000011001100 */
+ 0x0cc0, /* 000011001100 */
+ 0x1ce0, /* 000111001110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 21 0x15 '^U' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1f00, /* 000111110000 */
+ 0x3180, /* 001100011000 */
+ 0x3180, /* 001100011000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x1f00, /* 000111110000 */
+ 0x3180, /* 001100011000 */
+ 0x3180, /* 001100011000 */
+ 0x1f00, /* 000111110000 */
+ 0x0180, /* 000000011000 */
+ 0x0180, /* 000000011000 */
+ 0x3180, /* 001100011000 */
+ 0x3180, /* 001100011000 */
+ 0x1f00, /* 000111110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 22 0x16 '^V' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 23 0x17 '^W' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 24 0x18 '^X' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 25 0x19 '^Y' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 26 0x1a '^Z' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 27 0x1b '^[' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 28 0x1c '^\' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 29 0x1d '^]' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 30 0x1e '^^' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 31 0x1f '^_' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 32 0x20 ' ' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 33 0x21 '!' */
+ 0x0000, /* 000000000000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 34 0x22 '"' */
+ 0x0000, /* 000000000000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 35 0x23 '#' */
+ 0x0000, /* 000000000000 */
+ 0x0330, /* 000000110011 */
+ 0x0330, /* 000000110011 */
+ 0x0330, /* 000000110011 */
+ 0x0660, /* 000001100110 */
+ 0x1ff0, /* 000111111111 */
+ 0x1ff0, /* 000111111111 */
+ 0x0cc0, /* 000011001100 */
+ 0x0cc0, /* 000011001100 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x7fc0, /* 011111111100 */
+ 0x7fc0, /* 011111111100 */
+ 0x3300, /* 001100110000 */
+ 0x6600, /* 011001100000 */
+ 0x6600, /* 011001100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 36 0x24 '$' */
+ 0x0000, /* 000000000000 */
+ 0x0600, /* 000001100000 */
+ 0x1f80, /* 000111111000 */
+ 0x3fc0, /* 001111111100 */
+ 0x66e0, /* 011001101110 */
+ 0x6660, /* 011001100110 */
+ 0x6600, /* 011001100000 */
+ 0x3e00, /* 001111100000 */
+ 0x1f80, /* 000111111000 */
+ 0x07c0, /* 000001111100 */
+ 0x0660, /* 000001100110 */
+ 0x0660, /* 000001100110 */
+ 0x6660, /* 011001100110 */
+ 0x7fc0, /* 011111111100 */
+ 0x3f80, /* 001111111000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 37 0x25 '%' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x38c0, /* 001110001100 */
+ 0x4cc0, /* 010011001100 */
+ 0x4580, /* 010001011000 */
+ 0x6580, /* 011001011000 */
+ 0x3b00, /* 001110110000 */
+ 0x0300, /* 000000110000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0c00, /* 000011000000 */
+ 0x0dc0, /* 000011011100 */
+ 0x1a60, /* 000110100110 */
+ 0x1a20, /* 000110100010 */
+ 0x3320, /* 001100110010 */
+ 0x31c0, /* 001100011100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 38 0x26 '&' */
+ 0x0000, /* 000000000000 */
+ 0x0700, /* 000001110000 */
+ 0x0f80, /* 000011111000 */
+ 0x18c0, /* 000110001100 */
+ 0x18c0, /* 000110001100 */
+ 0x18c0, /* 000110001100 */
+ 0x0f80, /* 000011111000 */
+ 0x1e00, /* 000111100000 */
+ 0x3e00, /* 001111100000 */
+ 0x7700, /* 011101110000 */
+ 0x6360, /* 011000110110 */
+ 0x61e0, /* 011000011110 */
+ 0x61c0, /* 011000011100 */
+ 0x6180, /* 011000011000 */
+ 0x3fe0, /* 001111111110 */
+ 0x1e60, /* 000111100110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 39 0x27 ''' */
+ 0x0000, /* 000000000000 */
+ 0x0c00, /* 000011000000 */
+ 0x1e00, /* 000111100000 */
+ 0x1e00, /* 000111100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0c00, /* 000011000000 */
+ 0x1800, /* 000110000000 */
+ 0x1000, /* 000100000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 40 0x28 '(' */
+ 0x0000, /* 000000000000 */
+ 0x0180, /* 000000011000 */
+ 0x0300, /* 000000110000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0300, /* 000000110000 */
+ 0x0180, /* 000000011000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 41 0x29 ')' */
+ 0x0000, /* 000000000000 */
+ 0x1800, /* 000110000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0c00, /* 000011000000 */
+ 0x1800, /* 000110000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 42 0x2a '*' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0f00, /* 000011110000 */
+ 0x0600, /* 000001100000 */
+ 0x6660, /* 011001100110 */
+ 0x76e0, /* 011101101110 */
+ 0x1980, /* 000110011000 */
+ 0x0000, /* 000000000000 */
+ 0x1980, /* 000110011000 */
+ 0x76e0, /* 011101101110 */
+ 0x6660, /* 011001100110 */
+ 0x0600, /* 000001100000 */
+ 0x0f00, /* 000011110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 43 0x2b '+' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x7fe0, /* 011111111110 */
+ 0x7fe0, /* 011111111110 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 44 0x2c ',' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0c00, /* 000011000000 */
+ 0x1e00, /* 000111100000 */
+ 0x1e00, /* 000111100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0c00, /* 000011000000 */
+ 0x1800, /* 000110000000 */
+ 0x1000, /* 000100000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 45 0x2d '-' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x7fe0, /* 011111111110 */
+ 0x7fe0, /* 011111111110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 46 0x2e '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0c00, /* 000011000000 */
+ 0x1e00, /* 000111100000 */
+ 0x1e00, /* 000111100000 */
+ 0x0c00, /* 000011000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 47 0x2f '/' */
+ 0x0000, /* 000000000000 */
+ 0x0060, /* 000000000110 */
+ 0x00c0, /* 000000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x0180, /* 000000011000 */
+ 0x0180, /* 000000011000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x1800, /* 000110000000 */
+ 0x1800, /* 000110000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x6000, /* 011000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 48 0x30 '0' */
+ 0x0000, /* 000000000000 */
+ 0x0700, /* 000001110000 */
+ 0x0f80, /* 000011111000 */
+ 0x1180, /* 000100011000 */
+ 0x10c0, /* 000100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x3080, /* 001100001000 */
+ 0x1880, /* 000110001000 */
+ 0x1f00, /* 000111110000 */
+ 0x0e00, /* 000011100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 49 0x31 '1' */
+ 0x0000, /* 000000000000 */
+ 0x0200, /* 000000100000 */
+ 0x0600, /* 000001100000 */
+ 0x0e00, /* 000011100000 */
+ 0x1e00, /* 000111100000 */
+ 0x3600, /* 001101100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 50 0x32 '2' */
+ 0x0000, /* 000000000000 */
+ 0x1f00, /* 000111110000 */
+ 0x3f80, /* 001111111000 */
+ 0x61c0, /* 011000011100 */
+ 0x40c0, /* 010000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x0180, /* 000000011000 */
+ 0x0300, /* 000000110000 */
+ 0x0600, /* 000001100000 */
+ 0x0c00, /* 000011000000 */
+ 0x1800, /* 000110000000 */
+ 0x3020, /* 001100000010 */
+ 0x7fe0, /* 011111111110 */
+ 0x7fe0, /* 011111111110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 51 0x33 '3' */
+ 0x0000, /* 000000000000 */
+ 0x0f80, /* 000011111000 */
+ 0x1fc0, /* 000111111100 */
+ 0x20e0, /* 001000001110 */
+ 0x4060, /* 010000000110 */
+ 0x0060, /* 000000000110 */
+ 0x00e0, /* 000000001110 */
+ 0x07c0, /* 000001111100 */
+ 0x0fc0, /* 000011111100 */
+ 0x00e0, /* 000000001110 */
+ 0x0060, /* 000000000110 */
+ 0x0060, /* 000000000110 */
+ 0x4060, /* 010000000110 */
+ 0x6040, /* 011000000100 */
+ 0x3f80, /* 001111111000 */
+ 0x1f00, /* 000111110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 52 0x34 '4' */
+ 0x0000, /* 000000000000 */
+ 0x0180, /* 000000011000 */
+ 0x0380, /* 000000111000 */
+ 0x0380, /* 000000111000 */
+ 0x0580, /* 000001011000 */
+ 0x0580, /* 000001011000 */
+ 0x0980, /* 000010011000 */
+ 0x0980, /* 000010011000 */
+ 0x1180, /* 000100011000 */
+ 0x1180, /* 000100011000 */
+ 0x2180, /* 001000011000 */
+ 0x3fe0, /* 001111111110 */
+ 0x7fe0, /* 011111111110 */
+ 0x0180, /* 000000011000 */
+ 0x0180, /* 000000011000 */
+ 0x0180, /* 000000011000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 53 0x35 '5' */
+ 0x0000, /* 000000000000 */
+ 0x0fc0, /* 000011111100 */
+ 0x0fc0, /* 000011111100 */
+ 0x1000, /* 000100000000 */
+ 0x1000, /* 000100000000 */
+ 0x2000, /* 001000000000 */
+ 0x3f80, /* 001111111000 */
+ 0x31c0, /* 001100011100 */
+ 0x00e0, /* 000000001110 */
+ 0x0060, /* 000000000110 */
+ 0x0060, /* 000000000110 */
+ 0x0060, /* 000000000110 */
+ 0x4060, /* 010000000110 */
+ 0x6060, /* 011000000110 */
+ 0x30c0, /* 001100001100 */
+ 0x1f80, /* 000111111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 54 0x36 '6' */
+ 0x0000, /* 000000000000 */
+ 0x0700, /* 000001110000 */
+ 0x0c00, /* 000011000000 */
+ 0x1800, /* 000110000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x6000, /* 011000000000 */
+ 0x6780, /* 011001111000 */
+ 0x6fc0, /* 011011111100 */
+ 0x70e0, /* 011100001110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x7040, /* 011100000100 */
+ 0x3f80, /* 001111111000 */
+ 0x1f00, /* 000111110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 55 0x37 '7' */
+ 0x0000, /* 000000000000 */
+ 0x1fe0, /* 000111111110 */
+ 0x3fe0, /* 001111111110 */
+ 0x6040, /* 011000000100 */
+ 0x0040, /* 000000000100 */
+ 0x00c0, /* 000000001100 */
+ 0x0080, /* 000000001000 */
+ 0x0080, /* 000000001000 */
+ 0x0180, /* 000000011000 */
+ 0x0100, /* 000000010000 */
+ 0x0100, /* 000000010000 */
+ 0x0300, /* 000000110000 */
+ 0x0200, /* 000000100000 */
+ 0x0200, /* 000000100000 */
+ 0x0600, /* 000001100000 */
+ 0x0400, /* 000001000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 56 0x38 '8' */
+ 0x0000, /* 000000000000 */
+ 0x0f00, /* 000011110000 */
+ 0x1180, /* 000100011000 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x1880, /* 000110001000 */
+ 0x0d00, /* 000011010000 */
+ 0x0600, /* 000001100000 */
+ 0x0b00, /* 000010110000 */
+ 0x1180, /* 000100011000 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x1880, /* 000110001000 */
+ 0x0f00, /* 000011110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 57 0x39 '9' */
+ 0x0000, /* 000000000000 */
+ 0x0f80, /* 000011111000 */
+ 0x11c0, /* 000100011100 */
+ 0x20e0, /* 001000001110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x70e0, /* 011100001110 */
+ 0x3f60, /* 001111110110 */
+ 0x1e60, /* 000111100110 */
+ 0x0060, /* 000000000110 */
+ 0x00c0, /* 000000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x0180, /* 000000011000 */
+ 0x0700, /* 000001110000 */
+ 0x3c00, /* 001111000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 58 0x3a ':' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0c00, /* 000011000000 */
+ 0x1e00, /* 000111100000 */
+ 0x1e00, /* 000111100000 */
+ 0x0c00, /* 000011000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0c00, /* 000011000000 */
+ 0x1e00, /* 000111100000 */
+ 0x1e00, /* 000111100000 */
+ 0x0c00, /* 000011000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 59 0x3b ';' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0c00, /* 000011000000 */
+ 0x1e00, /* 000111100000 */
+ 0x1e00, /* 000111100000 */
+ 0x0c00, /* 000011000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0c00, /* 000011000000 */
+ 0x1e00, /* 000111100000 */
+ 0x1e00, /* 000111100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0c00, /* 000011000000 */
+ 0x1800, /* 000110000000 */
+ 0x1000, /* 000100000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 60 0x3c '<' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0060, /* 000000000110 */
+ 0x01c0, /* 000000011100 */
+ 0x0700, /* 000001110000 */
+ 0x1c00, /* 000111000000 */
+ 0x7000, /* 011100000000 */
+ 0x7000, /* 011100000000 */
+ 0x1c00, /* 000111000000 */
+ 0x0700, /* 000001110000 */
+ 0x01c0, /* 000000011100 */
+ 0x0060, /* 000000000110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 61 0x3d '=' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x7fe0, /* 011111111110 */
+ 0x7fe0, /* 011111111110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x7fe0, /* 011111111110 */
+ 0x7fe0, /* 011111111110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 62 0x3e '>' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x6000, /* 011000000000 */
+ 0x3800, /* 001110000000 */
+ 0x0e00, /* 000011100000 */
+ 0x0380, /* 000000111000 */
+ 0x00e0, /* 000000001110 */
+ 0x00e0, /* 000000001110 */
+ 0x0380, /* 000000111000 */
+ 0x0e00, /* 000011100000 */
+ 0x3800, /* 001110000000 */
+ 0x6000, /* 011000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 63 0x3f '?' */
+ 0x0000, /* 000000000000 */
+ 0x0f00, /* 000011110000 */
+ 0x1f80, /* 000111111000 */
+ 0x39c0, /* 001110011100 */
+ 0x20c0, /* 001000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x0180, /* 000000011000 */
+ 0x0300, /* 000000110000 */
+ 0x0600, /* 000001100000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 64 0x40 '@' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0f80, /* 000011111000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3060, /* 001100000110 */
+ 0x6060, /* 011000000110 */
+ 0x6720, /* 011001110010 */
+ 0x6fa0, /* 011011111010 */
+ 0x6ca0, /* 011011001010 */
+ 0x6ca0, /* 011011001010 */
+ 0x67e0, /* 011001111110 */
+ 0x6000, /* 011000000000 */
+ 0x3000, /* 001100000000 */
+ 0x3fe0, /* 001111111110 */
+ 0x0fe0, /* 000011111110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 65 0x41 'A' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0b00, /* 000010110000 */
+ 0x0b00, /* 000010110000 */
+ 0x0900, /* 000010010000 */
+ 0x1180, /* 000100011000 */
+ 0x1180, /* 000100011000 */
+ 0x1080, /* 000100001000 */
+ 0x3fc0, /* 001111111100 */
+ 0x20c0, /* 001000001100 */
+ 0x2040, /* 001000000100 */
+ 0x4060, /* 010000000110 */
+ 0x4060, /* 010000000110 */
+ 0xe0f0, /* 111000001111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 66 0x42 'B' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xff00, /* 111111110000 */
+ 0x6080, /* 011000001000 */
+ 0x60c0, /* 011000001100 */
+ 0x60c0, /* 011000001100 */
+ 0x60c0, /* 011000001100 */
+ 0x6180, /* 011000011000 */
+ 0x7f80, /* 011111111000 */
+ 0x60c0, /* 011000001100 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x60c0, /* 011000001100 */
+ 0xff80, /* 111111111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 67 0x43 'C' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0fc0, /* 000011111100 */
+ 0x1060, /* 000100000110 */
+ 0x2020, /* 001000000010 */
+ 0x2000, /* 001000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x2000, /* 001000000000 */
+ 0x3020, /* 001100000010 */
+ 0x1840, /* 000110000100 */
+ 0x0f80, /* 000011111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 68 0x44 'D' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xff00, /* 111111110000 */
+ 0x61c0, /* 011000011100 */
+ 0x60c0, /* 011000001100 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6040, /* 011000000100 */
+ 0x6180, /* 011000011000 */
+ 0xfe00, /* 111111100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 69 0x45 'E' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x7fc0, /* 011111111100 */
+ 0x3040, /* 001100000100 */
+ 0x3040, /* 001100000100 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3080, /* 001100001000 */
+ 0x3f80, /* 001111111000 */
+ 0x3080, /* 001100001000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3020, /* 001100000010 */
+ 0x3020, /* 001100000010 */
+ 0x7fe0, /* 011111111110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 70 0x46 'F' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x7fc0, /* 011111111100 */
+ 0x3040, /* 001100000100 */
+ 0x3040, /* 001100000100 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3080, /* 001100001000 */
+ 0x3f80, /* 001111111000 */
+ 0x3080, /* 001100001000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x7800, /* 011110000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 71 0x47 'G' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0fc0, /* 000011111100 */
+ 0x1060, /* 000100000110 */
+ 0x2020, /* 001000000010 */
+ 0x2000, /* 001000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x61f0, /* 011000011111 */
+ 0x6060, /* 011000000110 */
+ 0x2060, /* 001000000110 */
+ 0x3060, /* 001100000110 */
+ 0x1860, /* 000110000110 */
+ 0x0f80, /* 000011111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 72 0x48 'H' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xf0f0, /* 111100001111 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x7fe0, /* 011111111110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0xf0f0, /* 111100001111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 73 0x49 'I' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1f80, /* 000111111000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x1f80, /* 000111111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 74 0x4a 'J' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1f80, /* 000111111000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0400, /* 000001000000 */
+ 0x3800, /* 001110000000 */
+ 0x3000, /* 001100000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 75 0x4b 'K' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xf0e0, /* 111100001110 */
+ 0x6180, /* 011000011000 */
+ 0x6300, /* 011000110000 */
+ 0x6600, /* 011001100000 */
+ 0x6c00, /* 011011000000 */
+ 0x7800, /* 011110000000 */
+ 0x7800, /* 011110000000 */
+ 0x7c00, /* 011111000000 */
+ 0x6e00, /* 011011100000 */
+ 0x6700, /* 011001110000 */
+ 0x6380, /* 011000111000 */
+ 0x61c0, /* 011000011100 */
+ 0x60e0, /* 011000001110 */
+ 0xf070, /* 111100000111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 76 0x4c 'L' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x7800, /* 011110000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3020, /* 001100000010 */
+ 0x3020, /* 001100000010 */
+ 0x7fe0, /* 011111111110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 77 0x4d 'M' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xe070, /* 111000000111 */
+ 0x60e0, /* 011000001110 */
+ 0x70e0, /* 011100001110 */
+ 0x70e0, /* 011100001110 */
+ 0x70e0, /* 011100001110 */
+ 0x5960, /* 010110010110 */
+ 0x5960, /* 010110010110 */
+ 0x5960, /* 010110010110 */
+ 0x4d60, /* 010011010110 */
+ 0x4e60, /* 010011100110 */
+ 0x4e60, /* 010011100110 */
+ 0x4460, /* 010001000110 */
+ 0x4460, /* 010001000110 */
+ 0xe4f0, /* 111001001111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 78 0x4e 'N' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xc070, /* 110000000111 */
+ 0x6020, /* 011000000010 */
+ 0x7020, /* 011100000010 */
+ 0x7820, /* 011110000010 */
+ 0x5820, /* 010110000010 */
+ 0x4c20, /* 010011000010 */
+ 0x4620, /* 010001100010 */
+ 0x4720, /* 010001110010 */
+ 0x4320, /* 010000110010 */
+ 0x41a0, /* 010000011010 */
+ 0x40e0, /* 010000001110 */
+ 0x40e0, /* 010000001110 */
+ 0x4060, /* 010000000110 */
+ 0xe030, /* 111000000011 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 79 0x4f 'O' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0f00, /* 000011110000 */
+ 0x11c0, /* 000100011100 */
+ 0x20c0, /* 001000001100 */
+ 0x2060, /* 001000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x2040, /* 001000000100 */
+ 0x3040, /* 001100000100 */
+ 0x1880, /* 000110001000 */
+ 0x0f00, /* 000011110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 80 0x50 'P' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x7f80, /* 011111111000 */
+ 0x30c0, /* 001100001100 */
+ 0x3060, /* 001100000110 */
+ 0x3060, /* 001100000110 */
+ 0x3060, /* 001100000110 */
+ 0x30c0, /* 001100001100 */
+ 0x3780, /* 001101111000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x7800, /* 011110000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 81 0x51 'Q' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0f00, /* 000011110000 */
+ 0x11c0, /* 000100011100 */
+ 0x20c0, /* 001000001100 */
+ 0x2060, /* 001000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x3040, /* 001100000100 */
+ 0x3840, /* 001110000100 */
+ 0x1f80, /* 000111111000 */
+ 0x0e00, /* 000011100000 */
+ 0x1f00, /* 000111110000 */
+ 0x2390, /* 001000111001 */
+ 0x01e0, /* 000000011110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 82 0x52 'R' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xff00, /* 111111110000 */
+ 0x6180, /* 011000011000 */
+ 0x60c0, /* 011000001100 */
+ 0x60c0, /* 011000001100 */
+ 0x60c0, /* 011000001100 */
+ 0x6080, /* 011000001000 */
+ 0x7f00, /* 011111110000 */
+ 0x7c00, /* 011111000000 */
+ 0x6e00, /* 011011100000 */
+ 0x6700, /* 011001110000 */
+ 0x6380, /* 011000111000 */
+ 0x61c0, /* 011000011100 */
+ 0x60e0, /* 011000001110 */
+ 0xf070, /* 111100000111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 83 0x53 'S' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1fe0, /* 000111111110 */
+ 0x3060, /* 001100000110 */
+ 0x6020, /* 011000000010 */
+ 0x6020, /* 011000000010 */
+ 0x7000, /* 011100000000 */
+ 0x3c00, /* 001111000000 */
+ 0x1e00, /* 000111100000 */
+ 0x0780, /* 000001111000 */
+ 0x01c0, /* 000000011100 */
+ 0x00e0, /* 000000001110 */
+ 0x4060, /* 010000000110 */
+ 0x4060, /* 010000000110 */
+ 0x60c0, /* 011000001100 */
+ 0x7f80, /* 011111111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 84 0x54 'T' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x7fe0, /* 011111111110 */
+ 0x4620, /* 010001100010 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x1f80, /* 000111111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 85 0x55 'U' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xf070, /* 111100000111 */
+ 0x6020, /* 011000000010 */
+ 0x6020, /* 011000000010 */
+ 0x6020, /* 011000000010 */
+ 0x6020, /* 011000000010 */
+ 0x6020, /* 011000000010 */
+ 0x6020, /* 011000000010 */
+ 0x6020, /* 011000000010 */
+ 0x6020, /* 011000000010 */
+ 0x6020, /* 011000000010 */
+ 0x6020, /* 011000000010 */
+ 0x7040, /* 011100000100 */
+ 0x3fc0, /* 001111111100 */
+ 0x1f80, /* 000111111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 86 0x56 'V' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xe0e0, /* 111000001110 */
+ 0x6040, /* 011000000100 */
+ 0x3080, /* 001100001000 */
+ 0x3080, /* 001100001000 */
+ 0x3080, /* 001100001000 */
+ 0x1900, /* 000110010000 */
+ 0x1900, /* 000110010000 */
+ 0x1900, /* 000110010000 */
+ 0x0a00, /* 000010100000 */
+ 0x0e00, /* 000011100000 */
+ 0x0e00, /* 000011100000 */
+ 0x0400, /* 000001000000 */
+ 0x0400, /* 000001000000 */
+ 0x0400, /* 000001000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 87 0x57 'W' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xfef0, /* 111111101111 */
+ 0x6620, /* 011001100010 */
+ 0x6620, /* 011001100010 */
+ 0x6620, /* 011001100010 */
+ 0x7620, /* 011101100010 */
+ 0x7740, /* 011101110100 */
+ 0x3340, /* 001100110100 */
+ 0x3740, /* 001101110100 */
+ 0x3bc0, /* 001110111100 */
+ 0x3b80, /* 001110111000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 88 0x58 'X' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xf070, /* 111100000111 */
+ 0x6020, /* 011000000010 */
+ 0x3040, /* 001100000100 */
+ 0x3880, /* 001110001000 */
+ 0x1880, /* 000110001000 */
+ 0x0d00, /* 000011010000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0b00, /* 000010110000 */
+ 0x1180, /* 000100011000 */
+ 0x11c0, /* 000100011100 */
+ 0x20c0, /* 001000001100 */
+ 0x4060, /* 010000000110 */
+ 0xe0f0, /* 111000001111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 89 0x59 'Y' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xf070, /* 111100000111 */
+ 0x6020, /* 011000000010 */
+ 0x3040, /* 001100000100 */
+ 0x1880, /* 000110001000 */
+ 0x1880, /* 000110001000 */
+ 0x0d00, /* 000011010000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0f00, /* 000011110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 90 0x5a 'Z' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fe0, /* 001111111110 */
+ 0x20c0, /* 001000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x0180, /* 000000011000 */
+ 0x0180, /* 000000011000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x1800, /* 000110000000 */
+ 0x1820, /* 000110000010 */
+ 0x3fe0, /* 001111111110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 91 0x5b '[' */
+ 0x0000, /* 000000000000 */
+ 0x0f80, /* 000011111000 */
+ 0x0f80, /* 000011111000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0f80, /* 000011111000 */
+ 0x0f80, /* 000011111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 92 0x5c '\' */
+ 0x0000, /* 000000000000 */
+ 0x6000, /* 011000000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x1800, /* 000110000000 */
+ 0x1800, /* 000110000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0180, /* 000000011000 */
+ 0x0180, /* 000000011000 */
+ 0x00c0, /* 000000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x0060, /* 000000000110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 93 0x5d ']' */
+ 0x0000, /* 000000000000 */
+ 0x1f00, /* 000111110000 */
+ 0x1f00, /* 000111110000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x1f00, /* 000111110000 */
+ 0x1f00, /* 000111110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 94 0x5e '^' */
+ 0x0000, /* 000000000000 */
+ 0x0400, /* 000001000000 */
+ 0x0e00, /* 000011100000 */
+ 0x1b00, /* 000110110000 */
+ 0x3180, /* 001100011000 */
+ 0x60c0, /* 011000001100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 95 0x5f '_' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 96 0x60 '`' */
+ 0x0000, /* 000000000000 */
+ 0x0100, /* 000000010000 */
+ 0x0300, /* 000000110000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0780, /* 000001111000 */
+ 0x0780, /* 000001111000 */
+ 0x0300, /* 000000110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 97 0x61 'a' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0f80, /* 000011111000 */
+ 0x18c0, /* 000110001100 */
+ 0x10c0, /* 000100001100 */
+ 0x03c0, /* 000000111100 */
+ 0x1cc0, /* 000111001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x39c0, /* 001110011100 */
+ 0x1ee0, /* 000111101110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 98 0x62 'b' */
+ 0x0000, /* 000000000000 */
+ 0x2000, /* 001000000000 */
+ 0x6000, /* 011000000000 */
+ 0xe000, /* 111000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6780, /* 011001111000 */
+ 0x6fc0, /* 011011111100 */
+ 0x70e0, /* 011100001110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x7060, /* 011100000110 */
+ 0x78c0, /* 011110001100 */
+ 0x4f80, /* 010011111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 99 0x63 'c' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1f80, /* 000111111000 */
+ 0x31c0, /* 001100011100 */
+ 0x20c0, /* 001000001100 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x7040, /* 011100000100 */
+ 0x30c0, /* 001100001100 */
+ 0x1f80, /* 000111111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 100 0x64 'd' */
+ 0x0000, /* 000000000000 */
+ 0x0060, /* 000000000110 */
+ 0x00e0, /* 000000001110 */
+ 0x0060, /* 000000000110 */
+ 0x0060, /* 000000000110 */
+ 0x0060, /* 000000000110 */
+ 0x0f60, /* 000011110110 */
+ 0x31e0, /* 001100011110 */
+ 0x20e0, /* 001000001110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x70e0, /* 011100001110 */
+ 0x3960, /* 001110010110 */
+ 0x1e70, /* 000111100111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 101 0x65 'e' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0f00, /* 000011110000 */
+ 0x30c0, /* 001100001100 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x7fe0, /* 011111111110 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x3000, /* 001100000000 */
+ 0x1860, /* 000110000110 */
+ 0x0f80, /* 000011111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 102 0x66 'f' */
+ 0x0000, /* 000000000000 */
+ 0x0380, /* 000000111000 */
+ 0x04c0, /* 000001001100 */
+ 0x04c0, /* 000001001100 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x3f80, /* 001111111000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x1e00, /* 000111100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 103 0x67 'g' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1f20, /* 000111110010 */
+ 0x31e0, /* 001100011110 */
+ 0x60c0, /* 011000001100 */
+ 0x60c0, /* 011000001100 */
+ 0x60c0, /* 011000001100 */
+ 0x3180, /* 001100011000 */
+ 0x3f00, /* 001111110000 */
+ 0x6000, /* 011000000000 */
+ 0x7fc0, /* 011111111100 */
+ 0x3fe0, /* 001111111110 */
+ 0x2060, /* 001000000110 */
+ 0x4020, /* 010000000010 */
+ 0x4020, /* 010000000010 */
+ 0x7fc0, /* 011111111100 */
+ 0x3f80, /* 001111111000 */
+ 0x0000, /* 000000000000 */
+
+ /* 104 0x68 'h' */
+ 0x0000, /* 000000000000 */
+ 0x1000, /* 000100000000 */
+ 0x3000, /* 001100000000 */
+ 0x7000, /* 011100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3780, /* 001101111000 */
+ 0x39c0, /* 001110011100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x79e0, /* 011110011110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 105 0x69 'i' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1e00, /* 000111100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x1f80, /* 000111111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 106 0x6a 'j' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x00c0, /* 000000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x03c0, /* 000000111100 */
+ 0x00c0, /* 000000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x20c0, /* 001000001100 */
+ 0x30c0, /* 001100001100 */
+ 0x3880, /* 001110001000 */
+ 0x1f00, /* 000111110000 */
+ 0x0e00, /* 000011100000 */
+ 0x0000, /* 000000000000 */
+
+ /* 107 0x6b 'k' */
+ 0x0000, /* 000000000000 */
+ 0x6000, /* 011000000000 */
+ 0xe000, /* 111000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x61c0, /* 011000011100 */
+ 0x6300, /* 011000110000 */
+ 0x6600, /* 011001100000 */
+ 0x7c00, /* 011111000000 */
+ 0x7800, /* 011110000000 */
+ 0x7c00, /* 011111000000 */
+ 0x6e00, /* 011011100000 */
+ 0x6700, /* 011001110000 */
+ 0x6380, /* 011000111000 */
+ 0xf1e0, /* 111100011110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 108 0x6c 'l' */
+ 0x0000, /* 000000000000 */
+ 0x1e00, /* 000111100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x1f80, /* 000111111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 109 0x6d 'm' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xddc0, /* 110111011100 */
+ 0x6ee0, /* 011011101110 */
+ 0x6660, /* 011001100110 */
+ 0x6660, /* 011001100110 */
+ 0x6660, /* 011001100110 */
+ 0x6660, /* 011001100110 */
+ 0x6660, /* 011001100110 */
+ 0x6660, /* 011001100110 */
+ 0x6660, /* 011001100110 */
+ 0xef70, /* 111011110111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 110 0x6e 'n' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x2780, /* 001001111000 */
+ 0x79c0, /* 011110011100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x79e0, /* 011110011110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 111 0x6f 'o' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0f80, /* 000011111000 */
+ 0x11c0, /* 000100011100 */
+ 0x20e0, /* 001000001110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x7040, /* 011100000100 */
+ 0x3880, /* 001110001000 */
+ 0x1f00, /* 000111110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 112 0x70 'p' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xef80, /* 111011111000 */
+ 0x71c0, /* 011100011100 */
+ 0x60e0, /* 011000001110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6040, /* 011000000100 */
+ 0x7080, /* 011100001000 */
+ 0x7f00, /* 011111110000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0xf000, /* 111100000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 113 0x71 'q' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0f20, /* 000011110010 */
+ 0x11e0, /* 000100011110 */
+ 0x20e0, /* 001000001110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x7060, /* 011100000110 */
+ 0x38e0, /* 001110001110 */
+ 0x1fe0, /* 000111111110 */
+ 0x0060, /* 000000000110 */
+ 0x0060, /* 000000000110 */
+ 0x0060, /* 000000000110 */
+ 0x0060, /* 000000000110 */
+ 0x00f0, /* 000000001111 */
+ 0x0000, /* 000000000000 */
+
+ /* 114 0x72 'r' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x7380, /* 011100111000 */
+ 0x34c0, /* 001101001100 */
+ 0x38c0, /* 001110001100 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x7800, /* 011110000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 115 0x73 's' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1fc0, /* 000111111100 */
+ 0x30c0, /* 001100001100 */
+ 0x3040, /* 001100000100 */
+ 0x3800, /* 001110000000 */
+ 0x1e00, /* 000111100000 */
+ 0x0780, /* 000001111000 */
+ 0x01c0, /* 000000011100 */
+ 0x20c0, /* 001000001100 */
+ 0x30c0, /* 001100001100 */
+ 0x3f80, /* 001111111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 116 0x74 't' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0400, /* 000001000000 */
+ 0x0400, /* 000001000000 */
+ 0x0c00, /* 000011000000 */
+ 0x7fc0, /* 011111111100 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0c20, /* 000011000010 */
+ 0x0e40, /* 000011100100 */
+ 0x0780, /* 000001111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 117 0x75 'u' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x79e0, /* 011110011110 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x39c0, /* 001110011100 */
+ 0x1e60, /* 000111100110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 118 0x76 'v' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xf070, /* 111100000111 */
+ 0x6020, /* 011000000010 */
+ 0x3040, /* 001100000100 */
+ 0x3040, /* 001100000100 */
+ 0x1880, /* 000110001000 */
+ 0x1880, /* 000110001000 */
+ 0x0d00, /* 000011010000 */
+ 0x0d00, /* 000011010000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 119 0x77 'w' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xff70, /* 111111110111 */
+ 0x6620, /* 011001100010 */
+ 0x6620, /* 011001100010 */
+ 0x6620, /* 011001100010 */
+ 0x3740, /* 001101110100 */
+ 0x3b40, /* 001110110100 */
+ 0x3b40, /* 001110110100 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 120 0x78 'x' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xf8f0, /* 111110001111 */
+ 0x7040, /* 011100000100 */
+ 0x3880, /* 001110001000 */
+ 0x1d00, /* 000111010000 */
+ 0x0e00, /* 000011100000 */
+ 0x0700, /* 000001110000 */
+ 0x0b80, /* 000010111000 */
+ 0x11c0, /* 000100011100 */
+ 0x20e0, /* 001000001110 */
+ 0xf1f0, /* 111100011111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 121 0x79 'y' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xf0f0, /* 111100001111 */
+ 0x6020, /* 011000000010 */
+ 0x3040, /* 001100000100 */
+ 0x3040, /* 001100000100 */
+ 0x1880, /* 000110001000 */
+ 0x1880, /* 000110001000 */
+ 0x0d00, /* 000011010000 */
+ 0x0d00, /* 000011010000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0400, /* 000001000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0800, /* 000010000000 */
+ 0x7800, /* 011110000000 */
+ 0x7000, /* 011100000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 122 0x7a 'z' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x7fe0, /* 011111111110 */
+ 0x60e0, /* 011000001110 */
+ 0x41c0, /* 010000011100 */
+ 0x0380, /* 000000111000 */
+ 0x0700, /* 000001110000 */
+ 0x0e00, /* 000011100000 */
+ 0x1c00, /* 000111000000 */
+ 0x3820, /* 001110000010 */
+ 0x7060, /* 011100000110 */
+ 0x7fe0, /* 011111111110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 123 0x7b '{' */
+ 0x0000, /* 000000000000 */
+ 0x0380, /* 000000111000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0c00, /* 000011000000 */
+ 0x3800, /* 001110000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0380, /* 000000111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 124 0x7c '|' */
+ 0x0000, /* 000000000000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+
+ /* 125 0x7d '}' */
+ 0x0000, /* 000000000000 */
+ 0x1c00, /* 000111000000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0300, /* 000000110000 */
+ 0x01c0, /* 000000011100 */
+ 0x0300, /* 000000110000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x1c00, /* 000111000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 126 0x7e '~' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1c20, /* 000111000010 */
+ 0x3e60, /* 001111100110 */
+ 0x67c0, /* 011001111100 */
+ 0x4380, /* 010000111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 127 0x7f '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 128 0x80 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0fc0, /* 000011111100 */
+ 0x1060, /* 000100000110 */
+ 0x2020, /* 001000000010 */
+ 0x2000, /* 001000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x2000, /* 001000000000 */
+ 0x3020, /* 001100000010 */
+ 0x1840, /* 000110000100 */
+ 0x0f80, /* 000011111000 */
+ 0x0600, /* 000001100000 */
+ 0x0300, /* 000000110000 */
+ 0x0180, /* 000000011000 */
+ 0x0f00, /* 000011110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 129 0x81 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x79e0, /* 011110011110 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x39c0, /* 001110011100 */
+ 0x1e60, /* 000111100110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 130 0x82 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0180, /* 000000011000 */
+ 0x0300, /* 000000110000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x0f00, /* 000011110000 */
+ 0x30c0, /* 001100001100 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x7fe0, /* 011111111110 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x3000, /* 001100000000 */
+ 0x1860, /* 000110000110 */
+ 0x0f80, /* 000011111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 131 0x83 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0200, /* 000000100000 */
+ 0x0700, /* 000001110000 */
+ 0x0d80, /* 000011011000 */
+ 0x18c0, /* 000110001100 */
+ 0x0000, /* 000000000000 */
+ 0x0f80, /* 000011111000 */
+ 0x18c0, /* 000110001100 */
+ 0x10c0, /* 000100001100 */
+ 0x03c0, /* 000000111100 */
+ 0x1cc0, /* 000111001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x39c0, /* 001110011100 */
+ 0x1ee0, /* 000111101110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 132 0x84 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0f80, /* 000011111000 */
+ 0x18c0, /* 000110001100 */
+ 0x10c0, /* 000100001100 */
+ 0x03c0, /* 000000111100 */
+ 0x1cc0, /* 000111001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x39c0, /* 001110011100 */
+ 0x1ee0, /* 000111101110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 133 0x85 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0600, /* 000001100000 */
+ 0x0300, /* 000000110000 */
+ 0x0000, /* 000000000000 */
+ 0x0f80, /* 000011111000 */
+ 0x18c0, /* 000110001100 */
+ 0x10c0, /* 000100001100 */
+ 0x03c0, /* 000000111100 */
+ 0x1cc0, /* 000111001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x39c0, /* 001110011100 */
+ 0x1ee0, /* 000111101110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 134 0x86 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0700, /* 000001110000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0700, /* 000001110000 */
+ 0x0000, /* 000000000000 */
+ 0x0f80, /* 000011111000 */
+ 0x18c0, /* 000110001100 */
+ 0x10c0, /* 000100001100 */
+ 0x03c0, /* 000000111100 */
+ 0x1cc0, /* 000111001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x39c0, /* 001110011100 */
+ 0x1ee0, /* 000111101110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 135 0x87 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1f80, /* 000111111000 */
+ 0x31c0, /* 001100011100 */
+ 0x20c0, /* 001000001100 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x7040, /* 011100000100 */
+ 0x30c0, /* 001100001100 */
+ 0x1f80, /* 000111111000 */
+ 0x0600, /* 000001100000 */
+ 0x0300, /* 000000110000 */
+ 0x0180, /* 000000011000 */
+ 0x0f00, /* 000011110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 136 0x88 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0200, /* 000000100000 */
+ 0x0700, /* 000001110000 */
+ 0x0d80, /* 000011011000 */
+ 0x18c0, /* 000110001100 */
+ 0x0000, /* 000000000000 */
+ 0x0f00, /* 000011110000 */
+ 0x30c0, /* 001100001100 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x7fe0, /* 011111111110 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x3000, /* 001100000000 */
+ 0x1860, /* 000110000110 */
+ 0x0f80, /* 000011111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 137 0x89 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0f00, /* 000011110000 */
+ 0x30c0, /* 001100001100 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x7fe0, /* 011111111110 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x3000, /* 001100000000 */
+ 0x1860, /* 000110000110 */
+ 0x0f80, /* 000011111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 138 0x8a '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0600, /* 000001100000 */
+ 0x0300, /* 000000110000 */
+ 0x0000, /* 000000000000 */
+ 0x0f00, /* 000011110000 */
+ 0x30c0, /* 001100001100 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x7fe0, /* 011111111110 */
+ 0x6000, /* 011000000000 */
+ 0x6000, /* 011000000000 */
+ 0x3000, /* 001100000000 */
+ 0x1860, /* 000110000110 */
+ 0x0f80, /* 000011111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 139 0x8b '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1e00, /* 000111100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x1f80, /* 000111111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 140 0x8c '.' */
+ 0x0000, /* 000000000000 */
+ 0x0400, /* 000001000000 */
+ 0x0e00, /* 000011100000 */
+ 0x1b00, /* 000110110000 */
+ 0x3180, /* 001100011000 */
+ 0x0000, /* 000000000000 */
+ 0x1e00, /* 000111100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x1f80, /* 000111111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 141 0x8d '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1800, /* 000110000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x1e00, /* 000111100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x1f80, /* 000111111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 142 0x8e '.' */
+ 0x0000, /* 000000000000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x0000, /* 000000000000 */
+ 0x0400, /* 000001000000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0b00, /* 000010110000 */
+ 0x0b00, /* 000010110000 */
+ 0x1980, /* 000110011000 */
+ 0x1180, /* 000100011000 */
+ 0x3fc0, /* 001111111100 */
+ 0x20c0, /* 001000001100 */
+ 0x6060, /* 011000000110 */
+ 0x4060, /* 010000000110 */
+ 0xe0f0, /* 111000001111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 143 0x8f '.' */
+ 0x0000, /* 000000000000 */
+ 0x0f00, /* 000011110000 */
+ 0x1980, /* 000110011000 */
+ 0x0f00, /* 000011110000 */
+ 0x0400, /* 000001000000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0b00, /* 000010110000 */
+ 0x0b00, /* 000010110000 */
+ 0x1980, /* 000110011000 */
+ 0x1180, /* 000100011000 */
+ 0x3fc0, /* 001111111100 */
+ 0x20c0, /* 001000001100 */
+ 0x6060, /* 011000000110 */
+ 0x4060, /* 010000000110 */
+ 0xe0f0, /* 111000001111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 144 0x90 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0300, /* 000000110000 */
+ 0x0600, /* 000001100000 */
+ 0x0800, /* 000010000000 */
+ 0x7fe0, /* 011111111110 */
+ 0x3020, /* 001100000010 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3080, /* 001100001000 */
+ 0x3f80, /* 001111111000 */
+ 0x3080, /* 001100001000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3020, /* 001100000010 */
+ 0x3020, /* 001100000010 */
+ 0x7fe0, /* 011111111110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 145 0x91 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3de0, /* 001111011110 */
+ 0x6630, /* 011001100011 */
+ 0x4630, /* 010001100011 */
+ 0x0630, /* 000001100011 */
+ 0x3ff0, /* 001111111111 */
+ 0x6600, /* 011001100000 */
+ 0xc600, /* 110001100000 */
+ 0xc600, /* 110001100000 */
+ 0xe730, /* 111001110011 */
+ 0x7de0, /* 011111011110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 146 0x92 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x03f0, /* 000000111111 */
+ 0x0710, /* 000001110001 */
+ 0x0710, /* 000001110001 */
+ 0x0b00, /* 000010110000 */
+ 0x0b00, /* 000010110000 */
+ 0x0b20, /* 000010110010 */
+ 0x13e0, /* 000100111110 */
+ 0x1320, /* 000100110010 */
+ 0x3f00, /* 001111110000 */
+ 0x2300, /* 001000110000 */
+ 0x2300, /* 001000110000 */
+ 0x4310, /* 010000110001 */
+ 0x4310, /* 010000110001 */
+ 0xe7f0, /* 111001111111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 147 0x93 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0200, /* 000000100000 */
+ 0x0700, /* 000001110000 */
+ 0x0d80, /* 000011011000 */
+ 0x18c0, /* 000110001100 */
+ 0x0000, /* 000000000000 */
+ 0x0f80, /* 000011111000 */
+ 0x11c0, /* 000100011100 */
+ 0x20e0, /* 001000001110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x7040, /* 011100000100 */
+ 0x3880, /* 001110001000 */
+ 0x1f00, /* 000111110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 148 0x94 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0f80, /* 000011111000 */
+ 0x11c0, /* 000100011100 */
+ 0x20e0, /* 001000001110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x7040, /* 011100000100 */
+ 0x3880, /* 001110001000 */
+ 0x1f00, /* 000111110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 149 0x95 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0600, /* 000001100000 */
+ 0x0300, /* 000000110000 */
+ 0x0000, /* 000000000000 */
+ 0x0f80, /* 000011111000 */
+ 0x11c0, /* 000100011100 */
+ 0x20e0, /* 001000001110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x7040, /* 011100000100 */
+ 0x3880, /* 001110001000 */
+ 0x1f00, /* 000111110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 150 0x96 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0200, /* 000000100000 */
+ 0x0700, /* 000001110000 */
+ 0x0d80, /* 000011011000 */
+ 0x18c0, /* 000110001100 */
+ 0x0000, /* 000000000000 */
+ 0x79e0, /* 011110011110 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x39c0, /* 001110011100 */
+ 0x1e60, /* 000111100110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 151 0x97 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1800, /* 000110000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x79e0, /* 011110011110 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x39c0, /* 001110011100 */
+ 0x1e60, /* 000111100110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 152 0x98 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xf0f0, /* 111100001111 */
+ 0x6020, /* 011000000010 */
+ 0x3040, /* 001100000100 */
+ 0x3040, /* 001100000100 */
+ 0x1880, /* 000110001000 */
+ 0x1880, /* 000110001000 */
+ 0x0d00, /* 000011010000 */
+ 0x0d00, /* 000011010000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0400, /* 000001000000 */
+ 0x0c00, /* 000011000000 */
+ 0x0800, /* 000010000000 */
+ 0x7800, /* 011110000000 */
+ 0x7000, /* 011100000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 153 0x99 '.' */
+ 0x0000, /* 000000000000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x0000, /* 000000000000 */
+ 0x0f80, /* 000011111000 */
+ 0x11c0, /* 000100011100 */
+ 0x20c0, /* 001000001100 */
+ 0x2060, /* 001000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x2040, /* 001000000100 */
+ 0x3040, /* 001100000100 */
+ 0x1880, /* 000110001000 */
+ 0x0f00, /* 000011110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 154 0x9a '.' */
+ 0x0000, /* 000000000000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0xe030, /* 111000000011 */
+ 0x6020, /* 011000000010 */
+ 0x6020, /* 011000000010 */
+ 0x6020, /* 011000000010 */
+ 0x6020, /* 011000000010 */
+ 0x6020, /* 011000000010 */
+ 0x6020, /* 011000000010 */
+ 0x6020, /* 011000000010 */
+ 0x6020, /* 011000000010 */
+ 0x6020, /* 011000000010 */
+ 0x7040, /* 011100000100 */
+ 0x3fc0, /* 001111111100 */
+ 0x1f80, /* 000111111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 155 0x9b '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x1f80, /* 000111111000 */
+ 0x36c0, /* 001101101100 */
+ 0x26c0, /* 001001101100 */
+ 0x6600, /* 011001100000 */
+ 0x6600, /* 011001100000 */
+ 0x6600, /* 011001100000 */
+ 0x6600, /* 011001100000 */
+ 0x7640, /* 011101100100 */
+ 0x36c0, /* 001101101100 */
+ 0x1f80, /* 000111111000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 156 0x9c '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0f80, /* 000011111000 */
+ 0x1cc0, /* 000111001100 */
+ 0x18c0, /* 000110001100 */
+ 0x1800, /* 000110000000 */
+ 0x1800, /* 000110000000 */
+ 0x1800, /* 000110000000 */
+ 0x7e00, /* 011111100000 */
+ 0x7e00, /* 011111100000 */
+ 0x1800, /* 000110000000 */
+ 0x1800, /* 000110000000 */
+ 0x1800, /* 000110000000 */
+ 0x1800, /* 000110000000 */
+ 0x3e20, /* 001111100010 */
+ 0x7fe0, /* 011111111110 */
+ 0x61c0, /* 011000011100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 157 0x9d '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x30c0, /* 001100001100 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x0f00, /* 000011110000 */
+ 0x0600, /* 000001100000 */
+ 0x1f80, /* 000111111000 */
+ 0x0600, /* 000001100000 */
+ 0x1f80, /* 000111111000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 158 0x9e '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 159 0x9f '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 160 0xa0 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0180, /* 000000011000 */
+ 0x0300, /* 000000110000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x0f80, /* 000011111000 */
+ 0x18c0, /* 000110001100 */
+ 0x10c0, /* 000100001100 */
+ 0x03c0, /* 000000111100 */
+ 0x1cc0, /* 000111001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x39c0, /* 001110011100 */
+ 0x1ee0, /* 000111101110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 161 0xa1 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0180, /* 000000011000 */
+ 0x0300, /* 000000110000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x1e00, /* 000111100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x1f80, /* 000111111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 162 0xa2 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0180, /* 000000011000 */
+ 0x0300, /* 000000110000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x0f80, /* 000011111000 */
+ 0x11c0, /* 000100011100 */
+ 0x20e0, /* 001000001110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x6060, /* 011000000110 */
+ 0x7040, /* 011100000100 */
+ 0x3880, /* 001110001000 */
+ 0x1f00, /* 000111110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 163 0xa3 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0180, /* 000000011000 */
+ 0x0300, /* 000000110000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x79e0, /* 011110011110 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x39c0, /* 001110011100 */
+ 0x1e60, /* 000111100110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 164 0xa4 '.' */
+ 0x0000, /* 000000000000 */
+ 0x1c40, /* 000111000100 */
+ 0x3fc0, /* 001111111100 */
+ 0x2380, /* 001000111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x2780, /* 001001111000 */
+ 0x79c0, /* 011110011100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x79e0, /* 011110011110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 165 0xa5 '.' */
+ 0x0000, /* 000000000000 */
+ 0x1c40, /* 000111000100 */
+ 0x3fc0, /* 001111111100 */
+ 0x2380, /* 001000111000 */
+ 0xc070, /* 110000000111 */
+ 0x6020, /* 011000000010 */
+ 0x7020, /* 011100000010 */
+ 0x7820, /* 011110000010 */
+ 0x5c20, /* 010111000010 */
+ 0x4e20, /* 010011100010 */
+ 0x4720, /* 010001110010 */
+ 0x43a0, /* 010000111010 */
+ 0x41e0, /* 010000011110 */
+ 0x40e0, /* 010000001110 */
+ 0x4060, /* 010000000110 */
+ 0xe030, /* 111000000011 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 166 0xa6 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1f00, /* 000111110000 */
+ 0x3180, /* 001100011000 */
+ 0x0180, /* 000000011000 */
+ 0x0780, /* 000001111000 */
+ 0x1980, /* 000110011000 */
+ 0x3180, /* 001100011000 */
+ 0x3180, /* 001100011000 */
+ 0x3380, /* 001100111000 */
+ 0x1dc0, /* 000111011100 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 167 0xa7 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0700, /* 000001110000 */
+ 0x1980, /* 000110011000 */
+ 0x10c0, /* 000100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x3080, /* 001100001000 */
+ 0x1980, /* 000110011000 */
+ 0x0e00, /* 000011100000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 168 0xa8 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0300, /* 000000110000 */
+ 0x0300, /* 000000110000 */
+ 0x0600, /* 000001100000 */
+ 0x0c00, /* 000011000000 */
+ 0x1800, /* 000110000000 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x3040, /* 001100000100 */
+ 0x39c0, /* 001110011100 */
+ 0x1f80, /* 000111111000 */
+ 0x0f00, /* 000011110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 169 0xa9 '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 170 0xaa '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x00c0, /* 000000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x00c0, /* 000000001100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 171 0xab '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1000, /* 000100000000 */
+ 0x3000, /* 001100000000 */
+ 0x1000, /* 000100000000 */
+ 0x1040, /* 000100000100 */
+ 0x1080, /* 000100001000 */
+ 0x1100, /* 000100010000 */
+ 0x3a00, /* 001110100000 */
+ 0x05c0, /* 000001011100 */
+ 0x0a20, /* 000010100010 */
+ 0x1020, /* 000100000010 */
+ 0x20c0, /* 001000001100 */
+ 0x4100, /* 010000010000 */
+ 0x0200, /* 000000100000 */
+ 0x03e0, /* 000000111110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 172 0xac '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x1000, /* 000100000000 */
+ 0x3000, /* 001100000000 */
+ 0x1000, /* 000100000000 */
+ 0x1040, /* 000100000100 */
+ 0x1080, /* 000100001000 */
+ 0x1100, /* 000100010000 */
+ 0x3a40, /* 001110100100 */
+ 0x04c0, /* 000001001100 */
+ 0x0940, /* 000010010100 */
+ 0x1240, /* 000100100100 */
+ 0x2440, /* 001001000100 */
+ 0x47e0, /* 010001111110 */
+ 0x0040, /* 000000000100 */
+ 0x0040, /* 000000000100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 173 0xad '.' */
+ 0x0000, /* 000000000000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 174 0xae '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0660, /* 000001100110 */
+ 0x0cc0, /* 000011001100 */
+ 0x1980, /* 000110011000 */
+ 0x3300, /* 001100110000 */
+ 0x6600, /* 011001100000 */
+ 0x3300, /* 001100110000 */
+ 0x1980, /* 000110011000 */
+ 0x0cc0, /* 000011001100 */
+ 0x0660, /* 000001100110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 175 0xaf '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x6600, /* 011001100000 */
+ 0x3300, /* 001100110000 */
+ 0x1980, /* 000110011000 */
+ 0x0cc0, /* 000011001100 */
+ 0x0660, /* 000001100110 */
+ 0x0cc0, /* 000011001100 */
+ 0x1980, /* 000110011000 */
+ 0x3300, /* 001100110000 */
+ 0x6600, /* 011001100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 176 0xb0 '.' */
+ 0x0c30, /* 000011000011 */
+ 0x0820, /* 000010000010 */
+ 0x6180, /* 011000011000 */
+ 0x2080, /* 001000001000 */
+ 0x0c30, /* 000011000011 */
+ 0x0820, /* 000010000010 */
+ 0x6180, /* 011000011000 */
+ 0x2080, /* 001000001000 */
+ 0x0c30, /* 000011000011 */
+ 0x0820, /* 000010000010 */
+ 0x6180, /* 011000011000 */
+ 0x2080, /* 001000001000 */
+ 0x0c30, /* 000011000011 */
+ 0x0820, /* 000010000010 */
+ 0x6180, /* 011000011000 */
+ 0x2080, /* 001000001000 */
+ 0x0c30, /* 000011000011 */
+ 0x0820, /* 000010000010 */
+ 0x6180, /* 011000011000 */
+ 0x2080, /* 001000001000 */
+ 0x0c30, /* 000011000011 */
+ 0x0820, /* 000010000010 */
+
+ /* 177 0xb1 '.' */
+ 0x7770, /* 011101110111 */
+ 0x2220, /* 001000100010 */
+ 0x8880, /* 100010001000 */
+ 0xddd0, /* 110111011101 */
+ 0x8880, /* 100010001000 */
+ 0x2220, /* 001000100010 */
+ 0x7770, /* 011101110111 */
+ 0x2220, /* 001000100010 */
+ 0x8880, /* 100010001000 */
+ 0xddd0, /* 110111011101 */
+ 0x8880, /* 100010001000 */
+ 0x2220, /* 001000100010 */
+ 0x7770, /* 011101110111 */
+ 0x2220, /* 001000100010 */
+ 0x8880, /* 100010001000 */
+ 0xddd0, /* 110111011101 */
+ 0x8880, /* 100010001000 */
+ 0x2220, /* 001000100010 */
+ 0x7770, /* 011101110111 */
+ 0x2220, /* 001000100010 */
+ 0x8880, /* 100010001000 */
+ 0xddd0, /* 110111011101 */
+
+ /* 178 0xb2 '.' */
+ 0xf3c0, /* 111100111100 */
+ 0xf7d0, /* 111101111101 */
+ 0x9e70, /* 100111100111 */
+ 0xdf70, /* 110111110111 */
+ 0xf3c0, /* 111100111100 */
+ 0xf7d0, /* 111101111101 */
+ 0x9e70, /* 100111100111 */
+ 0xdf70, /* 110111110111 */
+ 0xf3c0, /* 111100111100 */
+ 0xf7d0, /* 111101111101 */
+ 0x9e70, /* 100111100111 */
+ 0xdf70, /* 110111110111 */
+ 0xf3c0, /* 111100111100 */
+ 0xf7d0, /* 111101111101 */
+ 0x9e70, /* 100111100111 */
+ 0xdf70, /* 110111110111 */
+ 0xf3c0, /* 111100111100 */
+ 0xf7d0, /* 111101111101 */
+ 0x9e70, /* 100111100111 */
+ 0xdf70, /* 110111110111 */
+ 0xf3c0, /* 111100111100 */
+ 0xf7d0, /* 111101111101 */
+
+ /* 179 0xb3 '.' */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+
+ /* 180 0xb4 '.' */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0xfe00, /* 111111100000 */
+ 0xfe00, /* 111111100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+
+ /* 181 0xb5 '.' */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0xfe00, /* 111111100000 */
+ 0xfe00, /* 111111100000 */
+ 0x0600, /* 000001100000 */
+ 0xfe00, /* 111111100000 */
+ 0xfe00, /* 111111100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+
+ /* 182 0xb6 '.' */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0xfd80, /* 111111011000 */
+ 0xfd80, /* 111111011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+
+ /* 183 0xb7 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xff80, /* 111111111000 */
+ 0xff80, /* 111111111000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+
+ /* 184 0xb8 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xfe00, /* 111111100000 */
+ 0xfe00, /* 111111100000 */
+ 0x0600, /* 000001100000 */
+ 0xfe00, /* 111111100000 */
+ 0xfe00, /* 111111100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+
+ /* 185 0xb9 '.' */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0xfd80, /* 111111011000 */
+ 0xfd80, /* 111111011000 */
+ 0x0180, /* 000000011000 */
+ 0xfd80, /* 111111011000 */
+ 0xfd80, /* 111111011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+
+ /* 186 0xba '.' */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+
+ /* 187 0xbb '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xff80, /* 111111111000 */
+ 0xff80, /* 111111111000 */
+ 0x0180, /* 000000011000 */
+ 0xfd80, /* 111111011000 */
+ 0xfd80, /* 111111011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+
+ /* 188 0xbc '.' */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0xfd80, /* 111111011000 */
+ 0xfd80, /* 111111011000 */
+ 0x0180, /* 000000011000 */
+ 0xff80, /* 111111111000 */
+ 0xff80, /* 111111111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 189 0xbd '.' */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0xff80, /* 111111111000 */
+ 0xff80, /* 111111111000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 190 0xbe '.' */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0xfe00, /* 111111100000 */
+ 0xfe00, /* 111111100000 */
+ 0x0600, /* 000001100000 */
+ 0xfe00, /* 111111100000 */
+ 0xfe00, /* 111111100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 191 0xbf '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xfe00, /* 111111100000 */
+ 0xfe00, /* 111111100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+
+ /* 192 0xc0 '.' */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x07f0, /* 000001111111 */
+ 0x07f0, /* 000001111111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 193 0xc1 '.' */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 194 0xc2 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+
+ /* 195 0xc3 '.' */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x07f0, /* 000001111111 */
+ 0x07f0, /* 000001111111 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+
+ /* 196 0xc4 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 197 0xc5 '.' */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+
+ /* 198 0xc6 '.' */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x07f0, /* 000001111111 */
+ 0x07f0, /* 000001111111 */
+ 0x0600, /* 000001100000 */
+ 0x07f0, /* 000001111111 */
+ 0x07f0, /* 000001111111 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+
+ /* 199 0xc7 '.' */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0df0, /* 000011011111 */
+ 0x0df0, /* 000011011111 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+
+ /* 200 0xc8 '.' */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0df0, /* 000011011111 */
+ 0x0df0, /* 000011011111 */
+ 0x0c00, /* 000011000000 */
+ 0x0ff0, /* 000011111111 */
+ 0x0ff0, /* 000011111111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 201 0xc9 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0ff0, /* 000011111111 */
+ 0x0ff0, /* 000011111111 */
+ 0x0c00, /* 000011000000 */
+ 0x0df0, /* 000011011111 */
+ 0x0df0, /* 000011011111 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+
+ /* 202 0xca '.' */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0xfdf0, /* 111111011111 */
+ 0xfdf0, /* 111111011111 */
+ 0x0000, /* 000000000000 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 203 0xcb '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0x0000, /* 000000000000 */
+ 0xfdf0, /* 111111011111 */
+ 0xfdf0, /* 111111011111 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+
+ /* 204 0xcc '.' */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0df0, /* 000011011111 */
+ 0x0df0, /* 000011011111 */
+ 0x0c00, /* 000011000000 */
+ 0x0df0, /* 000011011111 */
+ 0x0df0, /* 000011011111 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+
+ /* 205 0xcd '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0x0000, /* 000000000000 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 206 0xce '.' */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0xfdf0, /* 111111011111 */
+ 0xfdf0, /* 111111011111 */
+ 0x0000, /* 000000000000 */
+ 0xfdf0, /* 111111011111 */
+ 0xfdf0, /* 111111011111 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+
+ /* 207 0xcf '.' */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0x0000, /* 000000000000 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 208 0xd0 '.' */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 209 0xd1 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0x0000, /* 000000000000 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+
+ /* 210 0xd2 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+
+ /* 211 0xd3 '.' */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0ff0, /* 000011111111 */
+ 0x0ff0, /* 000011111111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 212 0xd4 '.' */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x07f0, /* 000001111111 */
+ 0x07f0, /* 000001111111 */
+ 0x0600, /* 000001100000 */
+ 0x07f0, /* 000001111111 */
+ 0x07f0, /* 000001111111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 213 0xd5 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x07f0, /* 000001111111 */
+ 0x07f0, /* 000001111111 */
+ 0x0600, /* 000001100000 */
+ 0x07f0, /* 000001111111 */
+ 0x07f0, /* 000001111111 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+
+ /* 214 0xd6 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0ff0, /* 000011111111 */
+ 0x0ff0, /* 000011111111 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+
+ /* 215 0xd7 '.' */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+ 0x0d80, /* 000011011000 */
+
+ /* 216 0xd8 '.' */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0x0600, /* 000001100000 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+
+ /* 217 0xd9 '.' */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0xfe00, /* 111111100000 */
+ 0xfe00, /* 111111100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 218 0xda '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x07f0, /* 000001111111 */
+ 0x07f0, /* 000001111111 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+
+ /* 219 0xdb '.' */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+
+ /* 220 0xdc '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+
+ /* 221 0xdd '.' */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+ 0xfc00, /* 111111000000 */
+
+ /* 222 0xde '.' */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+ 0x03f0, /* 000000111111 */
+
+ /* 223 0xdf '.' */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0xfff0, /* 111111111111 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 224 0xe0 '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 225 0xe1 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0f00, /* 000011110000 */
+ 0x1980, /* 000110011000 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x3180, /* 001100011000 */
+ 0x3780, /* 001101111000 */
+ 0x3180, /* 001100011000 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x3180, /* 001100011000 */
+ 0x7700, /* 011101110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 226 0xe2 '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 227 0xe3 '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 228 0xe4 '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 229 0xe5 '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 230 0xe6 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x30c0, /* 001100001100 */
+ 0x39c0, /* 001110011100 */
+ 0x36e0, /* 001101101110 */
+ 0x3000, /* 001100000000 */
+ 0x3000, /* 001100000000 */
+ 0x6000, /* 011000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 231 0xe7 '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 232 0xe8 '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 233 0xe9 '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 234 0xea '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 235 0xeb '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 236 0xec '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 237 0xed '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 238 0xee '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 239 0xef '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 240 0xf0 '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 241 0xf1 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x7fe0, /* 011111111110 */
+ 0x7fe0, /* 011111111110 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x7fe0, /* 011111111110 */
+ 0x7fe0, /* 011111111110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 242 0xf2 '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 243 0xf3 '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 244 0xf4 '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 245 0xf5 '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 246 0xf6 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x7fe0, /* 011111111110 */
+ 0x7fe0, /* 011111111110 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0600, /* 000001100000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 247 0xf7 '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 248 0xf8 '.' */
+ 0x0000, /* 000000000000 */
+ 0x0f00, /* 000011110000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x1980, /* 000110011000 */
+ 0x0f00, /* 000011110000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 249 0xf9 '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 250 0xfa '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0600, /* 000001100000 */
+ 0x0f00, /* 000011110000 */
+ 0x0f00, /* 000011110000 */
+ 0x0600, /* 000001100000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 251 0xfb '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 252 0xfc '.' */
+ /* FIXME */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 253 0xfd '.' */
+ 0x0000, /* 000000000000 */
+ 0x0f00, /* 000011110000 */
+ 0x1f80, /* 000111111000 */
+ 0x3180, /* 001100011000 */
+ 0x2180, /* 001000011000 */
+ 0x0300, /* 000000110000 */
+ 0x0600, /* 000001100000 */
+ 0x0c00, /* 000011000000 */
+ 0x1840, /* 000110000100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 254 0xfe '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x3fc0, /* 001111111100 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+ /* 255 0xff '.' */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+ 0x0000, /* 000000000000 */
+
+};
+
+
+struct fbcon_font_desc font_sun_12x22 = {
+ SUN12x22_IDX,
+ "SUN12x22",
+ 12,
+ 22,
+ fontdata_sun12x22,
+#ifdef __sparc__
+ 5
+#else
+ -1
+#endif
+};
diff --git a/drivers/video/font_sun8x16.c b/drivers/video/font_sun8x16.c
new file mode 100644
index 000000000..8bf027807
--- /dev/null
+++ b/drivers/video/font_sun8x16.c
@@ -0,0 +1,275 @@
+#include "font.h"
+
+#define FONTDATAMAX 4096
+
+static unsigned char fontdata_sun8x16[FONTDATAMAX] = {
+/* */ 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,
+/*0*/ 0x00,0x00,0x7c,0xc6,0xc6,0xce,0xde,0xf6,0xe6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*1*/ 0x00,0x00,0x18,0x38,0x78,0x18,0x18,0x18,0x18,0x18,0x18,0x7e,0x00,0x00,0x00,0x00,
+/*2*/ 0x00,0x00,0x7c,0xc6,0x06,0x0c,0x18,0x30,0x60,0xc0,0xc6,0xfe,0x00,0x00,0x00,0x00,
+/*3*/ 0x00,0x00,0x7c,0xc6,0x06,0x06,0x3c,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*4*/ 0x00,0x00,0x0c,0x1c,0x3c,0x6c,0xcc,0xfe,0x0c,0x0c,0x0c,0x1e,0x00,0x00,0x00,0x00,
+/*5*/ 0x00,0x00,0xfe,0xc0,0xc0,0xc0,0xfc,0x06,0x06,0x06,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*6*/ 0x00,0x00,0x38,0x60,0xc0,0xc0,0xfc,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*7*/ 0x00,0x00,0xfe,0xc6,0x06,0x06,0x0c,0x18,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,
+/*8*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0x7c,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*9*/ 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,
+/*A*/ 0x00,0x00,0x10,0x38,0x6c,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
+/*B*/ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x66,0x66,0x66,0x66,0xfc,0x00,0x00,0x00,0x00,
+/*C*/ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xc0,0xc0,0xc2,0x66,0x3c,0x00,0x00,0x00,0x00,
+/*D*/ 0x00,0x00,0xf8,0x6c,0x66,0x66,0x66,0x66,0x66,0x66,0x6c,0xf8,0x00,0x00,0x00,0x00,
+/*E*/ 0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00,
+/*F*/ 0x00,0x00,0xfe,0x66,0x62,0x68,0x78,0x68,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
+/*G*/ 0x00,0x00,0x3c,0x66,0xc2,0xc0,0xc0,0xde,0xc6,0xc6,0x66,0x3a,0x00,0x00,0x00,0x00,
+/*H*/ 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xfe,0xc6,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
+/*I*/ 0x00,0x00,0x3c,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
+/*J*/ 0x00,0x00,0x1e,0x0c,0x0c,0x0c,0x0c,0x0c,0xcc,0xcc,0xcc,0x78,0x00,0x00,0x00,0x00,
+/*K*/ 0x00,0x00,0xe6,0x66,0x66,0x6c,0x78,0x78,0x6c,0x66,0x66,0xe6,0x00,0x00,0x00,0x00,
+/*L*/ 0x00,0x00,0xf0,0x60,0x60,0x60,0x60,0x60,0x60,0x62,0x66,0xfe,0x00,0x00,0x00,0x00,
+/*M*/ 0x00,0x00,0xc3,0xe7,0xff,0xff,0xdb,0xc3,0xc3,0xc3,0xc3,0xc3,0x00,0x00,0x00,0x00,
+/*N*/ 0x00,0x00,0xc6,0xe6,0xf6,0xfe,0xde,0xce,0xc6,0xc6,0xc6,0xc6,0x00,0x00,0x00,0x00,
+/*O*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*P*/ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
+/*Q*/ 0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xd6,0xde,0x7c,0x0c,0x0e,0x00,0x00,
+/*R*/ 0x00,0x00,0xfc,0x66,0x66,0x66,0x7c,0x6c,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00,
+/*S*/ 0x00,0x00,0x7c,0xc6,0xc6,0x60,0x38,0x0c,0x06,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*T*/ 0x00,0x00,0xff,0xdb,0x99,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
+/*U*/ 0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*V*/ 0x00,0x00,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x00,0x00,0x00,0x00,
+/*W*/ 0x00,0x00,0xc3,0xc3,0xc3,0xc3,0xc3,0xdb,0xdb,0xff,0x66,0x66,0x00,0x00,0x00,0x00,
+/*X*/ 0x00,0x00,0xc3,0xc3,0x66,0x3c,0x18,0x18,0x3c,0x66,0xc3,0xc3,0x00,0x00,0x00,0x00,
+/*Y*/ 0x00,0x00,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
+/*Z*/ 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,
+/*a*/ 0x00,0x00,0x00,0x00,0x00,0x78,0x0c,0x7c,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
+/*b*/ 0x00,0x00,0xe0,0x60,0x60,0x78,0x6c,0x66,0x66,0x66,0x66,0x7c,0x00,0x00,0x00,0x00,
+/*c*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc0,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*d*/ 0x00,0x00,0x1c,0x0c,0x0c,0x3c,0x6c,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
+/*e*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xfe,0xc0,0xc0,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*f*/ 0x00,0x00,0x38,0x6c,0x64,0x60,0xf0,0x60,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
+/*g*/ 0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0xcc,0x78,0x00,
+/*h*/ 0x00,0x00,0xe0,0x60,0x60,0x6c,0x76,0x66,0x66,0x66,0x66,0xe6,0x00,0x00,0x00,0x00,
+/*i*/ 0x00,0x00,0x18,0x18,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
+/*j*/ 0x00,0x00,0x06,0x06,0x00,0x0e,0x06,0x06,0x06,0x06,0x06,0x06,0x66,0x66,0x3c,0x00,
+/*k*/ 0x00,0x00,0xe0,0x60,0x60,0x66,0x6c,0x78,0x78,0x6c,0x66,0xe6,0x00,0x00,0x00,0x00,
+/*l*/ 0x00,0x00,0x38,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x18,0x3c,0x00,0x00,0x00,0x00,
+/*m*/ 0x00,0x00,0x00,0x00,0x00,0xe6,0xff,0xdb,0xdb,0xdb,0xdb,0xdb,0x00,0x00,0x00,0x00,
+/*n*/ 0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x66,0x00,0x00,0x00,0x00,
+/*o*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0xc6,0xc6,0xc6,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*p*/ 0x00,0x00,0x00,0x00,0x00,0xdc,0x66,0x66,0x66,0x66,0x66,0x7c,0x60,0x60,0xf0,0x00,
+/*q*/ 0x00,0x00,0x00,0x00,0x00,0x76,0xcc,0xcc,0xcc,0xcc,0xcc,0x7c,0x0c,0x0c,0x1e,0x00,
+/*r*/ 0x00,0x00,0x00,0x00,0x00,0xdc,0x76,0x66,0x60,0x60,0x60,0xf0,0x00,0x00,0x00,0x00,
+/*s*/ 0x00,0x00,0x00,0x00,0x00,0x7c,0xc6,0x60,0x38,0x0c,0xc6,0x7c,0x00,0x00,0x00,0x00,
+/*t*/ 0x00,0x00,0x10,0x30,0x30,0xfc,0x30,0x30,0x30,0x30,0x36,0x1c,0x00,0x00,0x00,0x00,
+/*u*/ 0x00,0x00,0x00,0x00,0x00,0xcc,0xcc,0xcc,0xcc,0xcc,0xcc,0x76,0x00,0x00,0x00,0x00,
+/*v*/ 0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0xc3,0xc3,0x66,0x3c,0x18,0x00,0x00,0x00,0x00,
+/*w*/ 0x00,0x00,0x00,0x00,0x00,0xc3,0xc3,0xc3,0xdb,0xdb,0xff,0x66,0x00,0x00,0x00,0x00,
+/*x*/ 0x00,0x00,0x00,0x00,0x00,0xc3,0x66,0x3c,0x18,0x3c,0x66,0xc3,0x00,0x00,0x00,0x00,
+/*y*/ 0x00,0x00,0x00,0x00,0x00,0xc6,0xc6,0xc6,0xc6,0xc6,0xc6,0x7e,0x06,0x0c,0xf8,0x00,
+/*z*/ 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,
+};
+
+struct fbcon_font_desc font_sun_8x16 = {
+ SUN8x16_IDX,
+ "SUN8x16",
+ 8,
+ 16,
+ fontdata_sun8x16,
+#ifdef __sparc__
+ 10
+#else
+ -1
+#endif
+};
diff --git a/drivers/video/fonts.c b/drivers/video/fonts.c
index 56a3a33b2..72f29410a 100644
--- a/drivers/video/fonts.c
+++ b/drivers/video/fonts.c
@@ -2,6 +2,7 @@
* linux/drivers/video/fonts.c -- `Soft' font definitions
*
* Created 1995 by Geert Uytterhoeven
+ * Rewritten 1998 by Martin Mares <mj@ucw.cz>
*
* 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
@@ -12,83 +13,66 @@
#include <linux/config.h>
#include <linux/types.h>
#include <linux/string.h>
-#ifdef __mc68000__
+#if defined(__mc68000__) || defined(CONFIG_APUS)
#include <asm/setup.h>
#endif
#include "font.h"
+#define NO_FONTS
- /*
- * External Font Definitions
- */
-
-/* VGA8x8 */
-extern char fontname_8x8[];
-extern int fontwidth_8x8, fontheight_8x8;
-extern u8 fontdata_8x8[];
-
-/* VGA8x16 */
-extern char fontname_8x16[];
-extern int fontwidth_8x16, fontheight_8x16;
-extern u8 fontdata_8x16[];
-
-/* PEARL8x8 */
-extern char fontname_pearl8x8[];
-extern int fontwidth_pearl8x8, fontheight_pearl8x8;
-extern u8 fontdata_pearl8x8[];
-
-/* VGA6x11 */
-extern char fontname_6x11[];
-extern int fontwidth_6x11, fontheight_6x11;
-extern u8 fontdata_6x11[];
-
-
- /*
- * Font Descriptor Array
- */
-
-struct softfontdesc {
- char *name;
- int *width;
- int *height;
- u8 *data;
-};
-
-#define VGA8x8_IDX 0
-#define VGA8x16_IDX 1
-#define PEARL8x8_IDX 2
-#define VGA6x11_IDX 3
-
-static struct softfontdesc softfonts[] = {
- { fontname_8x8, &fontwidth_8x8, &fontheight_8x8, fontdata_8x8 },
- { fontname_8x16, &fontwidth_8x16, &fontheight_8x16, fontdata_8x16 },
- { fontname_pearl8x8, &fontwidth_pearl8x8, &fontheight_pearl8x8,
- fontdata_pearl8x8 },
- { fontname_6x11, &fontwidth_6x11, &fontheight_6x11, fontdata_6x11 },
+static struct fbcon_font_desc *fbcon_fonts[] = {
+#ifdef CONFIG_FONT_8x8
+#undef NO_FONTS
+ &font_vga_8x8,
+#endif
+#ifdef CONFIG_FONT_8x16
+#undef NO_FONTS
+ &font_vga_8x16,
+#endif
+#ifdef CONFIG_FONT_6x11
+#if defined(CONFIG_MAC) || defined(CONFIG_FB_SBUS)
+#undef NO_FONTS
+#endif
+ &font_vga_6x11,
+#endif
+#ifdef CONFIG_FONT_SUN8x16
+#undef NO_FONTS
+ &font_sun_8x16,
+#endif
+#ifdef CONFIG_FONT_SUN12x22
+#if defined(CONFIG_FB_SBUS) || defined(CONFIG_FBCON_CFB8) || defined(CONFIG_FBCON_CFB16) || defined(CONFIG_FBCON_CFB24) || defined(CONFIG_FBCON_CFB32)
+#undef NO_FONTS
+#endif
+ &font_sun_12x22,
+#endif
+#ifdef CONFIG_FONT_ACORN_8x8
+#undef NO_FONTS
+ &font_acorn_8x8,
+#endif
+#ifdef CONFIG_FONT_PEARL_8x8
+#undef NO_FONTS
+ &font_pearl_8x8,
+#endif
};
-static unsigned int numsoftfonts = sizeof(softfonts)/sizeof(*softfonts);
+#define num_fonts (sizeof(fbcon_fonts)/sizeof(*fbcon_fonts))
+#ifdef NO_FONTS
+#error No fonts configured.
+#endif
/*
* Find a font with a specific name
*/
-int findsoftfont(char *name, int *width, int *height, u8 *data[])
+struct fbcon_font_desc *fbcon_find_font(char *name)
{
unsigned int i;
- for (i = 0; i < numsoftfonts; i++)
- if (!strcmp(softfonts[i].name, name)) {
- if (width)
- *width = *softfonts[i].width;
- if (height)
- *height = *softfonts[i].height;
- if (data)
- *data = softfonts[i].data;
- return(1);
- }
- return(0);
+ for (i = 0; i < num_fonts; i++)
+ if (!strcmp(fbcon_fonts[i]->name, name))
+ return fbcon_fonts[i];
+ return NULL;
}
@@ -96,36 +80,32 @@ int findsoftfont(char *name, int *width, int *height, u8 *data[])
* Get the default font for a specific screen size
*/
-void getdefaultfont(int xres, int yres, char *name[], int *width, int *height,
- u8 *data[])
+struct fbcon_font_desc *fbcon_get_default_font(int xres, int yres)
{
- int i;
-
- if (yres < 400) {
- i = VGA8x8_IDX;
-#ifdef CONFIG_AMIGA
- if (MACH_IS_AMIGA)
- i = PEARL8x8_IDX;
+ int i, c, cc;
+ struct fbcon_font_desc *f, *g;
+
+ g = NULL;
+ cc = -10000;
+ for(i=0; i<num_fonts; i++) {
+ f = fbcon_fonts[i];
+ c = f->pref;
+#ifdef __mc68000__
+#ifdef CONFIG_FONT_PEARL_8x8
+ if (MACH_IS_AMIGA && f->idx == PEARL8x8_IDX)
+ c = 100;
#endif
- } else
- i = VGA8x16_IDX;
-
-#if defined(CONFIG_MAC)
- if (MACH_IS_MAC) {
-#if 0 /* MSch: removed until 6x11 is debugged */
- i = VGA6x11_IDX; /* I added this for fun ... I like 6x11 */
+#ifdef CONFIG_FONT_6x11
+ if (MACH_IS_MAC && xres < 640 && f->idx == VGA6x11_IDX)
+ c = 100;
#endif
- if (xres < 640)
- i = VGA6x11_IDX;
- }
#endif
-
- if (name)
- *name = softfonts[i].name;
- if (width)
- *width = *softfonts[i].width;
- if (height)
- *height = *softfonts[i].height;
- if (data)
- *data = softfonts[i].data;
+ if ((yres < 400) == (f->height <= 8))
+ c += 1000;
+ if (c > cc) {
+ cc = c;
+ g = f;
+ }
+ }
+ return g;
}
diff --git a/drivers/video/g364fb.c b/drivers/video/g364fb.c
index 56939ef61..81f7fb95e 100644
--- a/drivers/video/g364fb.c
+++ b/drivers/video/g364fb.c
@@ -1,4 +1,5 @@
-/*
+/* $Id: g364fb.c,v 1.1 1998/08/19 21:56:39 ralf Exp $
+ *
* linux/drivers/video/g364fb.c -- Mips Magnum frame buffer device
*
* (C) 1998 Thomas Bogendoerfer
diff --git a/drivers/video/hpfb.c b/drivers/video/hpfb.c
new file mode 100644
index 000000000..7a7bede02
--- /dev/null
+++ b/drivers/video/hpfb.c
@@ -0,0 +1,428 @@
+/*
+ * HP300 Topcat framebuffer support (derived from macfb of all things)
+ * Phil Blundell <philb@gnu.org> 1998
+ *
+ * Should this be moved to drivers/dio/video/ ? -- Peter Maydell
+ * No! -- Jes
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/fb.h>
+#include <linux/dio.h>
+#include <asm/io.h>
+#include <asm/blinken.h>
+#include <asm/hwtest.h>
+
+#include "fbcon-mfb.h"
+#include "fbcon-cfb2.h"
+#include "fbcon-cfb4.h"
+#include "fbcon-cfb8.h"
+
+#define arraysize(x) (sizeof(x)/sizeof(*(x)))
+
+static struct display disp;
+static struct fb_info fb_info;
+
+unsigned long fb_start, fb_size = 1024*768, fb_line_length = 1024;
+unsigned long fb_regs;
+unsigned char fb_bitmask;
+
+#define TC_WEN 0x4088
+#define TC_REN 0x408c
+#define TC_FBEN 0x4090
+#define TC_NBLANK 0x4080
+
+/* blitter regs */
+#define BUSY 0x4044
+#define WMRR 0x40ef
+#define SOURCE_X 0x40f2
+#define SOURCE_Y 0x40f6
+#define DEST_X 0x40fa
+#define DEST_Y 0x40fe
+#define WHEIGHT 0x4106
+#define WWIDTH 0x4102
+#define WMOVE 0x409c
+
+static struct fb_var_screeninfo hpfb_defined = {
+ 0,0,0,0, /* W,H, W, H (virtual) load xres,xres_virtual*/
+ 0,0, /* virtual -> visible no offset */
+ 0, /* depth -> load bits_per_pixel */
+ 0, /* greyscale ? */
+ {0,2,0}, /* R */
+ {0,2,0}, /* G */
+ {0,2,0}, /* B */
+ {0,0,0}, /* transparency */
+ 0, /* standard pixel format */
+ FB_ACTIVATE_NOW,
+ 274,195, /* 14" monitor */
+ FB_ACCEL_NONE,
+ 0L,0L,0L,0L,0L,
+ 0L,0L,0, /* No sync info */
+ FB_VMODE_NONINTERLACED,
+ {0,0,0,0,0,0}
+};
+
+struct hpfb_par
+{
+};
+
+static int currcon = 0;
+struct hpfb_par current_par;
+
+static void hpfb_encode_var(struct fb_var_screeninfo *var,
+ struct hpfb_par *par)
+{
+ int i=0;
+ var->xres=1024;
+ var->yres=768;
+ var->xres_virtual=1024;
+ var->yres_virtual=768;
+ var->xoffset=0;
+ var->yoffset=0;
+ var->bits_per_pixel = 1;
+ var->grayscale=0;
+ var->transp.offset=0;
+ var->transp.length=0;
+ var->transp.msb_right=0;
+ var->nonstd=0;
+ var->activate=0;
+ var->height= -1;
+ var->width= -1;
+ var->vmode=FB_VMODE_NONINTERLACED;
+ var->pixclock=0;
+ var->sync=0;
+ var->left_margin=0;
+ var->right_margin=0;
+ var->upper_margin=0;
+ var->lower_margin=0;
+ var->hsync_len=0;
+ var->vsync_len=0;
+ for(i=0;i<arraysize(var->reserved);i++)
+ var->reserved[i]=0;
+}
+
+static void hpfb_get_par(struct hpfb_par *par)
+{
+ *par=current_par;
+}
+
+static int fb_update_var(int con, struct fb_info *info)
+{
+ return 0;
+}
+
+static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive)
+{
+ struct hpfb_par par;
+
+ hpfb_get_par(&par);
+ hpfb_encode_var(var, &par);
+ return 0;
+}
+
+static int hpfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ return 0;
+}
+
+/*
+ * Set the palette. This may not work on all boards but only experimentation will tell.
+ * XXX Doesn't work at all.
+ */
+
+static int hpfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ unsigned int i;
+ for (i = 0; i < cmap->len; i++)
+ {
+ while (readw(fb_regs + 0x6002) & 0x4) udelay(1);
+ writew(0, fb_regs + 0x60f0);
+ writew(cmap->start + i, fb_regs + 0x60b8);
+ writew(cmap->red[i], fb_regs + 0x60b2);
+ writew(cmap->green[i], fb_regs + 0x60b4);
+ writew(cmap->blue[i], fb_regs + 0x60b6);
+ writew(0xff, fb_regs + 0x60f0);
+ udelay(100);
+ }
+ writew(0xffff, fb_regs + 0x60ba);
+ return 0;
+}
+
+static int hpfb_get_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ struct hpfb_par par;
+ if(con==-1)
+ {
+ hpfb_get_par(&par);
+ hpfb_encode_var(var, &par);
+ }
+ else
+ *var=fb_display[con].var;
+ return 0;
+}
+
+static int hpfb_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ int err;
+
+ if ((err=do_fb_set_var(var, 1)))
+ return err;
+ return 0;
+}
+
+static void hpfb_encode_fix(struct fb_fix_screeninfo *fix,
+ struct hpfb_par *par)
+{
+ memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+ strcpy(fix->id, "HP300 Topcat");
+
+ /*
+ * X works, but screen wraps ...
+ */
+ fix->smem_start=(char *)fb_start;
+ fix->smem_len=fb_size;
+ fix->type = FB_TYPE_PACKED_PIXELS;
+ fix->visual = FB_VISUAL_PSEUDOCOLOR;
+ fix->xpanstep=0;
+ fix->ypanstep=0;
+ fix->ywrapstep=0;
+ fix->line_length=fb_line_length;
+}
+
+static int hpfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info)
+{
+ struct hpfb_par par;
+ hpfb_get_par(&par);
+ hpfb_encode_fix(fix, &par);
+ return 0;
+}
+
+static void topcat_blit(int x0, int y0, int x1, int y1, int w, int h)
+{
+ while (readb(fb_regs + BUSY) & fb_bitmask);
+ writeb(0x3, fb_regs + WMRR);
+ writew(x0, fb_regs + SOURCE_X);
+ writew(y0, fb_regs + SOURCE_Y);
+ writew(x1, fb_regs + DEST_X);
+ writew(y1, fb_regs + DEST_Y);
+ writew(h, fb_regs + WHEIGHT);
+ writew(w, fb_regs + WWIDTH);
+ writeb(fb_bitmask, fb_regs + WMOVE);
+}
+
+static int hpfb_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg, int con,
+ struct fb_info *info)
+{
+ return -EINVAL;
+}
+
+static int hpfb_switch(int con, struct fb_info *info)
+{
+ do_fb_set_var(&fb_display[con].var,1);
+ currcon=con;
+ return 0;
+}
+
+/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
+
+static void hpfb_blank(int blank, struct fb_info *info)
+{
+ /* Not supported */
+}
+
+static int hpfb_open(struct fb_info *info, int user)
+{
+ /*
+ * Nothing, only a usage count for the moment
+ */
+ MOD_INC_USE_COUNT;
+ return(0);
+}
+
+static void hpfb_set_disp(int con)
+{
+ struct fb_fix_screeninfo fix;
+ struct display *display;
+
+ if (con >= 0)
+ display = &fb_display[con];
+ else
+ display = &disp; /* used during initialization */
+
+ hpfb_get_fix(&fix, con, 0);
+
+ display->screen_base = fix.smem_start;
+ display->visual = fix.visual;
+ display->type = fix.type;
+ display->type_aux = fix.type_aux;
+ display->ypanstep = fix.ypanstep;
+ display->ywrapstep = fix.ywrapstep;
+ display->line_length = fix.line_length;
+ display->next_line = fix.line_length;
+ display->can_soft_blank = 0;
+ display->inverse = 0;
+
+ display->dispsw = &fbcon_cfb8;
+}
+
+static int hpfb_release(struct fb_info *info, int user)
+{
+ MOD_DEC_USE_COUNT;
+ return(0);
+}
+
+static struct fb_ops hpfb_ops = {
+ hpfb_open,
+ hpfb_release,
+ hpfb_get_fix,
+ hpfb_get_var,
+ hpfb_set_var,
+ hpfb_get_cmap,
+ hpfb_set_cmap,
+ NULL,
+ hpfb_ioctl
+};
+
+#define TOPCAT_FBOMSB 0x5d
+#define TOPCAT_FBOLSB 0x5f
+
+__initfunc(int hpfb_init_one(unsigned long base))
+{
+ unsigned long fboff;
+
+ fboff = (readb(base + TOPCAT_FBOMSB) << 8)
+ | readb(base + TOPCAT_FBOLSB);
+
+ fb_start = 0xf0000000 | (readb(base + fboff) << 16);
+ fb_regs = base;
+
+#if 0
+ /* This is the magic incantation NetBSD uses to make Catseye boards work. */
+ writeb(0, base+0x4800);
+ writeb(0, base+0x4510);
+ writeb(0, base+0x4512);
+ writeb(0, base+0x4514);
+ writeb(0, base+0x4516);
+ writeb(0x90, base+0x4206);
+#endif
+
+ /*
+ * Fill in the available video resolution
+ */
+
+ hpfb_defined.xres = 1024;
+ hpfb_defined.yres = 768;
+ hpfb_defined.xres_virtual = 1024;
+ hpfb_defined.yres_virtual = 768;
+ hpfb_defined.bits_per_pixel = 8;
+
+ /*
+ * Give the hardware a bit of a prod and work out how many bits per
+ * pixel are supported.
+ */
+
+ writeb(0xff, base + TC_WEN);
+ writeb(0xff, base + TC_FBEN);
+ writeb(0xff, fb_start);
+ fb_bitmask = readb(fb_start);
+
+ /*
+ * Enable reading/writing of all the planes.
+ */
+ writeb(fb_bitmask, base + TC_WEN);
+ writeb(fb_bitmask, base + TC_REN);
+ writeb(fb_bitmask, base + TC_FBEN);
+ writeb(0x1, base + TC_NBLANK);
+
+ /*
+ * Let there be consoles..
+ */
+ strcpy(fb_info.modename, "Topcat");
+ fb_info.changevar = NULL;
+ fb_info.node = -1;
+ fb_info.fbops = &hpfb_ops;
+ fb_info.disp = &disp;
+ fb_info.switch_con = &hpfb_switch;
+ fb_info.updatevar = &fb_update_var;
+ fb_info.blank = &hpfb_blank;
+ do_fb_set_var(&hpfb_defined, 1);
+
+ hpfb_get_var(&disp.var, -1, &fb_info);
+ hpfb_set_disp(-1);
+
+ if (register_framebuffer(&fb_info) < 0)
+ return 1;
+
+ return 0;
+}
+
+/*
+ * Check that the secondary ID indicates that we have some hope of working with this
+ * framebuffer. The catseye boards are pretty much like topcats and we can muddle through.
+ */
+
+#define topcat_sid_ok(x) (((x) == DIO_ID2_LRCATSEYE) || ((x) == DIO_ID2_HRCCATSEYE) \
+ || ((x) == DIO_ID2_HRMCATSEYE) || ((x) == DIO_ID2_TOPCAT))
+
+/*
+ * Initialise the framebuffer
+ */
+
+__initfunc(unsigned long hpfb_init(unsigned long mem_start))
+{
+ unsigned int sid;
+
+ /* Topcats can be on the internal IO bus or real DIO devices.
+ * The internal variant sits at 0xf0560000; it has primary
+ * and secondary ID registers just like the DIO version.
+ * So we merge the two detection routines.
+ *
+ * Perhaps this #define should be in a global header file:
+ * I believe it's common to all internal fbs, not just topcat.
+ */
+#define INTFBADDR 0xf0560000
+
+ if (hwreg_present((void *)INTFBADDR) && (DIO_ID(INTFBADDR) == DIO_ID_FBUFFER)
+ && topcat_sid_ok(sid = DIO_SECID(INTFBADDR)))
+ {
+ printk("Internal Topcat found (secondary id %02x)\n", sid);
+ hpfb_init_one(INTFBADDR);
+ }
+ else
+ {
+ int sc = dio_find(DIO_ID_FBUFFER);
+ if (sc)
+ {
+ unsigned long addr = (unsigned long)dio_scodetoviraddr(sc);
+ unsigned int sid = DIO_SECID(addr);
+
+ if (topcat_sid_ok(sid))
+ {
+ printk("Topcat found at DIO select code %02x "
+ "(secondary id %02x)\n", sc, sid);
+ hpfb_init_one(addr);
+ }
+ }
+ }
+
+ return mem_start;
+}
+
+__initfunc(void hpfb_setup(char *options, int *ints))
+{
+}
diff --git a/drivers/video/macfb.c b/drivers/video/macfb.c
index 43932a080..67d6e87b1 100644
--- a/drivers/video/macfb.c
+++ b/drivers/video/macfb.c
@@ -2,7 +2,6 @@
* We've been given MAC frame buffer info by the booter. Now go set it up
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
@@ -44,7 +43,7 @@ static struct fb_var_screeninfo macfb_defined={
0, /* standard pixel format */
FB_ACTIVATE_NOW,
274,195, /* 14" monitor *Mikael Nykvist's anyway* */
- FB_ACCEL_NONE, /* The only way to accelerate a mac is .. */
+ 0, /* The only way to accelerate a mac is .. */
0L,0L,0L,0L,0L,
0L,0L,0, /* No sync info */
FB_VMODE_NONINTERLACED,
@@ -76,7 +75,7 @@ static unsigned long mac_videosize;
* Open/Release the frame buffer device
*/
-static int macfb_open(struct fb_info *info)
+static int macfb_open(struct fb_info *info, int user)
{
/*
* Nothing, only a usage count for the moment
@@ -85,7 +84,7 @@ static int macfb_open(struct fb_info *info)
return(0);
}
-static int macfb_release(struct fb_info *info)
+static int macfb_release(struct fb_info *info, int user)
{
MOD_DEC_USE_COUNT;
return(0);
@@ -94,7 +93,7 @@ static int macfb_release(struct fb_info *info)
static void macfb_encode_var(struct fb_var_screeninfo *var,
struct macfb_par *par)
{
- int i=0;
+ memset(var, 0, sizeof(struct fb_var_screeninfo));
var->xres=mac_xres;
var->yres=mac_yres;
var->xres_virtual=mac_vxres;
@@ -110,7 +109,6 @@ static void macfb_encode_var(struct fb_var_screeninfo *var,
var->activate=0;
var->height= -1;
var->width= -1;
- var->accel=0;
var->vmode=FB_VMODE_NONINTERLACED;
var->pixclock=0;
var->sync=0;
@@ -120,8 +118,6 @@ static void macfb_encode_var(struct fb_var_screeninfo *var,
var->lower_margin=0;
var->hsync_len=0;
var->vsync_len=0;
- for(i=0;i<arraysize(var->reserved);i++)
- var->reserved[i]=0;
return;
}
@@ -155,8 +151,6 @@ extern int console_loglevel;
static void macfb_encode_fix(struct fb_fix_screeninfo *fix,
struct macfb_par *par)
{
- int i;
-
memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id,"Macintosh");
@@ -210,7 +204,7 @@ static void macfb_set_disp(int con)
macfb_get_fix(&fix, con, 0);
- display->screen_base = (u_char *)(fix.smem_start+fix.smem_offset);
+ display->screen_base = fix.smem_start+fix.smem_offset;
display->visual = fix.visual;
display->type = fix.type;
display->type_aux = fix.type_aux;
@@ -222,22 +216,22 @@ static void macfb_set_disp(int con)
display->inverse = inverse;
switch (mac_depth) {
-#ifdef CONFIG_FBCON_MFB
+#ifdef FBCON_HAS_MFB
case 1:
display->dispsw = &fbcon_mfb;
break;
#endif
-#ifdef CONFIG_FBCON_CFB2
+#ifdef FBCON_HAS_CFB2
case 2:
display->dispsw = &fbcon_cfb2;
break;
#endif
-#ifdef CONFIG_FBCON_CFB4
+#ifdef FBCON_HAS_CFB4
case 4:
display->dispsw = &fbcon_cfb4;
break;
#endif
-#ifdef CONFIG_FBCON_CFB8
+#ifdef FBCON_HAS_CFB8
case 8:
display->dispsw = &fbcon_cfb8;
break;
@@ -323,14 +317,12 @@ static struct fb_ops macfb_ops = {
macfb_get_cmap,
macfb_set_cmap,
macfb_pan_display,
- NULL,
macfb_ioctl
};
void macfb_setup(char *options, int *ints)
{
char *this_opt;
- int temp;
fb_info.fontname[0] = '\0';
@@ -372,7 +364,7 @@ static int nubus_video_card(struct nubus_device_specifier *ns, int slot, struct
{
if(nt->category==NUBUS_CAT_DISPLAY)
return 0;
- /* Claim all video cards. We dont yet do driver specifics tho. */
+ /* Claim all video cards. We don't yet do driver specifics though. */
return -ENODEV;
}
@@ -381,13 +373,12 @@ static struct nubus_device_specifier nb_video={
NULL
};
-__initfunc(unsigned long macfb_init(unsigned long mem_start))
+__initfunc(void macfb_init(void))
{
/* nubus_remap the video .. */
- int err;
if (!MACH_IS_MAC)
- return mem_start;
+ return;
mac_xres=mac_bi_data.dimensions&0xFFFF;
mac_yres=(mac_bi_data.dimensions&0xFFFF0000)>>16;
@@ -426,13 +417,6 @@ __initfunc(unsigned long macfb_init(unsigned long mem_start))
fb_info.blank=&macfb_blank;
do_fb_set_var(&macfb_defined,1);
- err=register_framebuffer(&fb_info);
- if(err<0)
- {
- mac_boom(6);
- return NULL;
- }
-
macfb_get_var(&disp.var, -1, &fb_info);
macfb_set_disp(-1);
@@ -442,10 +426,14 @@ __initfunc(unsigned long macfb_init(unsigned long mem_start))
register_nubus_device(&nb_video);
+ if (register_framebuffer(&fb_info) < 0)
+ {
+ mac_boom(6);
+ return;
+ }
+
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 mem_start;
}
#if 0
diff --git a/drivers/video/macmodes.c b/drivers/video/macmodes.c
new file mode 100644
index 000000000..57cf4877a
--- /dev/null
+++ b/drivers/video/macmodes.c
@@ -0,0 +1,391 @@
+/*
+ * linux/drivers/video/macmodes.c -- Standard MacOS video modes
+ *
+ * Copyright (C) 1998 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/string.h>
+
+#include "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
+
+ /* 768x576, 50Hz (PAL full frame), Interlaced */
+
+#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
+};
+#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
+};
+
+
+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 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 */
+};
+
+
+static struct mon_map {
+ int sense;
+ int vmode;
+} monitor_map[] = {
+ { 0x000, VMODE_1280_1024_75 }, /* 21" RGB */
+ { 0x114, VMODE_640_870_75P }, /* Portrait Monochrome */
+ { 0x221, VMODE_512_384_60 }, /* 12" RGB*/
+ { 0x331, VMODE_1280_1024_75 }, /* 21" RGB (Radius) */
+ { 0x334, VMODE_1280_1024_75 }, /* 21" mono (Radius) */
+ { 0x335, VMODE_1280_1024_75 }, /* 21" mono */
+ { 0x40A, VMODE_640_480_60I }, /* NTSC */
+ { 0x51E, VMODE_640_870_75P }, /* Portrait RGB */
+ { 0x603, VMODE_832_624_75 }, /* 12"-16" multiscan */
+ { 0x60b, VMODE_1024_768_70 }, /* 13"-19" multiscan */
+ { 0x623, VMODE_1152_870_75 }, /* 13"-21" multiscan */
+ { 0x62b, VMODE_640_480_67 }, /* 13"/14" RGB */
+ { 0x700, VMODE_640_480_50I }, /* PAL */
+ { 0x714, VMODE_640_480_60I }, /* NTSC */
+ { 0x717, VMODE_800_600_75 }, /* VGA */
+ { 0x72d, VMODE_832_624_75 }, /* 16" RGB (Goldfish) */
+ { 0x730, VMODE_768_576_50I }, /* PAL (Alternate) */
+ { 0x73a, VMODE_1152_870_75 }, /* 3rd party 19" */
+ { 0x73f, VMODE_640_480_67 }, /* no sense lines connected at all */
+ { -1, VMODE_640_480_60 }, /* catch-all, must be last */
+};
+
+
+ /*
+ * Convert a MacOS vmode/cmode pair to a frame buffer video mode structure
+ */
+
+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];
+
+ if (!mode)
+ return -EINVAL;
+
+ memset(var, 0, sizeof(struct fb_var_screeninfo));
+ switch (cmode) {
+ case CMODE_8:
+ var->bits_per_pixel = 8;
+ var->red.offset = 0;
+ var->red.length = 8;
+ var->green.offset = 0;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ break;
+
+ case CMODE_16:
+ var->bits_per_pixel = 16;
+ var->red.offset = 10;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 5;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+ break;
+
+ case CMODE_32:
+ var->bits_per_pixel = 32;
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->transp.offset = 24;
+ var->transp.length = 8;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ var->xres = mode->xres;
+ var->yres = mode->yres;
+ var->xres_virtual = mode->xres;
+ var->yres_virtual = mode->yres;
+ var->height = -1;
+ var->width = -1;
+ 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;
+ return 0;
+}
+
+
+ /*
+ * Convert a frame buffer video mode structure to a MacOS vmode/cmode pair
+ */
+
+int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
+ int *cmode)
+{
+ int i = 0;
+
+ if (var->bits_per_pixel <= 8)
+ *cmode = CMODE_8;
+ else if (var->bits_per_pixel <= 16)
+ *cmode = CMODE_16;
+ else if (var->bits_per_pixel <= 32)
+ *cmode = CMODE_32;
+ 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];
+ if (var->xres > mode->xres || var->yres > mode->yres)
+ continue;
+ if (var->xres_virtual > mode->xres || var->yres_virtual > mode->yres)
+ continue;
+ if (var->pixclock > mode->pixclock)
+ continue;
+ if (var->vmode != mode->vmode)
+ continue;
+ *vmode = mode->number;
+ return 0;
+ }
+ return -EINVAL;
+}
+
+
+ /*
+ * Convert a Mac monitor sense number to a MacOS vmode number
+ */
+
+int mac_map_monitor_sense(int sense)
+{
+ struct mon_map *map;
+
+ for (map = monitor_map; map->sense >= 0; ++map)
+ if (map->sense == sense)
+ break;
+ return map->vmode;
+}
diff --git a/drivers/video/macmodes.h b/drivers/video/macmodes.h
new file mode 100644
index 000000000..e0e90c738
--- /dev/null
+++ b/drivers/video/macmodes.h
@@ -0,0 +1,60 @@
+/*
+ * linux/drivers/video/macmodes.h -- Standard MacOS video modes
+ *
+ * Copyright (C) 1998 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.
+ */
+
+
+ /*
+ * Video mode values.
+ * These are supposed to be the same as the values that Apple uses in
+ * MacOS.
+ */
+
+#define VMODE_NVRAM 0
+#define VMODE_512_384_60I 1 /* 512x384, 60Hz interlaced (NTSC) */
+#define VMODE_512_384_60 2 /* 512x384, 60Hz */
+#define VMODE_640_480_50I 3 /* 640x480, 50Hz interlaced (PAL) */
+#define VMODE_640_480_60I 4 /* 640x480, 60Hz interlaced (NTSC) */
+#define VMODE_640_480_60 5 /* 640x480, 60Hz (VGA) */
+#define VMODE_640_480_67 6 /* 640x480, 67Hz */
+#define VMODE_640_870_75P 7 /* 640x870, 75Hz (portrait) */
+#define VMODE_768_576_50I 8 /* 768x576, 50Hz (PAL full frame) */
+#define VMODE_800_600_56 9 /* 800x600, 56Hz */
+#define VMODE_800_600_60 10 /* 800x600, 60Hz */
+#define VMODE_800_600_72 11 /* 800x600, 72Hz */
+#define VMODE_800_600_75 12 /* 800x600, 75Hz */
+#define VMODE_832_624_75 13 /* 832x624, 75Hz */
+#define VMODE_1024_768_60 14 /* 1024x768, 60Hz */
+#define VMODE_1024_768_70 15 /* 1024x768, 70Hz (or 72Hz?) */
+#define VMODE_1024_768_75V 16 /* 1024x768, 75Hz (VESA) */
+#define VMODE_1024_768_75 17 /* 1024x768, 75Hz */
+#define VMODE_1152_870_75 18 /* 1152x870, 75Hz */
+#define VMODE_1280_960_75 19 /* 1280x960, 75Hz */
+#define VMODE_1280_1024_75 20 /* 1280x1024, 75Hz */
+#define VMODE_MAX 20
+#define VMODE_CHOOSE 99
+
+#define CMODE_NVRAM -1
+#define CMODE_8 0 /* 8 bits/pixel */
+#define CMODE_16 1 /* 16 (actually 15) bits/pixel */
+#define CMODE_32 2 /* 32 (actually 24) bits/pixel */
+
+
+extern int mac_vmode_to_var(int vmode, int cmode,
+ struct fb_var_screeninfo *var);
+extern int mac_var_to_vmode(const struct fb_var_screeninfo *var, int *vmode,
+ int *cmode);
+extern int mac_map_monitor_sense(int sense);
+
+
+ /*
+ * Addresses in NVRAM where video mode and pixel size are stored.
+ */
+
+#define NV_VMODE 0x140f
+#define NV_CMODE 0x1410
diff --git a/drivers/video/mdafb.c b/drivers/video/mdafb.c
new file mode 100644
index 000000000..35190d580
--- /dev/null
+++ b/drivers/video/mdafb.c
@@ -0,0 +1,480 @@
+/*
+ * linux/drivers/video/mdafb.c -- MDA frame buffer device
+ *
+ * Adapted from vgafb, May 1998 by Andrew Apted
+ *
+ * This file is based on vgacon.c and vgafb.c. Read about their
+ * contributors there.
+ *
+ * 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.
+ */
+
+
+/* KNOWN PROBLEMS/TO DO ==================================================== *
+ *
+ * - detecting amount of memory is not yet implemented
+ *
+ * ========================================================================= */
+
+
+#include <linux/module.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/ioport.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/selection.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include "fbcon.h"
+#include "fbcon-vga.h"
+
+
+#ifdef __powerpc__
+#define VGA_OFFSET _ISA_MEM_BASE;
+#else
+#define VGA_OFFSET 0x0
+#endif
+
+
+static int mda_font_height = 16; /* !!! */
+
+
+static int currcon = 0;
+static struct display disp;
+static struct fb_info fb_info;
+
+static struct fb_fix_screeninfo fb_fix = { { 0, } };
+static struct fb_var_screeninfo fb_var = { 0, };
+
+
+/* Description of the hardware situation */
+static unsigned char mda_video_type;
+static unsigned long mda_video_mem_base; /* Base of video memory */
+static unsigned long mda_video_mem_len; /* End of video memory */
+static u16 mda_video_port_reg; /* Video register select port */
+static u16 mda_video_port_val; /* Video register value port */
+static unsigned long mda_video_num_columns; /* Number of text columns */
+static unsigned long mda_video_num_lines; /* Number of text lines */
+
+
+ /*
+ * MDA screen access
+ */
+
+static inline void mda_writew(u16 val, u16 *addr)
+{
+#ifdef __powerpc__
+ st_le16(addr, val);
+#else
+ writew(val, (unsigned long)addr);
+#endif /* !__powerpc__ */
+}
+
+static inline u16 mda_readw(u16 *addr)
+{
+#ifdef __powerpc__
+ return ld_le16(addr);
+#else
+ return readw((unsigned long)addr);
+#endif /* !__powerpc__ */
+}
+
+
+static inline void write_mda(unsigned char reg, unsigned int val)
+{
+ unsigned long flags;
+
+ save_flags(flags); cli();
+
+ outb(reg, mda_video_port_reg);
+ outb(val >> 8, mda_video_port_val);
+ outb(reg+1, mda_video_port_reg);
+ outb(val & 0xff, mda_video_port_val);
+
+ restore_flags(flags);
+}
+
+static inline void mda_set_origin(unsigned short location)
+{
+ write_mda(12, location >> 1);
+}
+
+static inline void mda_set_cursor(int location)
+{
+ write_mda(14, location >> 1);
+}
+
+
+ /*
+ * Move hardware mda cursor
+ */
+
+void fbcon_mdafb_cursor(struct display *p, int mode, int x, int y)
+{
+ switch (mode) {
+ case CM_ERASE:
+ mda_set_cursor(mda_video_mem_len - 1);
+ break;
+
+ case CM_MOVE:
+ case CM_DRAW:
+ mda_set_cursor(y*p->next_line + (x << 1));
+ break;
+ }
+}
+
+
+ /*
+ * Interface to the low level console driver
+ */
+
+void mdafb_setup(char *options, int *ints);
+static int mdafbcon_switch(int con, struct fb_info *info);
+static int mdafbcon_updatevar(int con, struct fb_info *info);
+static void mdafbcon_blank(int blank, struct fb_info *info);
+
+
+ /*
+ * Open/Release the frame buffer device
+ */
+
+static int mdafb_open(struct fb_info *info, int user)
+{
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static int mdafb_release(struct fb_info *info, int user)
+{
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+
+ /*
+ * Get the Fixed Part of the Display
+ */
+
+static int mdafb_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info)
+{
+ memcpy(fix, &fb_fix, sizeof(fb_fix));
+ return 0;
+}
+
+
+ /*
+ * Get the User Defined Part of the Display
+ */
+
+static int mdafb_get_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ memcpy(var, &fb_var, sizeof(fb_var));
+ return 0;
+}
+
+
+ /*
+ * Set the User Defined Part of the Display
+ */
+
+static int mdafb_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ struct display *display;
+
+ if (con >= 0)
+ display = &fb_display[con];
+ else
+ display = &disp; /* used during initialization */
+
+ if (var->xres > fb_var.xres || var->yres > fb_var.yres ||
+ var->xres_virtual > fb_var.xres_virtual ||
+ var->yres_virtual > fb_var.yres_virtual ||
+ var->bits_per_pixel > fb_var.bits_per_pixel ||
+ var->nonstd || !(var->accel_flags & FB_ACCELF_TEXT) ||
+ (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+ return -EINVAL;
+
+ memcpy(var, &fb_var, sizeof(fb_var));
+
+ if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+ display->var = *var;
+ mda_set_origin(var->yoffset/mda_font_height*fb_fix.line_length);
+ }
+
+ return 0;
+}
+
+
+ /*
+ * Pan or Wrap the Display
+ *
+ * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+ */
+
+static int mdafb_pan_display(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ if (var->xoffset || var->yoffset+var->yres > var->yres_virtual)
+ return -EINVAL;
+
+ mda_set_origin(var->yoffset/mda_font_height*fb_fix.line_length);
+ return 0;
+}
+
+
+ /*
+ * Get the Colormap
+ */
+
+static int mdafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ /* MDA is simply black and white */
+
+ return 0;
+}
+
+
+ /*
+ * Set the Colormap
+ */
+
+static int mdafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ /* MDA is simply black and white */
+
+ return 0;
+}
+
+
+static int mdafb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg, int con, struct fb_info *info)
+{
+ return -EINVAL;
+}
+
+ /*
+ * Interface used by the world
+ */
+
+static struct fb_ops mdafb_ops = {
+ mdafb_open, mdafb_release, mdafb_get_fix, mdafb_get_var,
+ mdafb_set_var, mdafb_get_cmap, mdafb_set_cmap, mdafb_pan_display,
+ mdafb_ioctl
+};
+
+ /*
+ * MDA text console with hardware cursor
+ */
+
+static struct display_switch fbcon_mdafb = {
+ fbcon_vga_setup, fbcon_vga_bmove, fbcon_vga_clear, fbcon_vga_putc,
+ fbcon_vga_putcs, fbcon_vga_revc, fbcon_mdafb_cursor, NULL, NULL,
+ FONTWIDTH(8)
+};
+
+
+ /*
+ * Initialisation
+ */
+
+__initfunc(void mdafb_init(void))
+{
+ u16 saved;
+ u16 *p;
+
+ mda_video_num_lines = 25;
+ mda_video_num_columns = 80;
+ mda_video_type = VIDEO_TYPE_MDA;
+ mda_video_mem_base = 0xb0000 + VGA_OFFSET;
+ mda_video_mem_len = 0x01000;
+ mda_video_port_reg = 0x3b4;
+ mda_video_port_val = 0x3b5;
+
+ strcpy(fb_fix.id, "MDA-Dual-Head");
+ request_region(0x3b0, 12, "mda-2");
+ request_region(0x3bf, 1, "mda-2");
+
+ /*
+ * Find out if there is a graphics card present.
+ * Are there smarter methods around?
+ */
+ p = (u16 *)mda_video_mem_base;
+ saved = mda_readw(p);
+ mda_writew(0xAA55, p);
+ if (mda_readw(p) != 0xAA55) {
+ mda_writew(saved, p);
+ return;
+ }
+ mda_writew(0x55AA, p);
+ if (mda_readw(p) != 0x55AA) {
+ mda_writew(saved, p);
+ return;
+ }
+ mda_writew(saved, p);
+
+ fb_fix.smem_start = (char *) mda_video_mem_base;
+ fb_fix.smem_len = mda_video_mem_len;
+ fb_fix.type = FB_TYPE_TEXT;
+ fb_fix.type_aux = FB_AUX_TEXT_MDA;
+ fb_fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ fb_fix.ypanstep = mda_font_height;
+ fb_fix.xpanstep = 0;
+ fb_fix.ywrapstep = 0;
+ fb_fix.line_length = 2 * mda_video_num_columns;
+ fb_fix.mmio_start = NULL;
+ fb_fix.mmio_len = 0;
+ fb_fix.accel = FB_ACCEL_NONE;
+
+ fb_var.xres = mda_video_num_columns*8;
+ fb_var.yres = mda_video_num_lines * mda_font_height;
+ fb_var.xres_virtual = fb_var.xres;
+ /* the cursor is put at the end of the video memory, hence the -2 */
+ fb_var.yres_virtual = ((fb_fix.smem_len-2)/fb_fix.line_length)*
+ mda_font_height;
+
+ fb_var.xoffset = fb_var.yoffset = 0;
+ fb_var.bits_per_pixel = 1;
+ fb_var.grayscale = 1;
+ fb_var.red.offset = 0;
+ fb_var.red.length = 0;
+ fb_var.red.msb_right = 0;
+ fb_var.green.offset = 0;
+ fb_var.green.length = 0;
+ fb_var.green.msb_right = 0;
+ fb_var.blue.offset = 0;
+ fb_var.blue.length = 0;
+ fb_var.blue.msb_right = 0;
+ fb_var.transp.offset = 0;
+ fb_var.transp.length = 0;
+ fb_var.transp.msb_right = 0;
+ fb_var.nonstd = 0;
+ fb_var.activate = 0;
+ fb_var.height = fb_var.width = -1;
+ fb_var.accel_flags = FB_ACCELF_TEXT;
+ fb_var.pixclock = 39722; /* 25.175 MHz */
+ fb_var.left_margin = 40;
+ fb_var.right_margin = 24;
+ fb_var.upper_margin = 39;
+ fb_var.lower_margin = 9;
+ fb_var.hsync_len = 96;
+ fb_var.vsync_len = 2;
+ fb_var.sync = 0;
+ fb_var.vmode = FB_VMODE_NONINTERLACED;
+
+ disp.var = fb_var;
+ disp.cmap.start = 0;
+ disp.cmap.len = 0;
+ disp.cmap.red = NULL;
+ disp.cmap.green = NULL;
+ disp.cmap.blue = NULL;
+ disp.cmap.transp = NULL;
+
+#ifdef __i386__
+ disp.screen_base = ioremap((unsigned long) fb_fix.smem_start,
+ fb_fix.smem_len);
+#else
+ disp.screen_base = bus_to_virt((unsigned long) fb_fix.smem_start);
+#endif
+ disp.visual = fb_fix.visual;
+ disp.type = fb_fix.type;
+ disp.type_aux = fb_fix.type_aux;
+ disp.ypanstep = fb_fix.ypanstep;
+ disp.ywrapstep = fb_fix.ywrapstep;
+ disp.line_length = fb_fix.line_length;
+ disp.can_soft_blank = 1;
+ disp.inverse = 0;
+ disp.dispsw = &fbcon_mdafb;
+
+ strcpy(fb_info.modename, fb_fix.id);
+ fb_info.node = -1;
+ fb_info.fbops = &mdafb_ops;
+ fb_info.disp = &disp;
+ fb_info.fontname[0] = '\0';
+ fb_info.changevar = NULL;
+ fb_info.switch_con = &mdafbcon_switch;
+ fb_info.updatevar = &mdafbcon_updatevar;
+ fb_info.blank = &mdafbcon_blank;
+
+ mdafb_set_var(&fb_var, -1, &fb_info);
+
+ if (register_framebuffer(&fb_info) < 0)
+ return;
+
+ printk("fb%d: MDA frame buffer device, using %dK of video memory\n",
+ GET_FB_IDX(fb_info.node), fb_fix.smem_len>>10);
+}
+
+__initfunc(void mdafb_setup(char *options, int *ints))
+{
+ /* nothing yet */
+}
+
+ /*
+ * Update the `var' structure (called by fbcon.c)
+ */
+
+static int mdafbcon_updatevar(int con, struct fb_info *info)
+{
+ if (con == currcon) {
+ struct fb_var_screeninfo *var = &fb_display[currcon].var;
+
+ /* hardware scrolling */
+
+ mda_set_origin(var->yoffset / mda_font_height *
+ fb_fix.line_length);
+ }
+
+ return 0;
+}
+
+static int mdafbcon_switch(int con, struct fb_info *info)
+{
+ currcon = con;
+ mdafbcon_updatevar(con, info);
+ return 0;
+}
+
+ /*
+ * Blank the display.
+ */
+
+static void mdafbcon_blank(int blank, struct fb_info *info)
+{
+ if (blank) {
+ outb_p(0x00, 0x3b8); /* disable video */
+ } else {
+ outb_p(0x08, 0x3b8); /* enable video */
+ }
+}
+
+
+#ifdef MODULE
+int init_module(void)
+{
+ mdafb_init();
+ return 0;
+}
+
+void cleanup_module(void)
+{
+ unregister_framebuffer(&fb_info);
+}
+#endif /* MODULE */
diff --git a/drivers/video/newport_con.c b/drivers/video/newport_con.c
index c44526641..7532b0cdf 100644
--- a/drivers/video/newport_con.c
+++ b/drivers/video/newport_con.c
@@ -1,4 +1,5 @@
-/*
+/* $Id: newport_con.c,v 1.1 1998/08/19 21:56:41 ralf Exp $
+ *
* newport_con.c: Abscon for newport hardware
*
* (C) 1998 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
@@ -23,8 +24,7 @@
#include <asm/system.h>
#include <asm/page.h>
#include <asm/pgtable.h>
-
-#include "newport.h"
+#include <asm/newport.h>
struct newport_regs *npregs;
int newport_num_lines;
diff --git a/drivers/video/offb.c b/drivers/video/offb.c
index 26ab95dfb..0e6e57f56 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/offb.c
@@ -27,12 +27,14 @@
#include <linux/selection.h>
#include <linux/init.h>
#ifdef CONFIG_FB_COMPAT_XPMAC
-#include <linux/vc_ioctl.h>
+#include <asm/vc_ioctl.h>
#endif
#include <asm/io.h>
#include <asm/prom.h>
+#include "fbcon.h"
#include "fbcon-cfb8.h"
+#include "macmodes.h"
static int currcon = 0;
@@ -47,8 +49,6 @@ struct fb_info_offb {
volatile unsigned char *cmap_data;
};
-static struct fb_info_offb fb_info[FB_MAX];
-
#ifdef __powerpc__
#define mach_eieio() eieio()
#else
@@ -62,11 +62,11 @@ static int ofonly = 0;
* Interface used by the world
*/
-unsigned long offb_init(unsigned long mem_start);
+void offb_init(void);
void offb_setup(char *options, int *ints);
-static int offb_open(struct fb_info *info);
-static int offb_release(struct fb_info *info);
+static int offb_open(struct fb_info *info, int user);
+static int offb_release(struct fb_info *info, int user);
static int offb_get_fix(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info);
static int offb_get_var(struct fb_var_screeninfo *var, int con,
@@ -85,11 +85,9 @@ static int offb_ioctl(struct inode *inode, struct file *file, u_int cmd,
#ifdef CONFIG_FB_COMPAT_XPMAC
int console_getmode(struct vc_mode *);
int console_setmode(struct vc_mode *, int);
+int console_setcmap(int, unsigned char *, unsigned char *, unsigned char *);
int console_powermode(int);
struct fb_info *console_fb_info = NULL;
-int (*console_setmode_ptr)(struct vc_mode *, int) = NULL;
-int (*console_set_cmap_ptr)(struct fb_cmap *, int, int, struct fb_info *)
- = NULL;
struct vc_mode display_info;
#endif /* CONFIG_FB_COMPAT_XPMAC */
@@ -116,7 +114,7 @@ static void do_install_cmap(int con, struct fb_info *info);
static struct fb_ops offb_ops = {
offb_open, offb_release, offb_get_fix, offb_get_var, offb_set_var,
- offb_get_cmap, offb_set_cmap, offb_pan_display, NULL, offb_ioctl
+ offb_get_cmap, offb_set_cmap, offb_pan_display, offb_ioctl
};
@@ -124,7 +122,7 @@ static struct fb_ops offb_ops = {
* Open/Release the frame buffer device
*/
-static int offb_open(struct fb_info *info)
+static int offb_open(struct fb_info *info, int user)
{
/*
* Nothing, only a usage count for the moment
@@ -134,7 +132,7 @@ static int offb_open(struct fb_info *info)
return(0);
}
-static int offb_release(struct fb_info *info)
+static int offb_release(struct fb_info *info, int user)
{
MOD_DEC_USE_COUNT;
return(0);
@@ -276,25 +274,30 @@ static int offb_ioctl(struct inode *inode, struct file *file, u_int cmd,
#ifdef CONFIG_FB_ATY
-extern unsigned long atyfb_of_init(unsigned long mem_start,
- struct device_node *dp);
-
-static const char *aty_names[] = {
- "ATY,mach64", "ATY,XCLAIM", "ATY,264VT", "ATY,mach64ii", "ATY,264GT-B",
- "ATY,mach64_3D_pcc", "ATY,XCLAIM3D", "ATY,XCLAIMVR", "ATY,RAGEII_M",
- "ATY,XCLAIMVRPro", "ATY,mach64_3DU"
-};
+extern void atyfb_of_init(struct device_node *dp);
#endif /* CONFIG_FB_ATY */
+#ifdef CONFIG_FB_S3TRIO
+extern void s3triofb_init_of(struct device_node *dp);
+#endif /* CONFIG_FB_S3TRIO */
+#ifdef CONFIG_FB_CT65550
+extern void chips_of_init(struct device_node *dp);
+#endif /* CONFIG_FB_CT65550 */
+#ifdef CONFIG_FB_CONTROL
+extern void control_of_init(struct device_node *dp);
+#endif /* CONFIG_FB_CONTROL */
+#ifdef CONFIG_FB_PLATINUM
+extern void platinum_of_init(struct device_node *dp);
+#endif /* CONFIG_FB_PLATINUM */
/*
* Initialisation
*/
-__initfunc(unsigned long offb_init(unsigned long mem_start))
+__initfunc(void offb_init(void))
{
struct device_node *dp;
- int dpy, i, err, *pp, len;
+ int dpy, i, *pp, len;
unsigned *up, address;
struct fb_fix_screeninfo *fix;
struct fb_var_screeninfo *var;
@@ -305,23 +308,43 @@ __initfunc(unsigned long offb_init(unsigned long mem_start))
if (!(dp = find_path_device(prom_display_paths[dpy])))
continue;
- info = &fb_info[dpy];
- fix = &info->fix;
- var = &info->var;
- disp = &info->disp;
-
if (!ofonly) {
#ifdef CONFIG_FB_ATY
- for (i = 0; i < sizeof(aty_names)/sizeof(*aty_names); i++)
- if (!strcmp(dp->name, aty_names[i]))
- break;
- if (i < sizeof(aty_names)/sizeof(*aty_names)) {
- mem_start = atyfb_of_init(mem_start, dp);
+ if (!strncmp(dp->name, "ATY", 3)) {
+ atyfb_of_init(dp);
continue;
}
#endif /* CONFIG_FB_ATY */
+#ifdef CONFIG_FB_S3TRIO
+ if (s3triofb_init_of(dp))
+ continue;
+#endif /* CONFIG_FB_S3TRIO */
+#ifdef CONFIG_FB_CT65550
+ if (!strcmp(dp->name, "chips65550")) {
+ chips_of_init(dp);
+ continue;
+ }
+#endif /* CONFIG_FB_CT65550 */
+#ifdef CONFIG_FB_CONTROL
+ if(!strcmp(dp->name, "control")) {
+ control_of_init(dp);
+ continue;
+ }
+#endif /* CONFIG_FB_CONTROL */
+#ifdef CONFIG_FB_PLATINUM
+ if (!strncmp(dp->name, "platinum",8)) {
+ printk("jonh: offb_init sees device node %s\n", dp->name);
+ platinum_of_init(dp);
+ continue;
+ }
+#endif /* CONFIG_FB_PLATINUM */
}
+ info = kmalloc(sizeof(struct fb_info_offb), GFP_ATOMIC);
+ fix = &info->fix;
+ var = &info->var;
+ disp = &info->disp;
+
strcpy(fix->id, "OFfb ");
strncat(fix->id, dp->name, sizeof(fix->id));
fix->id[sizeof(fix->id)-1] = '\0';
@@ -329,6 +352,7 @@ __initfunc(unsigned long offb_init(unsigned long mem_start))
if ((pp = (int *)get_property(dp, "depth", &len)) != NULL
&& len == sizeof(int) && *pp != 8) {
printk("%s: can't use depth = %d\n", dp->full_name, *pp);
+ kfree(info);
continue;
}
if ((pp = (int *)get_property(dp, "width", &len)) != NULL
@@ -352,11 +376,12 @@ __initfunc(unsigned long offb_init(unsigned long mem_start))
break;
if (i >= dp->n_addrs) {
printk("no framebuffer address found for %s\n", dp->full_name);
+ kfree(info);
continue;
}
address = (u_long)dp->addrs[i].address;
}
- fix->smem_start = ioremap(address, fix->smem_len);
+ fix->smem_start = (char *)address;
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
@@ -379,7 +404,6 @@ __initfunc(unsigned long offb_init(unsigned long mem_start))
var->nonstd = 0;
var->activate = 0;
var->height = var->width = -1;
- var->accel = FB_ACCEL_NONE;
var->pixclock = 10000;
var->left_margin = var->right_margin = 16;
var->upper_margin = var->lower_margin = 16;
@@ -390,8 +414,11 @@ __initfunc(unsigned long offb_init(unsigned long mem_start))
disp->var = *var;
disp->cmap.start = 0;
disp->cmap.len = 0;
- disp->cmap.red = disp->cmap.green = disp->cmap.blue = disp->cmap.transp = NULL;
- disp->screen_base = fix->smem_start;
+ disp->cmap.red = NULL;
+ disp->cmap.green = NULL;
+ disp->cmap.blue = NULL;
+ disp->cmap.transp = NULL;
+ disp->screen_base = ioremap(address, fix->smem_len);
disp->visual = fix->visual;
disp->type = fix->type;
disp->type_aux = fix->type_aux;
@@ -400,11 +427,12 @@ __initfunc(unsigned long offb_init(unsigned long mem_start))
disp->line_length = fix->line_length;
disp->can_soft_blank = info->cmap_adr ? 1 : 0;
disp->inverse = 0;
-#ifdef CONFIG_FBCON_CFB8
+#ifdef FBCON_HAS_CFB8
disp->dispsw = &fbcon_cfb8;
#else
disp->dispsw = NULL;
#endif
+ disp->scrollmode = SCROLL_YREDRAW;
strcpy(info->info.modename, "OFfb ");
strncat(info->info.modename, dp->full_name,
@@ -418,10 +446,6 @@ __initfunc(unsigned long offb_init(unsigned long mem_start))
info->info.updatevar = &offbcon_updatevar;
info->info.blank = &offbcon_blank;
- err = register_framebuffer(&info->info);
- if (err < 0)
- continue;
-
for (i = 0; i < 16; i++) {
int j = color_table[i];
info->palette[i].red = default_red[j];
@@ -430,6 +454,11 @@ __initfunc(unsigned long offb_init(unsigned long mem_start))
}
offb_set_var(var, -1, &info->info);
+ if (register_framebuffer(&info->info) < 0) {
+ kfree(info);
+ return;
+ }
+
printk("fb%d: Open Firmware frame buffer device on %s\n",
GET_FB_IDX(info->info.node), dp->full_name);
@@ -441,22 +470,20 @@ __initfunc(unsigned long offb_init(unsigned long mem_start))
display_info.pitch = fix->line_length;
display_info.mode = 0;
strncpy(display_info.name, dp->name, sizeof(display_info.name));
- display_info.fb_address = iopa((unsigned long)fix->smem_start);
+ display_info.fb_address = address;
display_info.cmap_adr_address = 0;
display_info.cmap_data_address = 0;
display_info.disp_reg_address = 0;
/* XXX kludge for ati */
if (strncmp(dp->name, "ATY,", 4) == 0) {
- display_info.disp_reg_address = iopa(address + 0x7ffc00);
- display_info.cmap_adr_address = iopa(address + 0x7ffcc0);
- display_info.cmap_data_address = iopa(address + 0x7ffcc1);
+ display_info.disp_reg_address = address + 0x7ffc00;
+ display_info.cmap_adr_address = address + 0x7ffcc0;
+ display_info.cmap_data_address = address + 0x7ffcc1;
}
console_fb_info = &info->info;
- console_set_cmap_ptr = offb_set_cmap;
}
#endif /* CONFIG_FB_COMPAT_XPMAC) */
}
- return mem_start;
}
@@ -587,16 +614,6 @@ static void do_install_cmap(int con, struct fb_info *info)
/*
* Backward compatibility mode for Xpmac
- *
- * To do:
- *
- * - console_setmode() should fill in a struct fb_var_screeninfo (using
- * the MacOS video mode database) and simply call a decode_var()
- * function, so console_setmode_ptr is no longer needed.
- *
- * - instead of using the console_* stuff (filled in by the frame
- * buffer), we should use the correct struct fb_info for the
- * foreground virtual console.
*/
int console_getmode(struct vc_mode *mode)
@@ -607,12 +624,31 @@ int console_getmode(struct vc_mode *mode)
int console_setmode(struct vc_mode *mode, int doit)
{
- int err;
-
- if (console_setmode_ptr == NULL)
- return -EINVAL;
+ struct fb_var_screeninfo var;
+ int cmode, err;
- err = (*console_setmode_ptr)(mode, doit);
+ if (!console_fb_info)
+ return -EOPNOTSUPP;
+ switch (mode->depth) {
+ case 8:
+ case 0: /* default */
+ cmode = 0; /* CMODE_8 */
+ break;
+ case 16:
+ cmode = 1; /* CMODE_16 */
+ break;
+ case 24:
+ case 32:
+ cmode = 2; /* CMODE_32 */
+ break;
+ default:
+ return -EINVAL;
+ }
+ if ((err = mac_vmode_to_var(mode->mode, cmode, &var)))
+ return err;
+ var.activate = doit ? FB_ACTIVATE_NOW : FB_ACTIVATE_TEST;
+ err = console_fb_info->fbops->fb_set_var(&var, fg_console,
+ console_fb_info);
return err;
}
@@ -627,9 +663,9 @@ static struct fb_cmap palette_cmap = {
int console_setcmap(int n_entries, unsigned char *red, unsigned char *green,
unsigned char *blue)
{
- int i, j, n;
+ int i, j, n, err;
- if (console_set_cmap_ptr == NULL)
+ if (!console_fb_info)
return -EOPNOTSUPP;
for (i = 0; i < n_entries; i += n) {
n = n_entries-i;
@@ -642,7 +678,10 @@ int console_setcmap(int n_entries, unsigned char *red, unsigned char *green,
palette_cmap.green[j] = (green[i+j] << 8) | green[i+j];
palette_cmap.blue[j] = (blue[i+j] << 8) | blue[i+j];
}
- (*console_set_cmap_ptr)(&palette_cmap, 1, fg_console, console_fb_info);
+ err = console_fb_info->fbops->fb_set_cmap(&palette_cmap, 1, fg_console,
+ console_fb_info);
+ if (err)
+ return err;
}
return 0;
}
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
new file mode 100644
index 000000000..f2a3e9410
--- /dev/null
+++ b/drivers/video/platinumfb.c
@@ -0,0 +1,1052 @@
+/*
+ * platinumfb.c -- frame buffer device for the PowerMac 'platinum' display
+ *
+ * Created 12 July 1998 by Dan Jacobowitz <dan@debian.org>
+ * Copyright (C) 1998 Dan Jacobowitz
+ *
+ * Frame buffer structure from:
+ * drivers/video/chipsfb.c -- frame buffer device for
+ * Chips & Technologies 65550 chip.
+ *
+ * Copyright (C) 1998 Paul Mackerras
+ *
+ * This file is derived from the Powermac "chips" driver:
+ * Copyright (C) 1997 Fabio Riccardi.
+ * And from the frame buffer device for Open Firmware-initialized devices:
+ * Copyright (C) 1997 Geert Uytterhoeven.
+ *
+ * Hardware information from:
+ * platinum.c: Console support for PowerMac "platinum" display adaptor.
+ * Copyright (C) 1996 Paul Mackerras
+ *
+ * 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/config.h>
+#include <linux/module.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/selection.h>
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/nvram.h>
+#ifdef CONFIG_FB_COMPAT_XPMAC
+#include <asm/vc_ioctl.h>
+#endif
+#include <asm/io.h>
+#include <asm/prom.h>
+#include <asm/pgtable.h>
+#include <asm/adb.h>
+#include <asm/cuda.h>
+
+#include "fbcon.h"
+#include "fbcon-cfb8.h"
+#include "fbcon-cfb16.h"
+#include "fbcon-cfb32.h"
+
+#include "macmodes.h"
+#include "platinumfb.h"
+
+static int currcon = 0;
+static int switching = 0;
+
+struct fb_par_platinum {
+ int vmode, cmode;
+ int xres, yres;
+ int vxres, vyres;
+ int xoffset, yoffset;
+};
+
+struct fb_info_platinum {
+ struct fb_info info;
+ struct fb_fix_screeninfo fix;
+ struct fb_var_screeninfo var;
+ struct display disp;
+ struct fb_par_platinum par;
+ struct {
+ __u8 red, green, blue;
+ } palette[256];
+
+ volatile struct cmap_regs *cmap_regs;
+ unsigned long cmap_regs_phys;
+
+ volatile struct platinum_regs *platinum_regs;
+ unsigned long platinum_regs_phys;
+
+ __u8 *frame_buffer;
+ __u8 *base_frame_buffer;
+ unsigned long frame_buffer_phys;
+
+ int sense;
+ unsigned long total_vram;
+};
+
+/*
+ * Exported functions
+ */
+void platinum_init(void);
+void platinum_of_init(struct device_node *dp);
+
+static int platinum_open(struct fb_info *info, int user);
+static int platinum_release(struct fb_info *info, int user);
+static int platinum_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info);
+static int platinum_get_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int platinum_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int platinum_pan_display(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int platinum_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+static int platinum_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+static int platinum_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg, int con, struct fb_info *info);
+
+static int read_platinum_sense(struct fb_info_platinum *p);
+static inline int platinum_vram_reqd(int video_mode, int color_mode);
+static void set_platinum_clock(struct fb_info_platinum *p, unsigned char *params);
+static void platinum_set_hardware(struct fb_info_platinum *p);
+static void platinum_par_to_all(struct fb_info_platinum *p, int init);
+static inline void platinum_par_to_var(struct fb_par_platinum *par, struct fb_var_screeninfo *var);
+static int platinum_var_to_par(struct fb_var_screeninfo *var,
+ struct fb_par_platinum *par, const struct fb_info *fb_info);
+
+static void platinum_init_info(struct fb_info *info, struct fb_info_platinum *p);
+static void platinum_par_to_display(struct fb_par_platinum *par,
+ struct display *disp, struct fb_fix_screeninfo *fix, struct fb_info_platinum *p);
+static void platinum_init_display(struct display *disp);
+static void platinum_par_to_fix(struct fb_par_platinum *par, struct fb_fix_screeninfo *fix,
+ struct fb_info_platinum *p);
+static void platinum_init_fix(struct fb_fix_screeninfo *fix, struct fb_info_platinum *p);
+
+static struct fb_ops platinumfb_ops = {
+ platinum_open,
+ platinum_release,
+ platinum_get_fix,
+ platinum_get_var,
+ platinum_set_var,
+ platinum_get_cmap,
+ platinum_set_cmap,
+ platinum_pan_display,
+ platinum_ioctl
+};
+
+static int platinum_getcolreg(u_int regno, u_int *red, u_int *green,
+ u_int *blue, u_int *transp, struct fb_info *info);
+static int platinum_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info);
+static void do_install_cmap(int con, struct fb_info *info);
+
+#define FUNCID { printk(KERN_INFO "entering %s\n", __FUNCTION__); }
+
+__openfirmware
+
+
+static int platinum_open(struct fb_info *info, int user)
+{
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static int platinum_release(struct fb_info *info, int user)
+{
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+static int platinum_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info)
+{
+ struct fb_info_platinum *cp = (struct fb_info_platinum *) info;
+
+ *fix = cp->fix;
+ return 0;
+}
+
+static int platinum_get_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ struct fb_info_platinum *cp = (struct fb_info_platinum *) info;
+
+ *var = cp->var;
+ return 0;
+}
+
+/* Sets everything according to var */
+static int platinum_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ struct fb_info_platinum *p = (struct fb_info_platinum *) info;
+ struct display *disp;
+ struct fb_par_platinum par;
+ int depthchange, err;
+
+// FUNCID;
+ disp = (con >= 0) ? &fb_display[con] : &p->disp;
+ if((err = platinum_var_to_par(var, &par, info))) {
+ printk (KERN_ERR "Error in platinum_set_var, calling platinum_var_to_par: %d.\n", err);
+ return err;
+ }
+
+ if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW) {
+ printk("Not activating, in platinum_set_var.\n");
+ platinum_par_to_var(&par, var);
+ return 0;
+ }
+/* I know, we want to use fb_display[con], but grab certain info from p->var instead. */
+#define DIRTY(x) (p->var.x != var->x)
+ depthchange = DIRTY(bits_per_pixel);
+ if(!DIRTY(xres) && !DIRTY(yres) && !DIRTY(xres_virtual) &&
+ !DIRTY(yres_virtual) && !DIRTY(bits_per_pixel)) {
+ platinum_par_to_var(&par, var);
+ p->var = disp->var = *var;
+ return 0;
+ }
+ printk("Original bpp is %d, new bpp %d.\n", p->var.bits_per_pixel, var->bits_per_pixel);
+ /* OK, we're getting here at the right times... */
+ p->par = par;
+ platinum_par_to_var(&par, var);
+ p->var = *var;
+ platinum_par_to_fix(&par, &p->fix, p);
+ platinum_par_to_display(&par, disp, &p->fix, p);
+ p->disp = *disp;
+
+ if(info->changevar && !switching) /* Don't want to do this if just switching consoles. */
+ (*info->changevar)(con);
+ if(con == currcon)
+ platinum_set_hardware(p);
+ if(depthchange)
+ if((err = fb_alloc_cmap(&disp->cmap, 0, 0)))
+ return err;
+ if(depthchange || switching)
+ do_install_cmap(con, info);
+ return 0;
+}
+
+static int platinum_pan_display(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ /*
+ * Pan (or wrap, depending on the `vmode' field) the display using the
+ * `xoffset' and `yoffset' fields of the `var' structure.
+ * If the values don't fit, return -EINVAL.
+ */
+
+// FUNCID;
+ if (var->xoffset != 0 || var->yoffset != 0)
+ return -EINVAL;
+ return 0;
+}
+
+static int platinum_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+// FUNCID;
+ if (con == currcon) /* current console? */
+ return fb_get_cmap(cmap, &fb_display[con].var, kspc,
+ platinum_getcolreg, info);
+ if (fb_display[con].cmap.len) /* non default colormap? */
+ fb_copy_cmap(&fb_display[con].cmap, cmap, kspc? 0: 2);
+ else {
+ int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
+ fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
+ }
+ return 0;
+}
+
+static int platinum_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ struct display *disp = &fb_display[con];
+ int err;
+
+// FUNCID;
+ if (disp->cmap.len == 0) {
+ int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
+ err = fb_alloc_cmap(&disp->cmap, size, 0);
+ if (err)
+ return err;
+ }
+
+ if (con == currcon)
+ return fb_set_cmap(cmap, &disp->var, kspc, platinum_setcolreg,
+ info);
+ fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);
+ return 0;
+}
+
+static int platinum_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg, int con, struct fb_info *info)
+{
+// FUNCID;
+ return -EINVAL;
+}
+
+static int platinum_switch(int con, struct fb_info *info)
+{
+// FUNCID;
+ if (fb_display[currcon].cmap.len)
+ fb_get_cmap(&fb_display[currcon].cmap,
+ &fb_display[currcon].var, 1, platinum_getcolreg,
+ info);
+ currcon = con;
+#if 0
+ platinum_var_to_par(&fb_display[currcon].var, &par, info);
+ platinum_set_par(&par, info); /*STOPPEDHERE - did i define that? */
+ do_install_cmap(con, info);
+#else
+ /* I see no reason not to do this. Minus info->changevar(). */
+ /* DOH. This makes platinum_set_var compare, you guessed it, */
+ /* fb_display[con].var (first param), and fb_display[con].var! */
+ /* Perhaps I just fixed that... */
+ switching = 1;
+ platinum_set_var(&fb_display[con].var, con, info);
+ switching = 0;
+#endif
+ return 0;
+}
+
+static int platinum_updatevar(int con, struct fb_info *info)
+{
+ return 0;
+}
+
+static void platinum_blank(int blank_mode, struct fb_info *info)
+{
+/*
+ * 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
+ */
+/* [danj] I think there's something fishy about those constants... */
+/*
+ struct fb_info_platinum *p = (struct fb_info_platinum *) info;
+ int ctrl;
+
+ ctrl = ld_le32(&p->platinum_regs->ctrl.r) | 0x33;
+ if (blank_mode)
+ --blank_mode;
+ if (blank_mode & VESA_VSYNC_SUSPEND)
+ ctrl &= ~3;
+ if (blank_mode & VESA_HSYNC_SUSPEND)
+ ctrl &= ~0x30;
+ out_le32(&p->platinum_regs->ctrl.r, ctrl);
+*/
+/* TODO: Figure out how the heck to powerdown this thing! */
+//FUNCID;
+ return;
+}
+
+static int platinum_getcolreg(u_int regno, u_int *red, u_int *green,
+ u_int *blue, u_int *transp, struct fb_info *info)
+{
+ struct fb_info_platinum *p = (struct fb_info_platinum *) info;
+
+// FUNCID;
+ if (regno > 255 || regno < 0)
+ return 1;
+ *red = p->palette[regno].red;
+ *green = p->palette[regno].green;
+ *blue = p->palette[regno].blue;
+ return 0;
+}
+
+static int platinum_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info)
+{
+ struct fb_info_platinum *p = (struct fb_info_platinum *) info;
+
+// FUNCID;
+ if (regno > 255 || regno < 0)
+ return 1;
+ p->palette[regno].red = red;
+ p->palette[regno].green = green;
+ p->palette[regno].blue = blue;
+
+ out_8(&p->cmap_regs->addr, regno); /* tell clut what addr to fill */
+ out_8(&p->cmap_regs->lut, red); /* send one color channel at */
+ out_8(&p->cmap_regs->lut, green); /* a time... */
+ out_8(&p->cmap_regs->lut, blue);
+
+ if(regno < 16) {
+#if 0
+#ifdef FBCON_HAS_CFB16
+ fbcon_cfb16_cmap[regno] = (red << 10) | (green << 5) | blue;
+#endif
+#ifdef FBCON_HAS_CFB32
+ fbcon_cfb32_cmap[regno] = (red << 16) | (green << 8) | blue;
+ /* I think. */
+#endif
+#else
+#ifdef FBCON_HAS_CFB16
+ fbcon_cfb16_cmap[regno] = (regno << 10) | (regno << 5) | regno;
+#endif
+#ifdef FBCON_HAS_CFB32
+ fbcon_cfb32_cmap[regno] = (regno << 24) | (regno << 16) | (regno << 8) | regno;
+ /* I think. */
+#endif
+#endif
+ }
+ return 0;
+}
+
+static void do_install_cmap(int con, struct fb_info *info)
+{
+// FUNCID;
+ if (con != currcon)
+ return;
+ if (fb_display[con].cmap.len)
+ fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
+ platinum_setcolreg, info);
+ else {
+ int size = fb_display[con].var.bits_per_pixel == 16 ? 32 : 256;
+ fb_set_cmap(fb_default_cmap(size), &fb_display[con].var, 1,
+ platinum_setcolreg, info);
+ }
+}
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+extern struct vc_mode display_info;
+extern struct fb_info *console_fb_info;
+#if 0
+extern int (*console_setmode_ptr)(struct vc_mode *, int);
+extern int (*console_set_cmap_ptr)(struct fb_cmap *, int, int,
+ struct fb_info *);
+int console_setmode(struct vc_mode *, int);
+#endif
+#endif /* CONFIG_FB_COMPAT_XPMAC */
+
+static inline int platinum_vram_reqd(int video_mode, int color_mode)
+{
+ return vmode_attrs[video_mode - 1].vres
+ * platinum_reg_init[video_mode-1]->pitch[color_mode];
+}
+
+#define STORE_D2(a, d) { \
+ out_8(&p->cmap_regs->addr, (a+32)); \
+ out_8(&p->cmap_regs->d2, (d)); \
+}
+
+static void set_platinum_clock(struct fb_info_platinum *p, unsigned char *clock_params)
+{
+// FUNCID;
+ STORE_D2(6, 0xc6);
+ out_8(&p->cmap_regs->addr,3+32);
+ if (in_8(&p->cmap_regs->d2) == 2) {
+ STORE_D2(7, clock_params[0]);
+ STORE_D2(8, clock_params[1]);
+ STORE_D2(3, 3);
+ } else {
+ STORE_D2(4, clock_params[0]);
+ STORE_D2(5, clock_params[1]);
+ STORE_D2(3, 2);
+ }
+
+ __delay(5000);
+ STORE_D2(9, 0xa6);
+}
+
+
+__initfunc(static void init_platinum(struct fb_info_platinum *p))
+{
+ struct fb_par_platinum *par = &p->par;
+
+// FUNCID;
+ p->sense = read_platinum_sense(p);
+ printk("Monitor sense value = 0x%x, ", p->sense);
+ /* Try to pick a video mode out of NVRAM if we have one. */
+ par->vmode = nvram_read_byte(NV_VMODE);
+ if(par->vmode <= 0 || par->vmode > VMODE_MAX || !platinum_reg_init[par->vmode - 1])
+ par->vmode = VMODE_CHOOSE;
+ if(par->vmode == VMODE_CHOOSE)
+ par->vmode = mac_map_monitor_sense(p->sense);
+ if(!platinum_reg_init[par->vmode - 1])
+ par->vmode = VMODE_640_480_67;
+
+ par->cmode = nvram_read_byte(NV_CMODE);
+ if(par->cmode < CMODE_8 || par->cmode > CMODE_32)
+ par->cmode = CMODE_8;
+ /*
+ * Reduce the pixel size if we don't have enough VRAM.
+ */
+ while(par->cmode > CMODE_8 && platinum_vram_reqd(par->vmode, par->cmode) > p->total_vram)
+ par->cmode--;
+
+ printk("using video mode %d and color mode %d.\n", par->vmode, par->cmode);
+
+ par->vxres = par->xres = vmode_attrs[par->vmode - 1].hres;
+ par->vyres = par->yres = vmode_attrs[par->vmode - 1].vres;
+ par->xoffset = par->yoffset = 0;
+
+ platinum_par_to_all(p, 1);
+
+ if (register_framebuffer(&p->info) < 0) {
+ kfree(p);
+ return;
+ }
+ platinum_set_hardware(p);
+
+ printk("fb%d: platinum display adapter\n", GET_FB_IDX(p->info.node));
+}
+
+/* Now how about actually saying, Make it so! */
+/* Some things in here probably don't need to be done each time. */
+static void platinum_set_hardware(struct fb_info_platinum *p)
+{
+ struct platinum_regvals *init;
+ int i, dtype, clkmode;
+ int vmode, cmode;
+
+// FUNCID;
+ vmode = p->par.vmode;
+ cmode = p->par.cmode;
+
+ init = platinum_reg_init[vmode - 1];
+
+ /* Initialize display timing registers */
+ out_be32(&p->platinum_regs->reg[24].r, 7); /* turn display off */
+
+ for (i = 0; i < 26; ++i)
+ out_be32(&p->platinum_regs->reg[i+32].r, init->regs[i]);
+ out_be32(&p->platinum_regs->reg[26+32].r, (p->total_vram == 0x100000 ?
+ init->offset[cmode] + 4 - cmode :
+ init->offset[cmode]));
+ out_be32(&p->platinum_regs->reg[16].r, (unsigned) p->frame_buffer_phys + init->fb_offset);
+ out_be32(&p->platinum_regs->reg[18].r, init->pitch[cmode]);
+ out_be32(&p->platinum_regs->reg[19].r, (p->total_vram == 0x100000 ?
+ init->mode[cmode+1] :
+ init->mode[cmode]));
+ out_be32(&p->platinum_regs->reg[20].r, (p->total_vram == 0x100000 ? 0x11 : 0x1011));
+ out_be32(&p->platinum_regs->reg[21].r, 0x100);
+ out_be32(&p->platinum_regs->reg[22].r, 1);
+ out_be32(&p->platinum_regs->reg[23].r, 1);
+ out_be32(&p->platinum_regs->reg[26].r, 0xc00);
+ out_be32(&p->platinum_regs->reg[27].r, 0x235);
+ /* out_be32(&p->platinum_regs->reg[27].r, 0x2aa); */
+
+ STORE_D2(0, (p->total_vram == 0x100000 ?
+ init->dacula_ctrl[cmode] & 0xf :
+ init->dacula_ctrl[cmode]));
+ STORE_D2(1, 4);
+ STORE_D2(2, 0);
+ /*
+ * Try to determine whether we have an old or a new DACula.
+ */
+ out_8(&p->cmap_regs->addr, 0x40);
+ dtype = in_8(&p->cmap_regs->d2);
+ switch (dtype) {
+ case 0x3c:
+ clkmode = 1;
+ break;
+ case 0x84:
+ clkmode = 0;
+ break;
+ default:
+ clkmode = 0;
+ printk("Unknown DACula type: %x\n", dtype);
+ }
+
+ set_platinum_clock(p, init->clock_params[clkmode]);
+
+ out_be32(&p->platinum_regs->reg[24].r, 0); /* turn display on */
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+ /* And let the world know the truth. */
+ if (!console_fb_info || console_fb_info == &p->info) {
+ display_info.height = p->var.yres;
+ display_info.width = p->var.xres;
+ display_info.depth = ( (cmode == CMODE_32) ? 32 :
+ ((cmode == CMODE_16) ? 16 : 8));
+ display_info.pitch = p->fix.line_length;
+ display_info.mode = vmode;
+ strncpy(display_info.name, "platinum",
+ sizeof(display_info.name));
+ display_info.fb_address = p->frame_buffer_phys
+ + init->fb_offset
+ + 0x10;
+ display_info.cmap_adr_address = p->cmap_regs_phys;
+ display_info.cmap_data_address = p->cmap_regs_phys + 0x30;
+ display_info.disp_reg_address = p->platinum_regs_phys;
+ console_fb_info = &p->info;
+ }
+#endif /* CONFIG_FB_COMPAT_XPMAC */
+}
+
+__initfunc(void platinum_init(void))
+{
+#ifndef CONFIG_FB_OF
+ struct device_node *dp;
+
+ dp = find_devices("platinum");
+ if (dp != 0)
+ platinum_of_init(dp);
+#endif /* CONFIG_FB_OF */
+}
+
+__initfunc(void platinum_of_init(struct device_node *dp))
+{
+ struct fb_info_platinum *p;
+ unsigned long addr, size;
+ int i, bank0, bank1, bank2, bank3;
+//FUNCID;
+ if(dp->n_addrs != 2)
+ panic("expecting 2 address for platinum (got %d)", dp->n_addrs);
+ p = kmalloc(sizeof(*p), GFP_ATOMIC);
+ if (p == 0)
+ return;
+
+ /* Map in frame buffer and registers */
+ for (i = 0; i < dp->n_addrs; ++i) {
+ addr = dp->addrs[i].address;
+ size = dp->addrs[i].size;
+ if (size >= 0x400000) {
+ /* frame buffer - map only 4MB */
+ p->frame_buffer_phys = addr;
+ p->frame_buffer = __ioremap(addr, 0x400000, _PAGE_WRITETHRU);
+ p->base_frame_buffer = p->frame_buffer;
+ } else {
+ /* registers */
+ p->platinum_regs_phys = addr;
+ p->platinum_regs = ioremap(addr, size);
+ }
+ }
+ p->cmap_regs_phys = 0xf301b000; /* XXX not in prom? */
+ p->cmap_regs = ioremap(p->cmap_regs_phys, 0x1000);
+
+ /* Grok total video ram */
+ out_be32(&p->platinum_regs->reg[16].r, (unsigned)p->frame_buffer_phys);
+ out_be32(&p->platinum_regs->reg[20].r, 0x1011); /* select max vram */
+ out_be32(&p->platinum_regs->reg[24].r, 0); /* switch in vram */
+ eieio();
+ p->frame_buffer[0x100000] = 0x34;
+ asm volatile("eieio; dcbi 0,%0" : : "r" (&p->frame_buffer[0x100000]) : "memory");
+ p->frame_buffer[0x200000] = 0x56;
+ asm volatile("eieio; dcbi 0,%0" : : "r" (&p->frame_buffer[0x200000]) : "memory");
+ p->frame_buffer[0x300000] = 0x78;
+ asm volatile("eieio; dcbi 0,%0" : : "r" (&p->frame_buffer[0x300000]) : "memory");
+ bank0 = 1; /* builtin 1MB vram, always there */
+ bank1 = p->frame_buffer[0x100000] == 0x34;
+ bank2 = p->frame_buffer[0x200000] == 0x56;
+ bank3 = p->frame_buffer[0x300000] == 0x78;
+ p->total_vram = (bank0 + bank1 + bank2 + bank3) * 0x100000;
+ printk("Total VRAM = %dMB\n", p->total_vram / 1024 / 1024);
+
+// p->frame_buffer = p->base_frame_buffer
+// + platinum_reg_init[p->par.vmode-1]->fb_offset;
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+#if 0
+ console_set_cmap_ptr = platinum_set_cmap;
+ console_setmode_ptr = platinum_console_setmode;
+#endif
+#endif /* CONFIG_FB_COMPAT_XPMAC */
+
+ init_platinum(p);
+}
+
+/*
+ * Get the monitor sense value.
+ * Note that this can be called before calibrate_delay,
+ * so we can't use udelay.
+ */
+static int read_platinum_sense(struct fb_info_platinum *p)
+{
+ int sense;
+
+ out_be32(&p->platinum_regs->reg[23].r, 7); /* turn off drivers */
+ __delay(2000);
+ sense = (~in_be32(&p->platinum_regs->reg[23].r) & 7) << 8;
+
+ /* drive each sense line low in turn and collect the other 2 */
+ out_be32(&p->platinum_regs->reg[23].r, 3); /* drive A low */
+ __delay(2000);
+ sense |= (~in_be32(&p->platinum_regs->reg[23].r) & 3) << 4;
+ out_be32(&p->platinum_regs->reg[23].r, 5); /* drive B low */
+ __delay(2000);
+ sense |= (~in_be32(&p->platinum_regs->reg[23].r) & 4) << 1;
+ sense |= (~in_be32(&p->platinum_regs->reg[23].r) & 1) << 2;
+ out_be32(&p->platinum_regs->reg[23].r, 6); /* drive C low */
+ __delay(2000);
+ sense |= (~in_be32(&p->platinum_regs->reg[23].r) & 6) >> 1;
+
+ out_be32(&p->platinum_regs->reg[23].r, 7); /* turn off drivers */
+
+ return sense;
+}
+
+#if 0
+/* This routine takes a user-supplied var, and picks the best vmode/cmode from it. */
+static int platinum_var_to_par(struct fb_var_screeninfo *var,
+ struct fb_par_platinum *par, const struct fb_info *fb_info)
+{
+ int xres = var->xres;
+ int yres = var->yres;
+ int bpp = var->bits_per_pixel;
+
+ struct platinum_regvals *init;
+ struct fb_info_platinum *p = (struct fb_info_platinum *) fb_info;
+
+// FUNCID;
+ /*
+ * Get the video params out of 'var'. If a value doesn't fit, round it up,
+ * if it's too big, return -EINVAL.
+ *
+ * Suggestion: Round up in the following order: bits_per_pixel, xres,
+ * yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale,
+ * bitfields, horizontal timing, vertical timing.
+ */
+ /* swiped by jonh from atyfb.c */
+ if (xres <= 512 && yres <= 384)
+ par->vmode = VMODE_512_384_60; /* 512x384, 60Hz */
+ else if (xres <= 640 && yres <= 480)
+ par->vmode = VMODE_640_480_67; /* 640x480, 67Hz */
+ else if (xres <= 640 && yres <= 870)
+ par->vmode = VMODE_640_870_75P; /* 640x870, 75Hz (portrait) */
+ else if (xres <= 768 && yres <= 576)
+ par->vmode = VMODE_768_576_50I; /* 768x576, 50Hz (PAL full frame) */
+ else if (xres <= 800 && yres <= 600)
+ par->vmode = VMODE_800_600_75; /* 800x600, 75Hz */
+ else if (xres <= 832 && yres <= 624)
+ par->vmode = VMODE_832_624_75; /* 832x624, 75Hz */
+ else if (xres <= 1024 && yres <= 768)
+ par->vmode = VMODE_1024_768_75; /* 1024x768, 75Hz */
+ else if (xres <= 1152 && yres <= 870)
+ par->vmode = VMODE_1152_870_75; /* 1152x870, 75Hz */
+ else if (xres <= 1280 && yres <= 960)
+ par->vmode = VMODE_1280_960_75; /* 1280x960, 75Hz */
+ else if (xres <= 1280 && yres <= 1024)
+ par->vmode = VMODE_1280_1024_75; /* 1280x1024, 75Hz */
+ else {
+ printk(KERN_ERR "Bad resolution in platinum_var_to_par()!\n");
+ return -EINVAL;
+ }
+ xres = vmode_attrs[par->vmode - 1].hres;
+ yres = vmode_attrs[par->vmode - 1].vres;
+
+/*
+ if (var->xres_virtual <= xres)
+ par->vxres = xres;
+ else
+ par->vxres = (var->xres_virtual+7) & ~7;
+ if (var->yres_virtual <= yres)
+ par->vyres = yres;
+ else
+ par->vyres = var->yres_virtual;
+
+ par->xoffset = (var->xoffset+7) & ~7;
+ par->yoffset = var->yoffset;
+ if (par->xoffset+xres > par->vxres || par->yoffset+yres > par->vyres)
+ return -EINVAL;
+*/
+
+ /* I'm too chicken to think about virtual */
+ /* resolutions just yet. Bok bok. */
+
+ /* And I'm too chicken to even figure out what they are. Awk awk. [danj] */
+ if (var->xres_virtual > xres || var->yres_virtual > yres
+ || var->xoffset != 0 || var->yoffset != 0) {
+ printk(KERN_ERR "Bad virtual resolution in platinum_var_to_par()!\n");
+ return -EINVAL;
+ }
+
+ par->xres = xres;
+ par->yres = yres;
+ par->vxres = xres;
+ par->vyres = yres;
+ par->xoffset = 0;
+ par->yoffset = 0;
+
+ if (bpp <= 8)
+ par->cmode = CMODE_8;
+ else if (bpp <= 16)
+ par->cmode = CMODE_16;
+ else if (bpp <= 32)
+ par->cmode = CMODE_32;
+ else {
+ printk(KERN_ERR "Bad color mode in platinum_var_to_par()!\n");
+ return -EINVAL;
+ }
+
+ if (platinum_vram_reqd(par->vmode, par->cmode) > p->total_vram) {
+ printk(KERN_ERR "Bad vram size requested in platinum_var_to_par()!\n");
+ return -EINVAL;
+ }
+ /* Check if we know about the wanted video mode */
+ init = platinum_reg_init[par->vmode-1];
+ if (init == NULL) {
+ /* I'm not sure if platinum has any specific requirements -- */
+ /* if we have a regvals struct, we're good to go? */
+ printk(KERN_ERR "platinum_reg_init failed platinum_var_to_par()!\n");
+ return -EINVAL;
+ }
+
+ return 0;
+}
+#else
+/* This routine takes a user-supplied var, and picks the best vmode/cmode from it. */
+static int platinum_var_to_par(struct fb_var_screeninfo *var,
+ struct fb_par_platinum *par, const struct fb_info *fb_info)
+{
+ struct fb_info_platinum *p = (struct fb_info_platinum *) fb_info;
+
+// FUNCID;
+ if(mac_var_to_vmode(var, &par->vmode, &par->cmode) != 0)
+ return -EINVAL;
+ par->xres = par->vxres = vmode_attrs[par->vmode - 1].hres;
+ par->yres = par->vyres = vmode_attrs[par->vmode - 1].vres;
+ par->xoffset = par->yoffset = 0;
+
+ if (platinum_vram_reqd(par->vmode, par->cmode) > p->total_vram)
+ return -EINVAL;
+
+ /* Check if we know about the wanted video mode */
+ if(!platinum_reg_init[par->vmode-1]) {
+ /* I'm not sure if platinum has any specific requirements -- */
+ /* if we have a regvals struct, we're good to go? */
+ return -EINVAL;
+ }
+ return 0;
+}
+#endif
+
+#if 0
+static void platinum_par_to_var(struct fb_par_platinum *par, struct fb_var_screeninfo *var)
+{
+ memset(var, 0, sizeof(*var));
+ var->xres = vmode_attrs[par->vmode - 1].hres;
+ var->yres = vmode_attrs[par->vmode - 1].vres;
+ var->xres_virtual = var->xres;
+ var->yres_virtual = var->yres; /* For now. */
+ var->xoffset = par->xoffset;
+ var->yoffset = par->yoffset;
+ var->grayscale = 0;
+
+ if(par->cmode != CMODE_8 && par->cmode != CMODE_16 && par->cmode != CMODE_32) {
+ printk(KERN_ERR "Bad color mode in platinum_par_to_var()!\n");
+ par->cmode = CMODE_8;
+ }
+ switch(par->cmode) {
+ case CMODE_8:
+ var->bits_per_pixel = 8;
+ var->red.offset = 0;
+ var->red.length = 8;
+ var->green.offset = 0;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ break;
+ case CMODE_16: /* RGB 555 */
+ var->bits_per_pixel = 16;
+ var->red.offset = 10;
+ var->red.length = 5;
+ var->green.offset = 5;
+ var->green.length = 5;
+ var->blue.offset = 0;
+ var->blue.length = 5;
+ var->transp.offset = 0;
+ var->transp.length = 0;
+ break;
+ case CMODE_32: /* RGB 888 */
+ var->bits_per_pixel = 32;
+ var->red.offset = 16;
+ var->red.length = 8;
+ var->green.offset = 8;
+ var->green.length = 8;
+ var->blue.offset = 0;
+ var->blue.length = 8;
+ var->transp.offset = 24;
+ var->transp.length = 8;
+ break;
+ }
+ var->red.msb_right = 0;
+ var->green.msb_right = 0;
+ var->blue.msb_right = 0;
+ var->transp.msb_right = 0;
+ var->nonstd = 0;
+ var->activate = 0;
+ var->height = -1;
+ var->width = -1;
+ var->vmode = FB_VMODE_NONINTERLACED;
+
+ /* these are total guesses, copied right out of atyfb.c */
+ var->left_margin = var->right_margin = 64;
+ var->upper_margin = var->lower_margin = 32;
+ var->hsync_len = 8;
+ var->vsync_len = 8;
+ var->sync = 0;
+
+#if 1
+/* jonh's pixclocks...*/
+ /* no long long support in the kernel :-( */
+ /* this splittig trick will work if xres > 232 */
+ var->pixclock = 1000000000/
+ (var->left_margin+var->xres+var->right_margin+var->hsync_len);
+ var->pixclock *= 1000;
+ var->pixclock /= vmode_attrs[par->vmode-1].vfreq*
+ (var->upper_margin+var->yres+var->lower_margin+var->vsync_len);
+#else
+/* danj's */
+ /* 10^12 * clock_params[0] / (3906400 * clock_params[1] * 2^clock_params[2]) */
+ /* (10^12 * clock_params[0] / (3906400 * clock_params[1])) >> clock_params[2] */
+ /* (255990.17 * clock_params[0] / clock_params[1]) >> clock_params[2] */
+ var->pixclock = 255990 * platinum_reg_init[par->vmode-1]->clock_params[0];
+ var->pixclock /= platinum_reg_init[par->vmode-1]->clock_params[1];
+ var->pixclock >>= platinum_reg_init[par->vmode-1]->clock_params[2];
+#endif
+}
+#else
+static inline void platinum_par_to_var(struct fb_par_platinum *par, struct fb_var_screeninfo *var)
+{
+// FUNCID;
+ mac_vmode_to_var(par->vmode, par->cmode, var);
+}
+#endif
+
+static void platinum_init_fix(struct fb_fix_screeninfo *fix, struct fb_info_platinum *p)
+{
+// FUNCID;
+ memset(fix, 0, sizeof(*fix));
+ strcpy(fix->id, "platinum");
+ fix->mmio_start = (char *)p->platinum_regs_phys;
+ fix->mmio_len = 0x1000;
+ fix->type = FB_TYPE_PACKED_PIXELS;
+
+ fix->type_aux = 0;
+ fix->ywrapstep = 0;
+ fix->xpanstep = 0;
+ fix->ypanstep = 0;
+}
+
+/* Fix must already be inited ^^^^^^^ */
+static void platinum_par_to_fix(struct fb_par_platinum *par,
+ struct fb_fix_screeninfo *fix,
+ struct fb_info_platinum *p)
+{
+// FUNCID;
+ fix->smem_start = (void *)(p->frame_buffer_phys);
+ fix->smem_len = platinum_vram_reqd(par->vmode, par->cmode);
+ /* Hmm, jonh used total_vram here. */
+ fix->visual = (par->cmode == CMODE_8) ?
+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
+// fix->line_length = par->vxres << par->cmode;
+ fix->line_length = platinum_reg_init[par->vmode-1]->pitch[par->cmode];
+
+}
+
+static void platinum_init_display(struct display *disp)
+{
+ memset(disp, 0, sizeof(*disp));
+ disp->type = /* fix->type */ FB_TYPE_PACKED_PIXELS;
+ disp->can_soft_blank = 1;
+ disp->scrollmode = SCROLL_YREDRAW;
+#if 0
+ disp->type_aux = fix->type_aux;
+ disp->cmap.red = NULL; /* ??? danj */
+ disp->cmap.green = NULL;
+ disp->cmap.blue = NULL;
+ disp->cmap.transp = NULL;
+ /* Yeah, I realize I just set 0 = 0. */
+#endif
+}
+
+static void platinum_par_to_display(struct fb_par_platinum *par,
+ struct display *disp, struct fb_fix_screeninfo *fix, struct fb_info_platinum *p)
+{
+// FUNCID;
+ disp->var = p->var;
+ disp->screen_base = (char *) p->frame_buffer
+ + platinum_reg_init[par->vmode-1]->fb_offset
+ + ((par->yres % 16) / 2) * fix->line_length + 0x10;
+ disp->visual = fix->visual;
+ disp->line_length = fix->line_length;
+
+ if(disp->scrollmode != SCROLL_YREDRAW) {
+ printk(KERN_ERR "Scroll mode not YREDRAW in platinum_par_to_display!!\n");
+ disp->scrollmode = SCROLL_YREDRAW;
+ }
+
+ switch(par->cmode) {
+#ifdef FBCON_HAS_CFB8
+ case CMODE_8:
+ disp->dispsw = &fbcon_cfb8;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB16
+ case CMODE_16:
+ disp->dispsw = &fbcon_cfb16;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB32
+ case CMODE_32:
+ disp->dispsw = &fbcon_cfb32;
+ break;
+#endif
+ default:
+ disp->dispsw = NULL;
+ break;
+ }
+}
+
+static void platinum_init_info(struct fb_info *info, struct fb_info_platinum *p)
+{
+// FUNCID;
+ strcpy(info->modename, p->fix.id);
+ info->node = -1; /* ??? danj */
+ info->fbops = &platinumfb_ops;
+ info->disp = &p->disp;
+ info->fontname[0] = 0;
+ info->changevar = NULL;
+ info->switch_con = &platinum_switch;
+ info->updatevar = &platinum_updatevar;
+ info->blank = &platinum_blank;
+}
+
+/* danj: Oh, I HOPE I didn't miss anything major in here... */
+static void platinum_par_to_all(struct fb_info_platinum *p, int init)
+{
+// FUNCID;
+ if(init) {
+ platinum_init_fix(&p->fix, p);
+ }
+ platinum_par_to_fix(&p->par, &p->fix, p);
+
+ platinum_par_to_var(&p->par, &p->var);
+
+ if(init) {
+ platinum_init_display(&p->disp);
+ }
+ platinum_par_to_display(&p->par, &p->disp, &p->fix, p);
+
+ if(init) {
+ platinum_init_info(&p->info, p);
+ }
+}
+
+#if 0
+__initfunc(void platinum_setup(char *options, int *ints))
+{
+ /* Parse user speficied options (`video=platinumfb:') */
+ FUNCID;
+}
+
+#endif
+
diff --git a/drivers/video/platinumfb.h b/drivers/video/platinumfb.h
new file mode 100644
index 000000000..a9b4b1c8f
--- /dev/null
+++ b/drivers/video/platinumfb.h
@@ -0,0 +1,399 @@
+/*
+ * linux/drivers/video/platinumfb-hw.c -- Frame buffer device for the
+ * Platinum on-board video in PowerMac 7200s (and some clones based
+ * on the same motherboard.)
+ *
+ * Created 09 Feb 1998 by Jon Howell <jonh@cs.dartmouth.edu>
+ *
+ * Copyright (C) 1998 Jon Howell
+ *
+ * based on drivers/macintosh/platinum.c: Console support
+ * for PowerMac "platinum" display adaptor.
+ * Copyright (C) 1996 Paul Mackerras and Mark Abene.
+ *
+ * based on skeletonfb.c:
+ * Created 28 Dec 1997 by Geert Uytterhoeven
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file README.legal in the main directory of this archive
+ * for more details.
+ */
+
+/*
+ * Structure of the registers for the DACula colormap device.
+ */
+struct cmap_regs {
+ unsigned char addr;
+ char pad1[15];
+ unsigned char d1;
+ char pad2[15];
+ unsigned char d2;
+ char pad3[15];
+ unsigned char lut;
+ char pad4[15];
+};
+
+/*
+ * Structure of the registers for the "platinum" display adaptor".
+ */
+struct preg { /* padded register */
+ unsigned r; /* notice this is 32 bits. */
+ char pad[12];
+};
+
+struct platinum_regs {
+ struct preg reg[128];
+};
+
+/*
+ * Register initialization tables for the platinum display.
+ *
+ * It seems that there are two different types of platinum display
+ * out there. Older ones use the values in clocksel[1], for which
+ * the formula for the clock frequency seems to be
+ * F = 14.3MHz * c0 / (c1 & 0x1f) / (1 << (c1 >> 5))
+ * Newer ones use the values in clocksel[0], for which the formula
+ * seems to be
+ * F = 15MHz * c0 / ((c1 & 0x1f) + 2) / (1 << (c1 >> 5))
+ */
+struct platinum_regvals {
+ int fb_offset;
+ int pitch[3];
+ unsigned regs[26];
+ unsigned char offset[3];
+ unsigned char mode[3];
+ unsigned char dacula_ctrl[3];
+ unsigned char clock_params[2][2];
+};
+
+#define DIV2 0x20
+#define DIV4 0x40
+#define DIV8 0x60
+#define DIV16 0x80
+
+/* 1280x1024, 75Hz (20) */
+static struct platinum_regvals platinum_reg_init_20 = {
+ 0x5c00,
+ { 1312, 2592, 2592 },
+ { 0xffc, 4, 0, 0, 0, 0, 0x428, 0,
+ 0, 0xb3, 0xd3, 0x12, 0x1a5, 0x23, 0x28, 0x2d,
+ 0x5e, 0x19e, 0x1a4, 0x854, 0x852, 4, 9, 0x50,
+ 0x850, 0x851 }, { 0x58, 0x5d, 0x5d },
+ { 0, 0xff, 0xff }, { 0x51, 0x55, 0x55 },
+ {{ 45, 3 }, { 66, 7 }}
+};
+
+/* 1280x960, 75Hz (19) */
+static struct platinum_regvals platinum_reg_init_19 = {
+ 0x5c00,
+ { 1312, 2592, 2592 },
+ { 0xffc, 4, 0, 0, 0, 0, 0x428, 0,
+ 0, 0xb2, 0xd2, 0x12, 0x1a3, 0x23, 0x28, 0x2d,
+ 0x5c, 0x19c, 0x1a2, 0x7d0, 0x7ce, 4, 9, 0x4c,
+ 0x7cc, 0x7cd }, { 0x56, 0x5b, 0x5b },
+ { 0, 0xff, 0xff }, { 0x51, 0x55, 0x55 },
+ {{ 42, 3 }, { 44, 5 }}
+};
+
+/* 1152x870, 75Hz (18) */
+static struct platinum_regvals platinum_reg_init_18 = {
+ 0x11b0,
+ { 1184, 2336, 4640 },
+ { 0xff0, 4, 0, 0, 0, 0, 0x38f, 0,
+ 0, 0x294, 0x16c, 0x20, 0x2d7, 0x3f, 0x49, 0x53,
+ 0x82, 0x2c2, 0x2d6, 0x726, 0x724, 4, 9, 0x52,
+ 0x71e, 0x722 }, { 0x74, 0x7c, 0x81 },
+ { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
+ {{ 26, 0 + DIV2 }, { 42, 6 }}
+};
+
+/* 1024x768, 75Hz (17) */
+static struct platinum_regvals platinum_reg_init_17 = {
+ 0x10b0,
+ { 1056, 2080, 4128 },
+ { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
+ 0, 0x254, 0x14b, 0x18, 0x295, 0x2f, 0x32, 0x3b,
+ 0x80, 0x280, 0x296, 0x648, 0x646, 4, 9, 0x40,
+ 0x640, 0x644 }, { 0x72, 0x7a, 0x7f },
+ { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
+ {{ 54, 3 + DIV2 }, { 67, 12 }}
+};
+
+/* 1024x768, 75Hz (16) */
+static struct platinum_regvals platinum_reg_init_16 = {
+ 0x10b0,
+ { 1056, 2080, 4128 },
+ { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
+ 0, 0x250, 0x147, 0x17, 0x28f, 0x2f, 0x35, 0x47,
+ 0x82, 0x282, 0x28e, 0x640, 0x63e, 4, 9, 0x3c,
+ 0x63c, 0x63d }, { 0x74, 0x7c, 0x81 },
+ { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
+ {{ 20, 0 + DIV2 }, { 11, 2 }}
+};
+
+/* 1024x768, 70Hz (15) */
+static struct platinum_regvals platinum_reg_init_15 = {
+ 0x10b0,
+ { 1056, 2080, 4128 },
+ { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
+ 0, 0x254, 0x14b, 0x22, 0x297, 0x43, 0x49, 0x5b,
+ 0x86, 0x286, 0x296, 0x64c, 0x64a, 0xa, 0xf, 0x44,
+ 0x644, 0x646 }, { 0x78, 0x80, 0x85 },
+ { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
+ {{ 19, 0 + DIV2 }, { 110, 21 }}
+};
+
+/* 1024x768, 60Hz (14) */
+static struct platinum_regvals platinum_reg_init_14 = {
+ 0x10b0,
+ { 1056, 2080, 4128 },
+ { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
+ 0, 0x25a, 0x14f, 0x22, 0x29f, 0x43, 0x49, 0x5b,
+ 0x8e, 0x28e, 0x29e, 0x64c, 0x64a, 0xa, 0xf, 0x44,
+ 0x644, 0x646 }, { 0x80, 0x88, 0x8d },
+ { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
+ {{ 71, 6 + DIV2 }, { 118, 13 + DIV2 }}
+};
+
+/* 832x624, 75Hz (13) */
+static struct platinum_regvals platinum_reg_init_13 = {
+ 0x70,
+ { 864, 1680, 3360 }, /* MacOS does 1680 instead of 1696 to fit 16bpp in 1MB */
+ { 0xff0, 4, 0, 0, 0, 0, 0x299, 0,
+ 0, 0x21e, 0x120, 0x10, 0x23f, 0x1f, 0x25, 0x37,
+ 0x8a, 0x22a, 0x23e, 0x536, 0x534, 4, 9, 0x52,
+ 0x532, 0x533 }, { 0x7c, 0x84, 0x89 },
+ { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
+ {{ 30, 0 + DIV4 }, { 56, 7 + DIV2 }}
+};
+
+/* 800x600, 75Hz (12) */
+static struct platinum_regvals platinum_reg_init_12 = {
+ 0x1010,
+ { 832, 1632, 3232 },
+ { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
+ 0, 0x1ce, 0x108, 0x14, 0x20f, 0x27, 0x30, 0x39,
+ 0x72, 0x202, 0x20e, 0x4e2, 0x4e0, 4, 9, 0x2e,
+ 0x4de, 0x4df }, { 0x64, 0x6c, 0x71 },
+ { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
+ {{ 122, 7 + DIV4 }, { 62, 9 + DIV2 }}
+};
+
+/* 800x600, 72Hz (11) */
+static struct platinum_regvals platinum_reg_init_11 = {
+ 0x1010,
+ { 832, 1632, 3232 },
+ { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
+ 0, 0x1ca, 0x104, 0x1e, 0x207, 0x3b, 0x44, 0x4d,
+ 0x56, 0x1e6, 0x206, 0x534, 0x532, 0xa, 0xe, 0x38,
+ 0x4e8, 0x4ec }, { 0x48, 0x50, 0x55 },
+ { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
+ {{ 26, 0 + DIV4 }, { 42, 6 + DIV2 }}
+};
+
+/* 800x600, 60Hz (10) */
+static struct platinum_regvals platinum_reg_init_10 = {
+ 0x1010,
+ { 832, 1632, 3232 },
+ { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
+ 0, 0x1ce, 0x108, 0x20, 0x20f, 0x3f, 0x45, 0x5d,
+ 0x66, 0x1f6, 0x20e, 0x4e8, 0x4e6, 6, 0xa, 0x34,
+ 0x4e4, 0x4e5 }, { 0x58, 0x60, 0x65 },
+ { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
+ {{ 54, 3 + DIV4 }, { 95, 1 + DIV8 }}
+};
+
+/* 800x600, 56Hz (9) --unsupported? copy of mode 10 for now... */
+static struct platinum_regvals platinum_reg_init_9 = {
+ 0x1010,
+ { 832, 1632, 3232 },
+ { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
+ 0, 0x1ce, 0x108, 0x20, 0x20f, 0x3f, 0x45, 0x5d,
+ 0x66, 0x1f6, 0x20e, 0x4e8, 0x4e6, 6, 0xa, 0x34,
+ 0x4e4, 0x4e5 }, { 0x58, 0x60, 0x65 },
+ { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
+ {{ 54, 3 + DIV4 }, { 88, 1 + DIV8 }}
+};
+
+/* 768x576, 50Hz Interlaced-PAL (8) */
+static struct platinum_regvals platinum_reg_init_8 = {
+ 0x1010,
+ { 800, 1568, 3104 },
+ { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
+ 0, 0xc8, 0xec, 0x11, 0x1d7, 0x22, 0x25, 0x36,
+ 0x47, 0x1c7, 0x1d6, 0x271, 0x270, 4, 9, 0x27,
+ 0x267, 0x26b }, { 0x39, 0x41, 0x46 },
+ { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
+ {{ 31, 0 + DIV16 }, { 74, 9 + DIV8 }}
+};
+
+/* 640x870, 75Hz Portrait (7) */
+static struct platinum_regvals platinum_reg_init_7 = {
+ 0xb10,
+ { 672, 1312, 2592 },
+ { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
+ 0, 0x176, 0xd0, 0x14, 0x19f, 0x27, 0x2d, 0x3f,
+ 0x4a, 0x18a, 0x19e, 0x72c, 0x72a, 4, 9, 0x58,
+ 0x724, 0x72a }, { 0x3c, 0x44, 0x49 },
+ { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
+ {{ 30, 0 + DIV4 }, { 56, 7 + DIV2 }}
+};
+
+/* 640x480, 67Hz (6) */
+static struct platinum_regvals platinum_reg_init_6 = {
+ 0x1010,
+ { 672, 1312, 2592 },
+ { 0xff0, 4, 0, 0, 0, 0, 0x209, 0,
+ 0, 0x18e, 0xd8, 0x10, 0x1af, 0x1f, 0x25, 0x37,
+ 0x4a, 0x18a, 0x1ae, 0x41a, 0x418, 4, 9, 0x52,
+ 0x412, 0x416 }, { 0x3c, 0x44, 0x49 },
+ { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
+ {{ 99, 4 + DIV8 }, { 42, 5 + DIV4 }}
+};
+
+/* 640x480, 60Hz (5) */
+static struct platinum_regvals platinum_reg_init_5 = {
+ 0x1010,
+ { 672, 1312, 2592 },
+ { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
+ 0, 0x15e, 0xc8, 0x18, 0x18f, 0x2f, 0x35, 0x3e,
+ 0x42, 0x182, 0x18e, 0x41a, 0x418, 2, 7, 0x44,
+ 0x404, 0x408 }, { 0x34, 0x3c, 0x41 },
+ { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
+ {{ 26, 0 + DIV8 }, { 14, 2 + DIV4 }}
+};
+
+/* 640x480, 60Hz Interlaced-NTSC (4) */
+static struct platinum_regvals platinum_reg_init_4 = {
+ 0x1010,
+ { 672, 1312, 2592 },
+ { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
+ 0, 0xa5, 0xc3, 0xe, 0x185, 0x1c, 0x1f, 0x30,
+ 0x37, 0x177, 0x184, 0x20d, 0x20c, 5, 0xb, 0x23,
+ 0x203, 0x206 }, { 0x29, 0x31, 0x36 },
+ { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
+ {{ 94, 5 + DIV16 }, { 48, 7 + DIV8 }}
+};
+
+/* 640x480, 50Hz Interlaced-PAL (3) */
+static struct platinum_regvals platinum_reg_init_3 = {
+ 0x1010,
+ { 672, 1312, 2592 },
+ { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
+ 0, 0xc8, 0xec, 0x11, 0x1d7, 0x22, 0x25, 0x36,
+ 0x67, 0x1a7, 0x1d6, 0x271, 0x270, 4, 9, 0x57,
+ 0x237, 0x26b }, { 0x59, 0x61, 0x66 },
+ { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
+ {{ 31, 0 + DIV16 }, { 74, 9 + DIV8 }}
+};
+
+/* 512x384, 60Hz (2) */
+static struct platinum_regvals platinum_reg_init_2 = {
+ 0x1010,
+ { 544, 1056, 2080 },
+ { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
+ 0, 0x25c, 0x140, 0x10, 0x27f, 0x1f, 0x2b, 0x4f,
+ 0x68, 0x268, 0x27e, 0x32e, 0x32c, 4, 9, 0x2a,
+ 0x32a, 0x32b }, { 0x5a, 0x62, 0x67 },
+ { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
+ {{ 33, 2 + DIV8 }, { 79, 9 + DIV8 }}
+};
+
+/* 512x384, 60Hz Interlaced-NTSC (1) */
+static struct platinum_regvals platinum_reg_init_1 = {
+ 0x1010,
+ { 544, 1056, 2080 },
+ { 0xff0, 4, 0, 0, 0, 0, 0x320, 0,
+ 0, 0xa5, 0xc3, 0xe, 0x185, 0x1c, 0x1f, 0x30,
+ 0x57, 0x157, 0x184, 0x20d, 0x20c, 5, 0xb, 0x53,
+ 0x1d3, 0x206 }, { 0x49, 0x51, 0x56 },
+ { 2, 0, 0xff }, { 0x11, 0x15, 0x19 },
+ {{ 94, 5 + DIV16 }, { 48, 7 + DIV8 }}
+};
+
+#define VMODE_MAX 20
+
+static struct platinum_regvals *platinum_reg_init[VMODE_MAX] = {
+ &platinum_reg_init_1,
+ &platinum_reg_init_2,
+ &platinum_reg_init_3,
+ &platinum_reg_init_4,
+ &platinum_reg_init_5,
+ &platinum_reg_init_6,
+ &platinum_reg_init_7,
+ &platinum_reg_init_8,
+ &platinum_reg_init_9,
+ &platinum_reg_init_10,
+ &platinum_reg_init_11,
+ &platinum_reg_init_12,
+ &platinum_reg_init_13,
+ &platinum_reg_init_14,
+ &platinum_reg_init_15,
+ &platinum_reg_init_16,
+ &platinum_reg_init_17,
+ &platinum_reg_init_18,
+ &platinum_reg_init_19,
+ &platinum_reg_init_20
+};
+
+struct vmode_attr {
+ int hres;
+ int vres;
+ int vfreq;
+ int interlaced;
+};
+
+struct vmode_attr vmode_attrs[VMODE_MAX] = {
+ {512, 384, 60, 1},
+ {512, 384, 60},
+ {640, 480, 50, 1},
+ {640, 480, 60, 1},
+ {640, 480, 60},
+ {640, 480, 67},
+ {640, 870, 75},
+ {768, 576, 50, 1},
+ {800, 600, 56},
+ {800, 600, 60},
+ {800, 600, 72},
+ {800, 600, 75},
+ {832, 624, 75},
+ {1024, 768, 60},
+ {1024, 768, 72},
+ {1024, 768, 75},
+ {1024, 768, 75},
+ {1152, 870, 75},
+ {1280, 960, 75},
+ {1280, 1024, 75}
+};
+
+/* this stuff should probably be shared by the various vmode-based */
+/* drivers in a vmode.h header. */
+
+#define VMODE_NVRAM 0 /* use value stored in nvram */
+#define VMODE_512_384_60I 1 /* 512x384, 60Hz interlaced (NTSC) */
+#define VMODE_512_384_60 2 /* 512x384, 60Hz */
+#define VMODE_640_480_50I 3 /* 640x480, 50Hz interlaced (PAL) */
+#define VMODE_640_480_60I 4 /* 640x480, 60Hz interlaced (NTSC) */
+#define VMODE_640_480_60 5 /* 640x480, 60Hz (VGA) */
+#define VMODE_640_480_67 6 /* 640x480, 67Hz */
+#define VMODE_640_870_75P 7 /* 640x870, 75Hz (portrait) */
+#define VMODE_768_576_50I 8 /* 768x576, 50Hz (PAL full frame) */
+#define VMODE_800_600_56 9 /* 800x600, 56Hz */
+#define VMODE_800_600_60 10 /* 800x600, 60Hz */
+#define VMODE_800_600_72 11 /* 800x600, 72Hz */
+#define VMODE_800_600_75 12 /* 800x600, 75Hz */
+#define VMODE_832_624_75 13 /* 832x624, 75Hz */
+#define VMODE_1024_768_60 14 /* 1024x768, 60Hz */
+#define VMODE_1024_768_70 15 /* 1024x768, 70Hz (or 72Hz?) */
+#define VMODE_1024_768_75V 16 /* 1024x768, 75Hz (VESA) */
+#define VMODE_1024_768_75 17 /* 1024x768, 75Hz */
+#define VMODE_1152_870_75 18 /* 1152x870, 75Hz */
+#define VMODE_1280_960_75 19 /* 1280x960, 75Hz */
+#define VMODE_1280_1024_75 20 /* 1280x1024, 75Hz */
+#define VMODE_MAX 20
+#define VMODE_CHOOSE 99 /* choose based on monitor sense */
+
+#define CMODE_NVRAM -1 /* use value stored in nvram */
+#define CMODE_8 0 /* 8 bits/pixel */
+#define CMODE_16 1 /* 16 (actually 15) bits/pixel */
+#define CMODE_32 2 /* 32 (actually 24) bits/pixel */
diff --git a/drivers/video/prom.uni b/drivers/video/prom.uni
new file mode 100644
index 000000000..58f9c04ed
--- /dev/null
+++ b/drivers/video/prom.uni
@@ -0,0 +1,11 @@
+#
+# Unicode mapping table for font in Sun PROM
+#
+#
+0x20-0x7e idem
+0xa0-0xff idem
+#
+0x7c U+2502
+0x2d U+2500
+0x2b U+250c U+2510 U+2514 U+2518 U+251c U+2524 U+252c U+2534 U+253c
+0xa4 U+fffd
diff --git a/drivers/video/promcon.c b/drivers/video/promcon.c
new file mode 100644
index 000000000..76f945b45
--- /dev/null
+++ b/drivers/video/promcon.c
@@ -0,0 +1,600 @@
+/* $Id: promcon.c,v 1.10 1998/07/24 15:31:53 jj Exp $
+ * Console driver utilizing PROM sun terminal emulation
+ *
+ * Copyright (C) 1998 Eddie C. Dost (ecd@skynet.be)
+ * Copyright (C) 1998 Jakub Jelinek (jj@ultra.linux.cz)
+ */
+
+#include <linux/module.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/delay.h>
+#include <linux/console.h>
+#include <linux/console_struct.h>
+#include <linux/vt_kern.h>
+#include <linux/selection.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/kd.h>
+
+#include <asm/oplib.h>
+#include <asm/uaccess.h>
+
+static short pw = 80 - 1, ph = 34 - 1;
+static short px, py;
+static unsigned long promcon_uni_pagedir[2];
+
+extern u8 promfont_unicount[];
+extern u16 promfont_unitable[];
+
+#define PROMCON_COLOR 0
+
+#if PROMCON_COLOR
+#define inverted(s) ((((s) & 0x7700) == 0x0700) ? 0 : 1)
+#else
+#define inverted(s) (((s) & 0x0800) ? 1 : 0)
+#endif
+
+static __inline__ void
+promcon_puts(char *buf, int cnt)
+{
+ prom_printf("%*.*s", cnt, cnt, buf);
+}
+
+static int
+promcon_start(struct vc_data *conp, char *b)
+{
+ unsigned short *s = (unsigned short *)
+ (conp->vc_origin + py * conp->vc_size_row + (px << 1));
+
+ if (px == pw) {
+ unsigned short *t = s - 1;
+
+ if (inverted(*s) && inverted(*t))
+ return sprintf(b, "\b\033[7m%c\b\033[@%c\033[m",
+ *s, *t);
+ else if (inverted(*s))
+ return sprintf(b, "\b\033[7m%c\033[m\b\033[@%c",
+ *s, *t);
+ else if (inverted(*t))
+ return sprintf(b, "\b%c\b\033[@\033[7m%c\033[m",
+ *s, *t);
+ else
+ return sprintf(b, "\b%c\b\033[@%c", *s, *t);
+ }
+
+ if (inverted(*s))
+ return sprintf(b, "\033[7m%c\033[m\b", *s);
+ else
+ return sprintf(b, "%c\b", *s);
+}
+
+static int
+promcon_end(struct vc_data *conp, char *b)
+{
+ unsigned short *s = (unsigned short *)
+ (conp->vc_origin + py * conp->vc_size_row + (px << 1));
+ char *p = b;
+
+ b += sprintf(b, "\033[%d;%dH", py + 1, px + 1);
+
+ if (px == pw) {
+ unsigned short *t = s - 1;
+
+ if (inverted(*s) && inverted(*t))
+ b += sprintf(b, "\b%c\b\033[@\033[7m%c\033[m", *s, *t);
+ else if (inverted(*s))
+ b += sprintf(b, "\b%c\b\033[@%c", *s, *t);
+ else if (inverted(*t))
+ b += sprintf(b, "\b\033[7m%c\b\033[@%c\033[m", *s, *t);
+ else
+ b += sprintf(b, "\b\033[7m%c\033[m\b\033[@%c", *s, *t);
+ return b - p;
+ }
+
+ if (inverted(*s))
+ b += sprintf(b, "%c\b", *s);
+ else
+ b += sprintf(b, "\033[7m%c\033[m\b", *s);
+ return b - p;
+}
+
+__initfunc(const char *promcon_startup(void))
+{
+ const char *display_desc = "PROM";
+ int node;
+ char buf[40];
+
+ node = prom_getchild(prom_root_node);
+ node = prom_searchsiblings(node, "options");
+ if (prom_getproperty(node, "screen-#columns", buf, 40) != -1) {
+ pw = simple_strtoul(buf, NULL, 0);
+ if (pw < 10 || pw > 256)
+ pw = 80;
+ pw--;
+ }
+ if (prom_getproperty(node, "screen-#rows", buf, 40) != -1) {
+ ph = simple_strtoul(buf, NULL, 0);
+ if (ph < 10 || ph > 256)
+ ph = 34;
+ ph--;
+ }
+ promcon_puts("\033[H\033[J", 6);
+ return display_desc;
+}
+
+__initfunc(static void
+promcon_init_unimap(struct vc_data *conp))
+{
+ mm_segment_t old_fs = get_fs();
+ struct unipair *p, *p1;
+ u16 *q;
+ int i, j, k;
+
+ p = kmalloc(256*sizeof(struct unipair), GFP_KERNEL);
+ if (!p) return;
+
+ q = promfont_unitable;
+ p1 = p;
+ k = 0;
+ for (i = 0; i < 256; i++)
+ for (j = promfont_unicount[i]; j; j--) {
+ p1->unicode = *q++;
+ p1->fontpos = i;
+ p1++;
+ k++;
+ }
+ set_fs(KERNEL_DS);
+ con_clear_unimap(conp->vc_num, NULL);
+ con_set_unimap(conp->vc_num, k, p);
+ con_protect_unimap(conp->vc_num, 1);
+ set_fs(old_fs);
+ kfree(p);
+}
+
+static void
+promcon_init(struct vc_data *conp, int init)
+{
+ unsigned long p;
+
+ conp->vc_can_do_color = PROMCON_COLOR;
+ if (init) {
+ conp->vc_cols = pw + 1;
+ conp->vc_rows = ph + 1;
+ }
+ p = *conp->vc_uni_pagedir_loc;
+ if (conp->vc_uni_pagedir_loc == &conp->vc_uni_pagedir ||
+ !--conp->vc_uni_pagedir_loc[1])
+ con_free_unimap(conp->vc_num);
+ conp->vc_uni_pagedir_loc = promcon_uni_pagedir;
+ promcon_uni_pagedir[1]++;
+ if (!promcon_uni_pagedir[0] && p) {
+ promcon_init_unimap(conp);
+ }
+ if (!init) {
+ if (conp->vc_cols != pw + 1 || conp->vc_rows != ph + 1)
+ vc_resize_con(ph + 1, pw + 1, conp->vc_num);
+ else if (conp->vc_num == fg_console)
+ update_screen(fg_console);
+ }
+}
+
+static void
+promcon_deinit(struct vc_data *conp)
+{
+ /* When closing the last console, reset video origin */
+ if (!--promcon_uni_pagedir[1])
+ con_free_unimap(conp->vc_num);
+ conp->vc_uni_pagedir_loc = &conp->vc_uni_pagedir;
+ con_set_default_unimap(conp->vc_num);
+}
+
+static int
+promcon_switch(struct vc_data *conp)
+{
+ return 1;
+}
+
+static unsigned short *
+promcon_repaint_line(unsigned short *s, unsigned char *buf, unsigned char **bp)
+{
+ int cnt = pw + 1;
+ int attr = -1;
+ unsigned char *b = *bp;
+
+ while (cnt--) {
+ if (attr != inverted(*s)) {
+ attr = inverted(*s);
+ if (attr) {
+ strcpy (b, "\033[7m");
+ b += 4;
+ } else {
+ strcpy (b, "\033[m");
+ b += 3;
+ }
+ }
+ *b++ = *s++;
+ if (b - buf >= 224) {
+ promcon_puts(buf, b - buf);
+ b = buf;
+ }
+ }
+ *bp = b;
+ return s;
+}
+
+static void
+promcon_putcs(struct vc_data *conp, const unsigned short *s,
+ int count, int y, int x)
+{
+ unsigned char buf[256], *b = buf;
+ unsigned short attr = *s;
+ unsigned char save;
+ int i, last = 0;
+
+ if (console_blanked)
+ return;
+
+ if (count <= 0)
+ return;
+
+ b += promcon_start(conp, b);
+
+ if (x + count >= pw + 1) {
+ if (count == 1) {
+ x -= 1;
+ save = *(unsigned short *)(conp->vc_origin
+ + y * conp->vc_size_row
+ + (x << 1));
+
+ if (px != x || py != y) {
+ b += sprintf(b, "\033[%d;%dH", y + 1, x + 1);
+ px = x;
+ py = y;
+ }
+
+ if (inverted(attr))
+ b += sprintf(b, "\033[7m%c\033[m", *s++);
+ else
+ b += sprintf(b, "%c", *s++);
+
+ strcpy(b, "\b\033[@");
+ b += 4;
+
+ if (inverted(save))
+ b += sprintf(b, "\033[7m%c\033[m", save);
+ else
+ b += sprintf(b, "%c", save);
+
+ px++;
+
+ b += promcon_end(conp, b);
+ promcon_puts(buf, b - buf);
+ return;
+ } else {
+ last = 1;
+ count = pw - x - 1;
+ }
+ }
+
+ if (inverted(attr)) {
+ strcpy(b, "\033[7m");
+ b += 4;
+ }
+
+ if (px != x || py != y) {
+ b += sprintf(b, "\033[%d;%dH", y + 1, x + 1);
+ px = x;
+ py = y;
+ }
+
+ for (i = 0; i < count; i++) {
+ if (b - buf >= 224) {
+ promcon_puts(buf, b - buf);
+ b = buf;
+ }
+ *b++ = *s++;
+ }
+
+ px += count;
+
+ if (last) {
+ save = *s++;
+ b += sprintf(b, "%c\b\033[@%c", *s++, save);
+ px++;
+ }
+
+ if (inverted(attr)) {
+ strcpy(b, "\033[m");
+ b += 3;
+ }
+
+ b += promcon_end(conp, b);
+ promcon_puts(buf, b - buf);
+}
+
+static void
+promcon_putc(struct vc_data *conp, int c, int y, int x)
+{
+ unsigned short s = c;
+
+ if (console_blanked)
+ return;
+
+ promcon_putcs(conp, &s, 1, y, x);
+}
+
+static void
+promcon_clear(struct vc_data *conp, int sy, int sx, int height, int width)
+{
+ unsigned char buf[256], *b = buf;
+ int i, j;
+
+ if (console_blanked)
+ return;
+
+ b += promcon_start(conp, b);
+
+ if (!sx && width == pw + 1) {
+
+ if (!sy && height == ph + 1) {
+ strcpy(b, "\033[H\033[J");
+ b += 6;
+ b += promcon_end(conp, b);
+ promcon_puts(buf, b - buf);
+ return;
+ } else if (sy + height == ph + 1) {
+ b += sprintf(b, "\033[%dH\033[J", sy + 1);
+ b += promcon_end(conp, b);
+ promcon_puts(buf, b - buf);
+ return;
+ }
+
+ b += sprintf(b, "\033[%dH", sy + 1);
+ for (i = 1; i < height; i++) {
+ strcpy(b, "\033[K\n");
+ b += 4;
+ }
+
+ strcpy(b, "\033[K");
+ b += 3;
+
+ b += promcon_end(conp, b);
+ promcon_puts(buf, b - buf);
+ return;
+
+ } else if (sx + width == pw + 1) {
+
+ b += sprintf(b, "\033[%d;%dH", sy + 1, sx + 1);
+ for (i = 1; i < height; i++) {
+ strcpy(b, "\033[K\n");
+ b += 4;
+ }
+
+ strcpy(b, "\033[K");
+ b += 3;
+
+ b += promcon_end(conp, b);
+ promcon_puts(buf, b - buf);
+ return;
+ }
+
+ for (i = sy + 1; i <= sy + height; i++) {
+ b += sprintf(b, "\033[%d;%dH", i, sx + 1);
+ for (j = 0; j < width; j++)
+ *b++ = ' ';
+ if (b - buf + width >= 224) {
+ promcon_puts(buf, b - buf);
+ b = buf;
+ }
+ }
+
+ b += promcon_end(conp, b);
+ promcon_puts(buf, b - buf);
+}
+
+static void
+promcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
+ int height, int width)
+{
+ char buf[256], *b = buf;
+
+ if (console_blanked)
+ return;
+
+ b += promcon_start(conp, b);
+ if (sy == dy && height == 1) {
+ if (dx > sx && dx + width == conp->vc_cols)
+ b += sprintf(b, "\033[%d;%dH\033[%d@\033[%d;%dH",
+ sy + 1, sx + 1, dx - sx, py + 1, px + 1);
+ else if (dx < sx && sx + width == conp->vc_cols)
+ b += sprintf(b, "\033[%d;%dH\033[%dP\033[%d;%dH",
+ dy + 1, dx + 1, sx - dx, py + 1, px + 1);
+
+ b += promcon_end(conp, b);
+ promcon_puts(buf, b - buf);
+ return;
+ }
+
+ /*
+ * FIXME: What to do here???
+ * Current console.c should not call it like that ever.
+ */
+ prom_printf("\033[7mFIXME: bmove not handled\033[m\n");
+}
+
+static void
+promcon_cursor(struct vc_data *conp, int mode)
+{
+ char buf[32], *b = buf;
+
+ switch (mode) {
+ case CM_ERASE:
+ break;
+
+ case CM_MOVE:
+ case CM_DRAW:
+ b += promcon_start(conp, b);
+ if (px != conp->vc_x || py != conp->vc_y) {
+ px = conp->vc_x;
+ py = conp->vc_y;
+ b += sprintf(b, "\033[%d;%dH", py + 1, px + 1);
+ }
+ promcon_puts(buf, b - buf);
+ break;
+ }
+}
+
+static int
+promcon_font_op(struct vc_data *conp, struct console_font_op *op)
+{
+ return -ENOSYS;
+}
+
+static int
+promcon_blank(struct vc_data *conp, int blank)
+{
+ if (blank) {
+ promcon_puts("\033[H\033[J\033[7m \033[m\b", 15);
+ return 0;
+ } else {
+ /* Let console.c redraw */
+ return 1;
+ }
+}
+
+static int
+promcon_scroll(struct vc_data *conp, int t, int b, int dir, int count)
+{
+ unsigned char buf[256], *p = buf;
+ unsigned short *s;
+ int i;
+
+ if (console_blanked)
+ return 0;
+
+ p += promcon_start(conp, p);
+
+ switch (dir) {
+ case SM_UP:
+ if (b == ph + 1) {
+ p += sprintf(p, "\033[%dH\033[%dM", t + 1, count);
+ px = 0;
+ py = t;
+ p += promcon_end(conp, p);
+ promcon_puts(buf, p - buf);
+ break;
+ }
+
+ s = (unsigned short *)(conp->vc_origin
+ + (t + count) * conp->vc_size_row);
+
+ p += sprintf(p, "\033[%dH", t + 1);
+
+ for (i = t; i < b - count; i++)
+ s = promcon_repaint_line(s, buf, &p);
+
+ for (; i < b - 1; i++) {
+ strcpy(p, "\033[K\n");
+ p += 4;
+ if (p - buf >= 224) {
+ promcon_puts(buf, p - buf);
+ p = buf;
+ }
+ }
+
+ strcpy(p, "\033[K");
+ p += 3;
+
+ p += promcon_end(conp, p);
+ promcon_puts(buf, p - buf);
+ break;
+
+ case SM_DOWN:
+ if (b == ph + 1) {
+ p += sprintf(p, "\033[%dH\033[%dL", t + 1, count);
+ px = 0;
+ py = t;
+ p += promcon_end(conp, p);
+ promcon_puts(buf, p - buf);
+ break;
+ }
+
+ s = (unsigned short *)(conp->vc_origin + t * conp->vc_size_row);
+
+ p += sprintf(p, "\033[%dH", t + 1);
+
+ for (i = t; i < t + count; i++) {
+ strcpy(p, "\033[K\n");
+ p += 4;
+ if (p - buf >= 224) {
+ promcon_puts(buf, p - buf);
+ p = buf;
+ }
+ }
+
+ for (; i < b; i++)
+ s = promcon_repaint_line(s, buf, &p);
+
+ p += promcon_end(conp, p);
+ promcon_puts(buf, p - buf);
+ break;
+ }
+
+ return 0;
+}
+
+#if !(PROMCON_COLOR)
+static u8 promcon_build_attr(struct vc_data *conp, u8 _color, u8 _intensity, u8 _blink, u8 _underline, u8 _reverse)
+{
+ return (_reverse) ? 0xf : 0x7;
+}
+#endif
+
+/*
+ * The console 'switch' structure for the VGA based console
+ */
+
+static int promcon_dummy(void)
+{
+ return 0;
+}
+
+#define DUMMY (void *) promcon_dummy
+
+struct consw prom_con = {
+ con_startup: promcon_startup,
+ con_init: promcon_init,
+ con_deinit: promcon_deinit,
+ con_clear: promcon_clear,
+ con_putc: promcon_putc,
+ con_putcs: promcon_putcs,
+ con_cursor: promcon_cursor,
+ con_scroll: promcon_scroll,
+ con_bmove: promcon_bmove,
+ con_switch: promcon_switch,
+ con_blank: promcon_blank,
+ con_font_op: promcon_font_op,
+ con_set_palette: DUMMY,
+ con_scrolldelta: DUMMY,
+ con_set_origin: NULL,
+ con_save_screen: NULL,
+#if PROMCON_COLOR
+ con_build_attr: NULL,
+#else
+ con_build_attr: promcon_build_attr,
+#endif
+ con_invert_region: NULL,
+};
+
+__initfunc(void prom_con_init(void))
+{
+ if (conswitchp == &dummy_con)
+ take_over_console(&prom_con, 0, MAX_NR_CONSOLES-1, 1);
+ else if (conswitchp == &prom_con)
+ promcon_init_unimap(vc_cons[fg_console].d);
+}
diff --git a/drivers/video/retz3fb.c b/drivers/video/retz3fb.c
index 82dcc2877..548f88602 100644
--- a/drivers/video/retz3fb.c
+++ b/drivers/video/retz3fb.c
@@ -20,8 +20,6 @@
* for more details.
*/
-
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -81,6 +79,8 @@ struct retz3fb_par {
int hsync_len; /* length of horizontal sync */
int vsync_len; /* length of vertical sync */
int vmode;
+
+ int accel;
};
struct display_data {
@@ -196,7 +196,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},
- 0, 0, -1, -1, FB_ACCEL_NCR77C32BLT, 38461, 28, 32, 12, 10, 96, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, 38461, 28, 32, 12, 10, 96, 2,
FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
},
@@ -208,7 +208,7 @@ static struct fb_videomode retz3fb_predefined[] __initdata = {
"800x600", { /* 800x600, 8 bpp */
800, 600, 800, 600, 0, 0, 8, 0,
{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCEL_NCR77C32BLT, 27778, 64, 24, 22, 1, 120, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, 27778, 64, 24, 22, 1, 120, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
},
@@ -220,21 +220,21 @@ static struct fb_videomode retz3fb_predefined[] __initdata = {
"1024x768i", { /* 1024x768, 8 bpp, interlaced */
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_NCR77C32BLT, 22222, 40, 40, 32, 9, 160, 8,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, 22222, 40, 40, 32, 9, 160, 8,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_INTERLACED
}
}, {
"640x480-16", { /* 640x480, 16 bpp */
640, 480, 640, 480, 0, 0, 16, 0,
{11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCEL_NCR77C32BLT, 38461/2, 28, 32, 12, 10, 96, 2,
+ 0, 0, -1, -1, 0, 38461/2, 28, 32, 12, 10, 96, 2,
FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}, {
"640x480-24", { /* 640x480, 24 bpp */
640, 480, 640, 480, 0, 0, 24, 0,
{8, 8, 8}, {8, 8, 8}, {8, 8, 8}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCEL_NCR77C32BLT, 38461/3, 28, 32, 12, 10, 96, 2,
+ 0, 0, -1, -1, 0, 38461/3, 28, 32, 12, 10, 96, 2,
FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
},
@@ -255,8 +255,8 @@ static int z3fb_mode __initdata = 0;
void retz3fb_setup(char *options, int *ints);
-static int retz3fb_open(struct fb_info *info);
-static int retz3fb_release(struct fb_info *info);
+static int retz3fb_open(struct fb_info *info, int user);
+static int retz3fb_release(struct fb_info *info, int user);
static int retz3fb_get_fix(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info);
static int retz3fb_get_var(struct fb_var_screeninfo *var, int con,
@@ -278,7 +278,7 @@ static int retz3fb_ioctl(struct inode *inode, struct file *file,
* Interface to the low level console driver
*/
-unsigned long retz3fb_init(unsigned long mem_start);
+void 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);
@@ -288,7 +288,7 @@ static void z3fb_blank(int blank, struct fb_info *info);
* Text console acceleration
*/
-#ifdef CONFIG_FBCON_CFB8
+#ifdef FBCON_HAS_CFB8
static struct display_switch fbcon_retz3_8;
#endif
@@ -834,12 +834,11 @@ static int retz3_init(void)
static int retz3_encode_fix(struct fb_fix_screeninfo *fix,
struct retz3fb_par *par)
{
- short i;
-
+ memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id, retz3fb_name);
fix->smem_start = (char *)z3_fbmem;
fix->smem_len = z3_size;
- fix->mmio_start = (unsigned char *)z3_regs;
+ fix->mmio_start = (char *)z3_regs;
fix->mmio_len = 0x00c00000;
fix->type = FB_TYPE_PACKED_PIXELS;
@@ -854,10 +853,7 @@ static int retz3_encode_fix(struct fb_fix_screeninfo *fix,
fix->ywrapstep = 0;
fix->line_length = 0;
- fix->accel = FB_ACCEL_NCR77C32BLT;
-
- for (i = 0; i < arraysize(fix->reserved); i++)
- fix->reserved[i] = 0;
+ fix->accel = FB_ACCEL_NCR_77C32BLT;
return 0;
}
@@ -891,6 +887,11 @@ static int retz3_decode_var(struct fb_var_screeninfo *var,
par->hsync_len = var->hsync_len;
par->vsync_len = var->vsync_len;
+ if (var->accel_flags & FB_ACCELF_TEXT)
+ par->accel = FB_ACCELF_TEXT;
+ else
+ par->accel = 0;
+
return 0;
}
@@ -903,8 +904,7 @@ static int retz3_decode_var(struct fb_var_screeninfo *var,
static int retz3_encode_var(struct fb_var_screeninfo *var,
struct retz3fb_par *par)
{
- short i;
-
+ memset(var, 0, sizeof(struct fb_var_screeninfo));
var->xres = par->xres;
var->yres = par->yres;
var->xres_virtual = par->xres_vir;
@@ -926,7 +926,7 @@ static int retz3_encode_var(struct fb_var_screeninfo *var,
var->height = -1;
var->width = -1;
- var->accel = FB_ACCEL_NCR77C32BLT;
+ var->accel_flags = (par->accel && par->bpp == 8) ? FB_ACCELF_TEXT : 0;
var->pixclock = par->pixclock;
@@ -938,9 +938,6 @@ static int retz3_encode_var(struct fb_var_screeninfo *var,
var->hsync_len = par->hsync_len;
var->vsync_len = par->vsync_len;
- for (i = 0; i < arraysize(var->reserved); i++)
- var->reserved[i] = 0;
-
var->vmode = par->vmode;
return 0;
}
@@ -1202,7 +1199,7 @@ static void do_install_cmap(int con, struct fb_info *info)
* Open/Release the frame buffer device
*/
-static int retz3fb_open(struct fb_info *info)
+static int retz3fb_open(struct fb_info *info, int user)
{
/*
* Nothing, only a usage count for the moment
@@ -1212,7 +1209,7 @@ static int retz3fb_open(struct fb_info *info)
return 0;
}
-static int retz3fb_release(struct fb_info *info)
+static int retz3fb_release(struct fb_info *info, int user)
{
MOD_DEC_USE_COUNT;
return 0;
@@ -1272,7 +1269,7 @@ static void retz3fb_set_disp(int con, struct fb_info *info)
if (con == -1)
con = 0;
- display->screen_base = (unsigned char *)fix.smem_start;
+ display->screen_base = fix.smem_start;
display->visual = fix.visual;
display->type = fix.type;
display->type_aux = fix.type_aux;
@@ -1281,12 +1278,16 @@ static void retz3fb_set_disp(int con, struct fb_info *info)
display->can_soft_blank = 1;
display->inverse = z3fb_inverse;
switch (display->var.bits_per_pixel) {
-#ifdef CONFIG_FBCON_CFB8
+#ifdef FBCON_HAS_CFB8
case 8:
- display->dispsw = &fbcon_retz3_8;
+ if (display->var.accel_flags & FB_ACCELF_TEXT) {
+ display->dispsw = &fbcon_retz3_8;
+#warning FIXME: We should reinit the graphics engine here
+ } else
+ display->dispsw = &fbcon_cfb8;
break;
#endif
-#ifdef CONFIG_FBCON_CFB16
+#ifdef FBCON_HAS_CFB16
case 16:
display->dispsw = &fbcon_cfb16;
break;
@@ -1305,7 +1306,7 @@ static void retz3fb_set_disp(int con, struct fb_info *info)
static int retz3fb_set_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
- int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp;
+ int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel;
struct display *display;
if (con >= 0)
@@ -1326,12 +1327,14 @@ static int retz3fb_set_var(struct fb_var_screeninfo *var, int con,
oldvxres = display->var.xres_virtual;
oldvyres = display->var.yres_virtual;
oldbpp = display->var.bits_per_pixel;
+ oldaccel = display->var.accel_flags;
display->var = *var;
if (oldxres != var->xres || oldyres != var->yres ||
oldvxres != var->xres_virtual ||
oldvyres != var->yres_virtual ||
- oldbpp != var->bits_per_pixel) {
+ oldbpp != var->bits_per_pixel ||
+ oldaccel != var->accel_flags) {
struct fb_fix_screeninfo fix;
retz3fb_get_fix(&fix, con, info);
@@ -1346,12 +1349,16 @@ static int retz3fb_set_var(struct fb_var_screeninfo *var, int con,
display->can_soft_blank = 1;
display->inverse = z3fb_inverse;
switch (display->var.bits_per_pixel) {
-#ifdef CONFIG_FBCON_CFB8
+#ifdef FBCON_HAS_CFB8
case 8:
- display->dispsw = &fbcon_retz3_8;
+ if (var->accel_flags & FB_ACCELF_TEXT) {
+ display->dispsw = &fbcon_retz3_8;
+#warning FIXME: We should reinit the graphics engine here
+ } else
+ display->dispsw = &fbcon_cfb8;
break;
#endif
-#ifdef CONFIG_FBCON_CFB16
+#ifdef FBCON_HAS_CFB16
case 16:
display->dispsw = &fbcon_cfb16;
break;
@@ -1448,7 +1455,7 @@ static int retz3fb_ioctl(struct inode *inode, struct file *file,
static struct fb_ops retz3fb_ops = {
retz3fb_open, retz3fb_release, retz3fb_get_fix, retz3fb_get_var,
retz3fb_set_var, retz3fb_get_cmap, retz3fb_set_cmap,
- retz3fb_pan_display, NULL, retz3fb_ioctl
+ retz3fb_pan_display, retz3fb_ioctl
};
@@ -1478,9 +1485,8 @@ __initfunc(void retz3fb_setup(char *options, int *ints))
* Initialization
*/
-__initfunc(unsigned long retz3fb_init(unsigned long mem_start))
+__initfunc(void retz3fb_init(void))
{
- int err;
unsigned long board_addr, board_size;
unsigned int key;
const struct ConfigDev *cd;
@@ -1488,7 +1494,7 @@ __initfunc(unsigned long retz3fb_init(unsigned long mem_start))
struct retz3fb_par par;
if (!(key = zorro_find(ZORRO_PROD_MACROSYSTEMS_RETINA_Z3, 0, 0)))
- return mem_start;
+ return;
cd = zorro_get_board (key);
zorro_config_board (key, 0);
@@ -1496,7 +1502,7 @@ __initfunc(unsigned long retz3fb_init(unsigned long mem_start))
board_size = (unsigned long)cd->cd_BoardSize;
z3_mem = kernel_map (board_addr, board_size,
- KERNELMAP_NOCACHE_SER, &mem_start);
+ KERNELMAP_NOCACHE_SER, NULL);
z3_regs = (char*) z3_mem;
z3_fbmem = z3_mem + VIDEO_MEM_OFFSET;
@@ -1518,10 +1524,6 @@ __initfunc(unsigned long retz3fb_init(unsigned long mem_start))
fb_info.updatevar = &z3fb_updatevar;
fb_info.blank = &z3fb_blank;
- err = register_framebuffer(&fb_info);
- if (err < 0)
- return mem_start;
-
if (z3fb_mode == -1)
retz3fb_default = retz3fb_predefined[0].var;
@@ -1535,13 +1537,14 @@ __initfunc(unsigned long retz3fb_init(unsigned long mem_start))
do_install_cmap(0, &fb_info);
+ if (register_framebuffer(&fb_info) < 0)
+ return;
+
printk("fb%d: %s frame buffer device, using %ldK of video memory\n",
GET_FB_IDX(fb_info.node), fb_info.modename, z3_size>>10);
/* TODO: This driver cannot be unloaded yet */
MOD_INC_USE_COUNT;
-
- return mem_start;
}
@@ -1604,7 +1607,8 @@ __initfunc(static int get_video_mode(const char *name))
#ifdef MODULE
int init_module(void)
{
- return(retz3fb_init(NULL));
+ retz3fb_init();
+ return 0;
}
void cleanup_module(void)
@@ -1623,7 +1627,7 @@ void cleanup_module(void)
* Text console acceleration
*/
-#ifdef CONFIG_FBCON_CFB8
+#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)
{
@@ -1670,6 +1674,7 @@ static void fbcon_retz3_8_clear(struct vc_data *conp, struct display *p, int
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
+ fbcon_cfb8_putc, fbcon_cfb8_putcs, fbcon_cfb8_revc, NULL, NULL,
+ fbcon_cfb8_clear_margins, FONTWIDTH(8)
};
#endif
diff --git a/drivers/video/sbusfb.c b/drivers/video/sbusfb.c
new file mode 100644
index 000000000..a771c37bd
--- /dev/null
+++ b/drivers/video/sbusfb.c
@@ -0,0 +1,1128 @@
+/*
+ * linux/drivers/video/sbusfb.c -- SBUS or UPA based frame buffer device
+ *
+ * Copyright (C) 1998 Jakub Jelinek
+ *
+ * This driver is partly based on the Open Firmware console driver
+ *
+ * Copyright (C) 1997 Geert Uytterhoeven
+ *
+ * and SPARC console subsystem
+ *
+ * Copyright (C) 1995 Peter Zaitcev (zaitcev@lab.ipmce.su)
+ * Copyright (C) 1995-1997 David S. Miller (davem@caip.rutgers.edu)
+ * Copyright (C) 1995-1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
+ * Copyright (C) 1996 Dave Redman (djhr@tadpole.co.uk)
+ * Copyright (C) 1996-1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
+ * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
+ *
+ * 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/config.h>
+#include <linux/module.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/selection.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/kd.h>
+#include <linux/vt_kern.h>
+
+#include <asm/uaccess.h>
+
+#include "sbusfb.h"
+
+ /*
+ * Interface used by the world
+ */
+
+void sbusfb_init(void);
+void sbusfb_setup(char *options, int *ints);
+
+static int currcon;
+static int defx_margin = -1, defy_margin = -1;
+static char fontname[40] __initdata = { 0 };
+static struct {
+ int depth;
+ int xres, yres;
+ int x_margin, y_margin;
+} def_margins [] = {
+ { 8, 1280, 1024, 64, 80 },
+ { 8, 1152, 1024, 64, 80 },
+ { 8, 1152, 900, 64, 18 },
+ { 8, 1024, 768, 0, 0 },
+ { 8, 800, 600, 16, 12 },
+ { 8, 640, 480, 0, 0 },
+ { 1, 1152, 900, 8, 18 },
+ { 0 },
+};
+
+static int sbusfb_open(struct fb_info *info, int user);
+static int sbusfb_release(struct fb_info *info, int user);
+static int sbusfb_mmap(struct fb_info *info, struct file *file,
+ struct vm_area_struct *vma);
+static int sbusfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info);
+static int sbusfb_get_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int sbusfb_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int sbusfb_pan_display(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int sbusfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+static int sbusfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+static int sbusfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg, int con, struct fb_info *info);
+static void sbusfb_cursor(struct display *p, int mode, int x, int y);
+static void sbusfb_clear_margin(struct display *p, int s);
+extern int io_remap_page_range(unsigned long from, unsigned long offset,
+ unsigned long size, pgprot_t prot, int space);
+
+
+ /*
+ * Interface to the low level console driver
+ */
+
+static int sbusfbcon_switch(int con, struct fb_info *info);
+static int sbusfbcon_updatevar(int con, struct fb_info *info);
+static void sbusfbcon_blank(int blank, struct fb_info *info);
+
+
+ /*
+ * Internal routines
+ */
+
+static int sbusfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+ u_int *transp, struct fb_info *info);
+static int sbusfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info);
+static void do_install_cmap(int con, struct fb_info *info);
+
+static struct fb_ops sbusfb_ops = {
+ sbusfb_open, sbusfb_release, sbusfb_get_fix, sbusfb_get_var, sbusfb_set_var,
+ sbusfb_get_cmap, sbusfb_set_cmap, sbusfb_pan_display, sbusfb_ioctl, sbusfb_mmap
+};
+
+
+ /*
+ * Open/Release the frame buffer device
+ */
+
+static int sbusfb_open(struct fb_info *info, int user)
+{
+ struct fb_info_sbusfb *fb = sbusfbinfo(info);
+
+ if (user) {
+ if (fb->open) return -EBUSY;
+ fb->mmaped = 0;
+ fb->open = 1;
+ fb->vtconsole = -1;
+ } else
+ fb->consolecnt++;
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static int sbusfb_release(struct fb_info *info, int user)
+{
+ struct fb_info_sbusfb *fb = sbusfbinfo(info);
+
+ if (user) {
+ if (fb->vtconsole != -1) {
+ vt_cons[fb->vtconsole]->vc_mode = KD_TEXT;
+ if (fb->mmaped)
+ sbusfb_clear_margin(&fb_display[fb->vtconsole], 0);
+ }
+ if (fb->reset)
+ fb->reset(fb);
+ fb->open = 0;
+ } else
+ fb->consolecnt--;
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+static unsigned long sbusfb_mmapsize(struct fb_info_sbusfb *fb, long size)
+{
+ if (size == SBUS_MMAP_EMPTY) return 0;
+ if (size >= 0) return size;
+ return fb->type.fb_size * (-size);
+}
+
+static int sbusfb_mmap(struct fb_info *info, struct file *file,
+ struct vm_area_struct *vma)
+{
+ struct fb_info_sbusfb *fb = sbusfbinfo(info);
+ unsigned int size, page, r, map_size;
+ unsigned long map_offset = 0;
+ int i;
+
+ size = vma->vm_end - vma->vm_start;
+ if (vma->vm_offset & ~PAGE_MASK)
+ return -ENXIO;
+
+ /* To stop the swapper from even considering these pages */
+ vma->vm_flags |= (VM_SHM| VM_LOCKED);
+
+#ifdef __sparc_v9__
+ /* Align it as much as desirable */
+ {
+ int j, max = -1, alignment, s = 0;
+
+ map_offset = vma->vm_offset+size;
+ for (i = 0; fb->mmap_map[i].size; i++) {
+ if (fb->mmap_map[i].voff < vma->vm_offset)
+ continue;
+ if (fb->mmap_map[i].voff >= map_offset)
+ break;
+ if (max < 0 || sbusfb_mmapsize(fb,fb->mmap_map[i].size) > s) {
+ max = i;
+ s = sbusfb_mmapsize(fb,fb->mmap_map[max].size);
+ }
+ }
+ if (max >= 0) {
+ j = s;
+ if (fb->mmap_map[max].voff + j > map_offset)
+ j = map_offset - fb->mmap_map[max].voff;
+ for (alignment = 0x400000; alignment > PAGE_SIZE; alignment >>= 3)
+ if (j >= alignment && !(fb->mmap_map[max].poff & (alignment - 1)))
+ break;
+ if (alignment > PAGE_SIZE) {
+ j = alignment;
+ alignment = j - ((vma->vm_start + fb->mmap_map[max].voff - vma->vm_offset) & (j - 1));
+ if (alignment != j) {
+ struct vm_area_struct *vmm = find_vma(current->mm, vma->vm_start);
+ if (!vmm || vmm->vm_start >= vma->vm_end + alignment) {
+ vma->vm_start += alignment;
+ vma->vm_end += alignment;
+ }
+ }
+ }
+ }
+ }
+#endif
+
+ /* Each page, see which map applies */
+ for (page = 0; page < size; ){
+ map_size = 0;
+ for (i = 0; fb->mmap_map[i].size; i++)
+ if (fb->mmap_map[i].voff == vma->vm_offset+page) {
+ map_size = sbusfb_mmapsize(fb,fb->mmap_map[i].size);
+ map_offset = (fb->physbase + fb->mmap_map[i].poff) & PAGE_MASK;
+ break;
+ }
+ if (!map_size){
+ page += PAGE_SIZE;
+ continue;
+ }
+ if (page + map_size > size)
+ map_size = size - page;
+ r = io_remap_page_range (vma->vm_start+page, map_offset, map_size, vma->vm_page_prot, fb->iospace);
+ if (r)
+ return -EAGAIN;
+ page += map_size;
+ }
+
+ vma->vm_file = file;
+ file->f_count++;
+ vma->vm_flags |= VM_IO;
+ if (!fb->mmaped) {
+ int lastconsole = 0;
+
+ if (info->display_fg)
+ lastconsole = info->display_fg->vc_num;
+ fb->mmaped = 1;
+ if (fb->consolecnt && fb_display[lastconsole].fb_info == info) {
+ fb->vtconsole = lastconsole;
+ vt_cons [lastconsole]->vc_mode = KD_GRAPHICS;
+ } else if (fb->unblank && !fb->blanked)
+ (*fb->unblank)(fb);
+ }
+ return 0;
+}
+
+static void sbusfb_clear_margin(struct display *p, int s)
+{
+ struct fb_info_sbusfb *fb = sbusfbinfod(p);
+
+ if (fb->fill) {
+ unsigned short rects [16];
+
+ rects [0] = 0;
+ rects [1] = 0;
+ rects [2] = fb->var.xres_virtual;
+ rects [3] = fb->y_margin;
+ rects [4] = 0;
+ rects [5] = fb->y_margin;
+ rects [6] = fb->x_margin;
+ rects [7] = fb->var.yres_virtual;
+ rects [8] = fb->var.xres_virtual - fb->x_margin;
+ rects [9] = fb->y_margin;
+ rects [10] = fb->var.xres_virtual;
+ rects [11] = fb->var.yres_virtual;
+ rects [12] = fb->x_margin;
+ rects [13] = fb->var.yres_virtual - fb->y_margin;
+ rects [14] = fb->var.xres_virtual - fb->x_margin;
+ rects [15] = fb->var.yres_virtual;
+ (*fb->fill)(fb, p, s, 4, rects);
+ } else {
+ unsigned char *fb_base = p->screen_base, *q;
+ int skip_bytes = fb->y_margin * fb->var.xres_virtual;
+ int scr_size = fb->var.xres_virtual * fb->var.yres_virtual;
+ int h, he, incr, size;
+
+ he = fb->var.yres;
+ if (fb->var.bits_per_pixel == 1) {
+ fb_base -= (skip_bytes + fb->x_margin) / 8;
+ skip_bytes /= 8;
+ scr_size /= 8;
+ memset (fb_base, ~0, skip_bytes - fb->x_margin / 8);
+ memset (fb_base + scr_size - skip_bytes + fb->x_margin / 8, ~0, skip_bytes - fb->x_margin / 8);
+ incr = fb->var.xres_virtual / 8;
+ size = fb->x_margin / 8 * 2;
+ for (q = fb_base + skip_bytes - fb->x_margin / 8, h = 0;
+ h <= he; q += incr, h++)
+ memset (q, ~0, size);
+ } else {
+ fb_base -= (skip_bytes + fb->x_margin);
+ memset (fb_base, attr_bgcol(p,s), skip_bytes - fb->x_margin);
+ memset (fb_base + scr_size - skip_bytes + fb->x_margin, attr_bgcol(p,s), skip_bytes - fb->x_margin);
+ incr = fb->var.xres_virtual;
+ size = fb->x_margin * 2;
+ for (q = fb_base + skip_bytes - fb->x_margin, h = 0;
+ h <= he; q += incr, h++)
+ memset (q, attr_bgcol(p,s), size);
+ }
+ }
+ if (fb->switch_from_graph)
+ (*fb->switch_from_graph)(fb);
+}
+
+static void sbusfb_disp_setup(struct display *p)
+{
+ struct fb_info_sbusfb *fb = sbusfbinfod(p);
+
+ if (fb->setup)
+ fb->setup(p);
+ sbusfb_clear_margin(p, 0);
+}
+
+ /*
+ * Get the Fixed Part of the Display
+ */
+
+static int sbusfb_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info)
+{
+ struct fb_info_sbusfb *fb = sbusfbinfo(info);
+
+ memcpy(fix, &fb->fix, sizeof(struct fb_fix_screeninfo));
+ return 0;
+}
+
+ /*
+ * Get the User Defined Part of the Display
+ */
+
+static int sbusfb_get_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ struct fb_info_sbusfb *fb = sbusfbinfo(info);
+
+ memcpy(var, &fb->var, sizeof(struct fb_var_screeninfo));
+ return 0;
+}
+
+ /*
+ * Set the User Defined Part of the Display
+ */
+
+static int sbusfb_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ return -EINVAL;
+}
+
+ /*
+ * Pan or Wrap the Display
+ *
+ * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+ */
+
+static int sbusfb_pan_display(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ if (var->xoffset || var->yoffset)
+ return -EINVAL;
+ else
+ return 0;
+}
+
+ /*
+ * Hardware cursor
+ */
+
+static int sbus_hw_scursor (struct fbcursor *cursor, struct fb_info_sbusfb *fb)
+{
+ int op;
+ int i, bytes = 0;
+ struct fbcursor f;
+ char red[2], green[2], blue[2];
+
+ if (copy_from_user (&f, cursor, sizeof(struct fbcursor)))
+ return -EFAULT;
+ op = f.set;
+ if (op & FB_CUR_SETSHAPE){
+ if ((u32) f.size.fbx > fb->cursor.hwsize.fbx)
+ return -EINVAL;
+ if ((u32) f.size.fby > fb->cursor.hwsize.fby)
+ return -EINVAL;
+ if (f.size.fbx > 32)
+ bytes = f.size.fby << 3;
+ else
+ bytes = f.size.fby << 2;
+ }
+ if (op & FB_CUR_SETCMAP){
+ if (f.cmap.index || f.cmap.count != 2)
+ return -EINVAL;
+ if (copy_from_user (red, f.cmap.red, 2) ||
+ copy_from_user (green, f.cmap.green, 2) ||
+ copy_from_user (blue, f.cmap.blue, 2))
+ return -EFAULT;
+ }
+ if (op & FB_CUR_SETCMAP)
+ (*fb->setcursormap) (fb, red, green, blue);
+ if (op & FB_CUR_SETSHAPE){
+ u32 u;
+
+ fb->cursor.size = f.size;
+ memset ((void *)&fb->cursor.bits, 0, sizeof (fb->cursor.bits));
+ if (copy_from_user (fb->cursor.bits [0], f.mask, bytes) ||
+ copy_from_user (fb->cursor.bits [1], f.image, bytes))
+ return -EFAULT;
+ if (f.size.fbx <= 32) {
+ u = ~(0xffffffff >> f.size.fbx);
+ for (i = fb->cursor.size.fby - 1; i >= 0; i--) {
+ fb->cursor.bits [0][i] &= u;
+ fb->cursor.bits [1][i] &= fb->cursor.bits [0][i];
+ }
+ } else {
+ u = ~(0xffffffff >> (f.size.fbx - 32));
+ for (i = fb->cursor.size.fby - 1; i >= 0; i--) {
+ fb->cursor.bits [0][2*i+1] &= u;
+ fb->cursor.bits [1][2*i] &= fb->cursor.bits [0][2*i];
+ fb->cursor.bits [1][2*i+1] &= fb->cursor.bits [0][2*i+1];
+ }
+ }
+ (*fb->setcurshape) (fb);
+ }
+ if (op & (FB_CUR_SETCUR | FB_CUR_SETPOS | FB_CUR_SETHOT)){
+ if (op & FB_CUR_SETCUR)
+ fb->cursor.enable = f.enable;
+ if (op & FB_CUR_SETPOS)
+ fb->cursor.cpos = f.pos;
+ if (op & FB_CUR_SETHOT)
+ fb->cursor.chot = f.hot;
+ (*fb->setcursor) (fb);
+ }
+ return 0;
+}
+
+static unsigned char hw_cursor_cmap[2] = { 0, 0xff };
+
+static void sbusfb_cursor(struct display *p, int mode, int x, int y)
+{
+ struct fb_info_sbusfb *fb = sbusfbinfod(p);
+
+ switch (mode) {
+ case CM_ERASE:
+ fb->cursor.enable = 0;
+ (*fb->setcursor)(fb);
+ fb->hw_cursor_shown = 0;
+ break;
+
+ case CM_MOVE:
+ case CM_DRAW:
+ if (!fb->hw_cursor_shown) {
+ fb->cursor.size.fbx = p->fontwidth;
+ fb->cursor.size.fby = p->fontheight;
+ fb->cursor.chot.fbx = 0;
+ fb->cursor.chot.fby = 0;
+ fb->cursor.enable = 1;
+ memset (fb->cursor.bits, 0, sizeof (fb->cursor.bits));
+ fb->cursor.bits[0][p->fontheight - 2] = (0xffffffff << (32 - p->fontwidth));
+ fb->cursor.bits[1][p->fontheight - 2] = (0xffffffff << (32 - p->fontwidth));
+ fb->cursor.bits[0][p->fontheight - 1] = (0xffffffff << (32 - p->fontwidth));
+ fb->cursor.bits[1][p->fontheight - 1] = (0xffffffff << (32 - p->fontwidth));
+ (*fb->setcursormap) (fb, hw_cursor_cmap, hw_cursor_cmap, hw_cursor_cmap);
+ (*fb->setcurshape) (fb);
+ fb->hw_cursor_shown = 1;
+ }
+ if (p->fontwidthlog)
+ fb->cursor.cpos.fbx = (x << p->fontwidthlog) + fb->x_margin;
+ else
+ fb->cursor.cpos.fbx = (x * p->fontwidth) + fb->x_margin;
+ if (p->fontheightlog)
+ fb->cursor.cpos.fby = (y << p->fontheightlog) + fb->y_margin;
+ else
+ fb->cursor.cpos.fby = (y * p->fontheight) + fb->y_margin;
+ (*fb->setcursor)(fb);
+ break;
+ }
+}
+
+ /*
+ * Get the Colormap
+ */
+
+static int sbusfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ if (con == currcon) /* current console? */
+ return fb_get_cmap(cmap, &fb_display[con].var, kspc, sbusfb_getcolreg, info);
+ else if (fb_display[con].cmap.len) /* non default colormap? */
+ fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+ else
+ fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), cmap, kspc ? 0 : 2);
+ return 0;
+}
+
+ /*
+ * Set the Colormap
+ */
+
+static int sbusfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ int err;
+
+ if (!fb_display[con].cmap.len) { /* no colormap allocated? */
+ if ((err = fb_alloc_cmap(&fb_display[con].cmap, 1<<fb_display[con].var.bits_per_pixel, 0)))
+ return err;
+ }
+ if (con == currcon) { /* current console? */
+ err = fb_set_cmap(cmap, &fb_display[con].var, kspc, sbusfb_setcolreg, info);
+ if (!err) {
+ struct fb_info_sbusfb *fb = sbusfbinfo(info);
+
+ if (fb->loadcmap)
+ (*fb->loadcmap)(fb, cmap->start, cmap->len);
+ }
+ return err;
+ } else
+ fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+ return 0;
+}
+
+static int sbusfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg, int con, struct fb_info *info)
+{
+ struct fb_info_sbusfb *fb = sbusfbinfo(info);
+ int i;
+ int lastconsole;
+
+ switch (cmd){
+ case FBIOGTYPE: /* return frame buffer type */
+ copy_to_user_ret((struct fbtype *)arg, &fb->type, sizeof(struct fbtype), -EFAULT);
+ break;
+ case FBIOGATTR: {
+ struct fbgattr *fba = (struct fbgattr *) arg;
+
+ i = verify_area (VERIFY_WRITE, (void *) arg, sizeof (struct fbgattr));
+ if (i) return i;
+ __put_user_ret(fb->emulations[0], &fba->real_type, -EFAULT);
+ __put_user_ret(0, &fba->owner, -EFAULT);
+ __copy_to_user_ret(&fba->fbtype, &fb->type,
+ sizeof(struct fbtype), -EFAULT);
+ __put_user_ret(0, &fba->sattr.flags, -EFAULT);
+ __put_user_ret(fb->type.fb_type, &fba->sattr.emu_type, -EFAULT);
+ __put_user_ret(-1, &fba->sattr.dev_specific[0], -EFAULT);
+ for (i = 0; i < 4; i++)
+ put_user_ret(fb->emulations[i], &fba->emu_types[i], -EFAULT);
+ break;
+ }
+ case FBIOSATTR:
+ i = verify_area (VERIFY_READ, (void *) arg, sizeof (struct fbsattr));
+ if (i) return i;
+ return -EINVAL;
+ case FBIOSVIDEO:
+ if (fb->consolecnt) {
+ lastconsole = info->display_fg->vc_num;
+ if (vt_cons[lastconsole]->vc_mode == KD_TEXT)
+ break;
+ }
+ get_user_ret(i, (int *)arg, -EFAULT);
+ if (i){
+ if (!fb->blanked || !fb->unblank)
+ break;
+ if (fb->consolecnt || (fb->open && fb->mmaped))
+ (*fb->unblank)(fb);
+ fb->blanked = 0;
+ } else {
+ if (fb->blanked || !fb->blank)
+ break;
+ (*fb->blank)(fb);
+ fb->blanked = 1;
+ }
+ break;
+ case FBIOGVIDEO:
+ put_user_ret(fb->blanked, (int *) arg, -EFAULT);
+ break;
+ case FBIOGETCMAP_SPARC: {
+ char *rp, *gp, *bp;
+ int end, count, index;
+ struct fbcmap *cmap;
+
+ if (!fb->loadcmap)
+ return -EINVAL;
+ i = verify_area (VERIFY_READ, (void *) arg, sizeof (struct fbcmap));
+ if (i) return i;
+ cmap = (struct fbcmap *) arg;
+ __get_user_ret(count, &cmap->count, -EFAULT);
+ __get_user_ret(index, &cmap->index, -EFAULT);
+ if ((index < 0) || (index > 255))
+ return -EINVAL;
+ if (index + count > 256)
+ count = 256 - index;
+ __get_user_ret(rp, &cmap->red, -EFAULT);
+ __get_user_ret(gp, &cmap->green, -EFAULT);
+ __get_user_ret(bp, &cmap->blue, -EFAULT);
+ if(verify_area (VERIFY_WRITE, rp, count)) return -EFAULT;
+ if(verify_area (VERIFY_WRITE, gp, count)) return -EFAULT;
+ if(verify_area (VERIFY_WRITE, bp, count)) return -EFAULT;
+ end = index + count;
+ for (i = index; i < end; i++){
+ __put_user_ret(fb->color_map CM(i,0), rp, -EFAULT);
+ __put_user_ret(fb->color_map CM(i,1), gp, -EFAULT);
+ __put_user_ret(fb->color_map CM(i,2), bp, -EFAULT);
+ rp++; gp++; bp++;
+ }
+ (*fb->loadcmap)(fb, index, count);
+ break;
+ }
+ case FBIOPUTCMAP_SPARC: { /* load color map entries */
+ char *rp, *gp, *bp;
+ int end, count, index;
+ struct fbcmap *cmap;
+
+ if (!fb->loadcmap)
+ return -EINVAL;
+ i = verify_area (VERIFY_READ, (void *) arg, sizeof (struct fbcmap));
+ if (i) return i;
+ cmap = (struct fbcmap *) arg;
+ __get_user_ret(count, &cmap->count, -EFAULT);
+ __get_user_ret(index, &cmap->index, -EFAULT);
+ if ((index < 0) || (index > 255))
+ return -EINVAL;
+ if (index + count > 256)
+ count = 256 - index;
+ __get_user_ret(rp, &cmap->red, -EFAULT);
+ __get_user_ret(gp, &cmap->green, -EFAULT);
+ __get_user_ret(bp, &cmap->blue, -EFAULT);
+ if(verify_area (VERIFY_READ, rp, count)) return -EFAULT;
+ if(verify_area (VERIFY_READ, gp, count)) return -EFAULT;
+ if(verify_area (VERIFY_READ, bp, count)) return -EFAULT;
+
+ end = index + count;
+ for (i = index; i < end; i++){
+ __get_user_ret(fb->color_map CM(i,0), rp, -EFAULT);
+ __get_user_ret(fb->color_map CM(i,1), gp, -EFAULT);
+ __get_user_ret(fb->color_map CM(i,2), bp, -EFAULT);
+ rp++; gp++; bp++;
+ }
+ (*fb->loadcmap)(fb, index, count);
+ break;
+ }
+ case FBIOGCURMAX: {
+ struct fbcurpos *p = (struct fbcurpos *) arg;
+ if (!fb->setcursor) return -EINVAL;
+ if(verify_area (VERIFY_WRITE, p, sizeof (struct fbcurpos)))
+ return -EFAULT;
+ __put_user_ret(fb->cursor.hwsize.fbx, &p->fbx, -EFAULT);
+ __put_user_ret(fb->cursor.hwsize.fby, &p->fby, -EFAULT);
+ break;
+ }
+ case FBIOSCURSOR:
+ if (!fb->setcursor) return -EINVAL;
+ if (fb->consolecnt) {
+ lastconsole = info->display_fg->vc_num;
+ if (vt_cons[lastconsole]->vc_mode == KD_TEXT)
+ return -EINVAL; /* Don't let graphics programs hide our nice text cursor */
+ fb->hw_cursor_shown = 0; /* Forget state of our text cursor */
+ }
+ return sbus_hw_scursor ((struct fbcursor *) arg, fb);
+
+ case FBIOSCURPOS:
+ if (!fb->setcursor) return -EINVAL;
+ /* Don't let graphics programs move our nice text cursor */
+ if (fb->consolecnt) {
+ lastconsole = info->display_fg->vc_num;
+ if (vt_cons[lastconsole]->vc_mode == KD_TEXT)
+ return -EINVAL; /* Don't let graphics programs move our nice text cursor */
+ }
+ if (copy_from_user(&fb->cursor.cpos, (void *)arg, sizeof(struct fbcurpos)))
+ return -EFAULT;
+ (*fb->setcursor) (fb);
+ break;
+ default:
+ /* FIXME: Call here possible fb specific ioctl */
+ return -EINVAL;
+ }
+ return 0;
+}
+
+ /*
+ * Setup: parse used options
+ */
+
+__initfunc(void sbusfb_setup(char *options, int *ints))
+{
+ char *p;
+
+ for (p = options;;) {
+ if (!strncmp(p, "nomargins", 9)) {
+ defx_margin = 0; defy_margin = 0;
+ } else if (!strncmp(p, "margins=", 8)) {
+ int i, j;
+ char *q;
+
+ i = simple_strtoul(p+8,&q,10);
+ if (i >= 0 && *q == 'x') {
+ j = simple_strtoul(q+1,&q,10);
+ if (j >= 0 && (*q == ' ' || !*q)) {
+ defx_margin = i; defy_margin = j;
+ }
+ }
+ } else if (!strncmp(p, "font=", 5)) {
+ int i;
+
+ for (i = 0; i < sizeof(fontname) - 1; i++)
+ if (p[i+5] == ' ' || !p[i+5])
+ break;
+ memcpy(fontname, p+5, i);
+ fontname[i] = 0;
+ }
+ while (*p && *p != ' ' && *p != ',') p++;
+ if (*p != ',') break;
+ p++;
+ }
+}
+
+static int sbusfbcon_switch(int con, struct fb_info *info)
+{
+ int x_margin, y_margin;
+ struct fb_info_sbusfb *fb = sbusfbinfo(info);
+ int lastconsole;
+
+ /* Do we have to save the colormap? */
+ if (fb_display[currcon].cmap.len)
+ fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1, sbusfb_getcolreg, info);
+
+ lastconsole = info->display_fg->vc_num;
+ if (lastconsole != con &&
+ (fb_display[lastconsole].fontwidth != fb_display[con].fontwidth ||
+ fb_display[lastconsole].fontheight != fb_display[con].fontheight))
+ fb->hw_cursor_shown = 0;
+ x_margin = (fb_display[con].var.xres_virtual - fb_display[con].var.xres) / 2;
+ y_margin = (fb_display[con].var.yres_virtual - fb_display[con].var.yres) / 2;
+ if (fb->margins)
+ fb->margins(fb, &fb_display[con], x_margin, y_margin);
+ if (fb->x_margin != x_margin || fb->y_margin != y_margin) {
+ fb->x_margin = x_margin; fb->y_margin = y_margin;
+ sbusfb_clear_margin(&fb_display[con], 0);
+ }
+ currcon = con;
+ /* Install new colormap */
+ do_install_cmap(con, info);
+ return 0;
+}
+
+ /*
+ * Update the `var' structure (called by fbcon.c)
+ */
+
+static int sbusfbcon_updatevar(int con, struct fb_info *info)
+{
+ /* Nothing */
+ return 0;
+}
+
+ /*
+ * Blank the display.
+ */
+
+static void sbusfbcon_blank(int blank, struct fb_info *info)
+{
+ struct fb_info_sbusfb *fb = sbusfbinfo(info);
+
+ if (blank && fb->blank)
+ return fb->blank(fb);
+ else if (!blank && fb->unblank)
+ return fb->unblank(fb);
+}
+
+ /*
+ * Read a single color register and split it into
+ * colors/transparent. Return != 0 for invalid regno.
+ */
+
+static int sbusfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+ u_int *transp, struct fb_info *info)
+{
+ struct fb_info_sbusfb *fb = sbusfbinfo(info);
+
+ if (!fb->color_map || regno > 255)
+ return 1;
+ *red = fb->color_map CM(regno, 0);
+ *green = fb->color_map CM(regno, 1);
+ *blue = fb->color_map CM(regno, 2);
+ return 0;
+}
+
+
+ /*
+ * Set a single color register. The values supplied are already
+ * rounded down to the hardware's capabilities (according to the
+ * entries in the var structure). Return != 0 for invalid regno.
+ */
+
+static int sbusfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info)
+{
+ struct fb_info_sbusfb *fb = sbusfbinfo(info);
+
+ if (!fb->color_map || regno > 255)
+ return 1;
+ fb->color_map CM(regno, 0) = red;
+ fb->color_map CM(regno, 1) = green;
+ fb->color_map CM(regno, 2) = blue;
+ return 0;
+}
+
+
+static void do_install_cmap(int con, struct fb_info *info)
+{
+ struct fb_info_sbusfb *fb = sbusfbinfo(info);
+
+ if (con != currcon)
+ return;
+ if (fb_display[con].cmap.len)
+ fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
+ sbusfb_setcolreg, info);
+ else
+ fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+ &fb_display[con].var, 1, sbusfb_setcolreg, info);
+ if (fb->loadcmap)
+ (*fb->loadcmap)(fb, 0, 256);
+}
+
+static int sbusfb_set_font(struct display *p, int width, int height)
+{
+ int margin;
+ int w = p->var.xres_virtual, h = p->var.yres_virtual;
+ int depth = p->var.bits_per_pixel;
+ struct fb_info_sbusfb *fb = sbusfbinfod(p);
+ int x_margin, y_margin;
+
+ if (depth > 8) depth = 8;
+ x_margin = 0;
+ y_margin = 0;
+ if (defx_margin < 0 || defy_margin < 0) {
+ for (margin = 0; def_margins[margin].depth; margin++)
+ if (w == def_margins[margin].xres &&
+ h == def_margins[margin].yres &&
+ depth == def_margins[margin].depth) {
+ x_margin = def_margins[margin].x_margin;
+ y_margin = def_margins[margin].y_margin;
+ break;
+ }
+ } else {
+ x_margin = defx_margin;
+ y_margin = defy_margin;
+ }
+ x_margin += ((w - 2*x_margin) % width) / 2;
+ y_margin += ((h - 2*y_margin) % height) / 2;
+
+ p->var.xres = w - 2*x_margin;
+ p->var.yres = h - 2*y_margin;
+
+ fb->hw_cursor_shown = 0;
+
+ if (fb->margins)
+ fb->margins(fb, p, x_margin, y_margin);
+ if (fb->x_margin != x_margin || fb->y_margin != y_margin) {
+ fb->x_margin = x_margin; fb->y_margin = y_margin;
+ sbusfb_clear_margin(p, 0);
+ }
+
+ return 1;
+}
+
+void sbusfb_palette(int enter)
+{
+ int i;
+ struct display *p;
+
+ for (i = 0; i < MAX_NR_CONSOLES; i++) {
+ p = &fb_display[i];
+ if (p->dispsw && p->dispsw->setup == sbusfb_disp_setup &&
+ p->fb_info->display_fg &&
+ p->fb_info->display_fg->vc_num == i) {
+ struct fb_info_sbusfb *fb = sbusfbinfod(p);
+
+ if (fb->restore_palette) {
+ if (enter)
+ fb->restore_palette(fb);
+ else if (vt_cons[i]->vc_mode != KD_GRAPHICS)
+ vc_cons[i].d->vc_sw->con_set_palette(vc_cons[i].d, color_table);
+ }
+ }
+ }
+}
+
+ /*
+ * Initialisation
+ */
+
+extern void (*prom_palette)(int);
+
+__initfunc(static void sbusfb_init_fb(int node, int parent, int fbtype,
+ struct linux_sbus_device *sbdp))
+{
+ struct fb_fix_screeninfo *fix;
+ struct fb_var_screeninfo *var;
+ struct display *disp;
+ struct fb_info_sbusfb *fb;
+ struct fbtype *type;
+ int linebytes, w, h, depth;
+ char *p = NULL;
+ int margin;
+
+ fb = kmalloc(sizeof(struct fb_info_sbusfb), GFP_ATOMIC);
+ if (!fb) {
+ prom_printf("Could not allocate sbusfb structure\n");
+ return;
+ }
+
+ if (!prom_palette)
+ prom_palette = sbusfb_palette;
+
+ memset(fb, 0, sizeof(struct fb_info_sbusfb));
+ fix = &fb->fix;
+ var = &fb->var;
+ disp = &fb->disp;
+ type = &fb->type;
+
+ fb->prom_node = node;
+ fb->prom_parent = parent;
+ fb->sbdp = sbdp;
+ if (sbdp)
+ fb->iospace = sbdp->reg_addrs[0].which_io;
+
+ type->fb_type = fbtype;
+ memset(&fb->emulations, 0xff, sizeof(fb->emulations));
+ fb->emulations[0] = fbtype;
+
+#ifndef __sparc_v9__
+ disp->screen_base = (unsigned char *)prom_getintdefault(node, "address", 0);
+#endif
+
+ type->fb_height = h = prom_getintdefault(node, "height", 900);
+ type->fb_width = w = prom_getintdefault(node, "width", 1152);
+sizechange:
+ type->fb_depth = depth = (fbtype == FBTYPE_SUN2BW) ? 1 : 8;
+ linebytes = prom_getintdefault(node, "linebytes", w * depth / 8);
+ type->fb_size = PAGE_ALIGN((linebytes) * h);
+
+ if (defx_margin < 0 || defy_margin < 0) {
+ for (margin = 0; def_margins[margin].depth; margin++)
+ if (w == def_margins[margin].xres &&
+ h == def_margins[margin].yres &&
+ depth == def_margins[margin].depth) {
+ fb->x_margin = def_margins[margin].x_margin;
+ fb->y_margin = def_margins[margin].y_margin;
+ break;
+ }
+ } else {
+ fb->x_margin = defx_margin;
+ fb->y_margin = defy_margin;
+ }
+ fb->x_margin += ((w - 2*fb->x_margin) & 7) / 2;
+ fb->y_margin += ((h - 2*fb->y_margin) & 15) / 2;
+
+ var->xres_virtual = w;
+ var->yres_virtual = h;
+ var->xres = w - 2*fb->x_margin;
+ var->yres = h - 2*fb->y_margin;
+
+ var->bits_per_pixel = depth;
+ var->height = var->width = -1;
+ var->pixclock = 10000;
+ var->vmode = FB_VMODE_NONINTERLACED;
+ var->red.length = var->green.length = var->blue.length = 8;
+
+ fix->line_length = linebytes;
+ fix->smem_len = type->fb_size;
+ fix->type = FB_TYPE_PACKED_PIXELS;
+ fix->visual = FB_VISUAL_PSEUDOCOLOR;
+
+ fb->info.node = -1;
+ fb->info.fbops = &sbusfb_ops;
+ fb->info.disp = disp;
+ strcpy(fb->info.fontname, fontname);
+ fb->info.changevar = NULL;
+ fb->info.switch_con = &sbusfbcon_switch;
+ fb->info.updatevar = &sbusfbcon_updatevar;
+ fb->info.blank = &sbusfbcon_blank;
+
+ fb->cursor.hwsize.fbx = 32;
+ fb->cursor.hwsize.fby = 32;
+
+ if (depth > 1 && !fb->color_map)
+ fb->color_map = kmalloc(256 * 3, GFP_ATOMIC);
+
+ switch(fbtype) {
+#ifdef CONFIG_FB_CREATOR
+ case FBTYPE_CREATOR:
+ p = creatorfb_init(fb); break;
+#endif
+#ifdef CONFIG_FB_CGSIX
+ case FBTYPE_SUNFAST_COLOR:
+ p = cgsixfb_init(fb); break;
+#endif
+#ifdef CONFIG_FB_CGTHREE
+ case FBTYPE_SUN3COLOR:
+ p = cgthreefb_init(fb); break;
+#endif
+#ifdef CONFIG_FB_TCX
+ case FBTYPE_TCXCOLOR:
+ p = tcxfb_init(fb); break;
+#endif
+#ifdef CONFIG_FB_LEO
+ case FBTYPE_SUNLEO:
+ p = leofb_init(fb); break;
+#endif
+#ifdef CONFIG_FB_BWTWO
+ case FBTYPE_SUN2BW:
+ p = bwtwofb_init(fb); break;
+#endif
+#ifdef CONFIG_FB_CGFOURTEEN
+ case FBTYPE_MDICOLOR:
+ p = cgfourteenfb_init(fb); break;
+#endif
+ }
+
+ if (!p) {
+ kfree(fb);
+ return;
+ }
+
+ if (p == SBUSFBINIT_SIZECHANGE)
+ goto sizechange;
+
+ disp->dispsw = &fb->dispsw;
+ if (fb->setcursor)
+ fb->dispsw.cursor = sbusfb_cursor;
+ fb->dispsw.set_font = sbusfb_set_font;
+ fb->setup = fb->dispsw.setup;
+ fb->dispsw.setup = sbusfb_disp_setup;
+ fb->dispsw.clear_margins = NULL;
+
+ disp->var = *var;
+ disp->visual = fix->visual;
+ disp->type = fix->type;
+ disp->type_aux = fix->type_aux;
+ disp->line_length = fix->line_length;
+
+ if (fb->blank)
+ disp->can_soft_blank = 1;
+
+ sbusfb_set_var(var, -1, &fb->info);
+
+ if (register_framebuffer(&fb->info) < 0) {
+ kfree(fb);
+ return;
+ }
+ printk("fb%d: %s\n", GET_FB_IDX(fb->info.node), p);
+}
+
+static inline int known_card(char *name)
+{
+ char *p;
+ for (p = name; *p && *p != ','; p++);
+ if (*p == ',') name = p + 1;
+ if (!strcmp(name, "cgsix") || !strcmp(name, "cgthree+"))
+ return FBTYPE_SUNFAST_COLOR;
+ if (!strcmp(name, "cgthree") || !strcmp(name, "cgRDI"))
+ return FBTYPE_SUN3COLOR;
+ if (!strcmp(name, "cgfourteen"))
+ return FBTYPE_MDICOLOR;
+ if (!strcmp(name, "leo"))
+ return FBTYPE_SUNLEO;
+ if (!strcmp(name, "bwtwo"))
+ return FBTYPE_SUN2BW;
+ if (!strcmp(name, "tcx"))
+ return FBTYPE_TCXCOLOR;
+ return FBTYPE_NOTYPE;
+}
+
+__initfunc(void sbusfb_init(void))
+{
+ int type;
+ struct linux_sbus_device *sbdp;
+ struct linux_sbus *sbus;
+ char prom_name[40];
+ extern int con_is_present(void);
+
+ if (!con_is_present()) return;
+
+#ifdef CONFIG_FB_CREATOR
+ {
+ int root, node;
+ root = prom_getchild(prom_root_node);
+ for (node = prom_searchsiblings(root, "SUNW,ffb"); node;
+ node = prom_searchsiblings(prom_getsibling(node), "SUNW,ffb")) {
+ sbusfb_init_fb(node, prom_root_node, FBTYPE_CREATOR, NULL);
+ }
+ }
+#endif
+#ifdef CONFIG_SUN4
+ sbusfb_init_fb(0, 0, FBTYPE_SUN2BW, NULL);
+#endif
+#if defined(CONFIG_FB_CGFOURTEEN) && !defined(__sparc_v9__)
+ {
+ int root, node;
+ root = prom_getchild(prom_root_node);
+ root = prom_searchsiblings(root, "obio");
+ if (root &&
+ (node = prom_searchsiblings(prom_getchild(root), "cgfourteen"))) {
+ sbusfb_init_fb(node, root, FBTYPE_MDICOLOR, NULL);
+ }
+ }
+#endif
+ if (!SBus_chain) return;
+ for_all_sbusdev(sbdp, sbus) {
+ type = known_card(sbdp->prom_name);
+ if (type == FBTYPE_NOTYPE) continue;
+ if (prom_getproperty(sbdp->prom_node, "emulation", prom_name, sizeof(prom_name)) > 0) {
+ type = known_card(prom_name);
+ if (type == FBTYPE_NOTYPE) type = known_card(sbdp->prom_name);
+ }
+ prom_apply_sbus_ranges(sbdp->my_bus, &sbdp->reg_addrs[0],
+ sbdp->num_registers, sbdp);
+ sbusfb_init_fb(sbdp->prom_node, sbdp->my_bus->prom_node, type, sbdp);
+ }
+}
diff --git a/drivers/video/sbusfb.h b/drivers/video/sbusfb.h
new file mode 100644
index 000000000..f65ca1d71
--- /dev/null
+++ b/drivers/video/sbusfb.h
@@ -0,0 +1,116 @@
+#include <asm/sbus.h>
+#include <asm/oplib.h>
+#include <asm/fbio.h>
+
+#include "fbcon.h"
+
+struct bt_regs {
+ volatile unsigned int addr; /* address register */
+ volatile unsigned int color_map; /* color map */
+ volatile unsigned int control; /* control register */
+ volatile unsigned int cursor; /* cursor map register */
+};
+
+struct fb_info_creator {
+ struct ffb_fbc *fbc;
+ struct ffb_dac *dac;
+ int dac_rev;
+ int xy_margin;
+};
+struct fb_info_cgsix {
+ struct bt_regs *bt;
+ struct cg6_fbc *fbc;
+ struct cg6_thc *thc;
+ struct cg6_tec *tec;
+ volatile u32 *fhc;
+};
+struct fb_info_bwtwo {
+ struct bw2_regs *regs;
+};
+struct fb_info_cgthree {
+ struct cg3_regs *regs;
+};
+struct fb_info_tcx {
+ struct bt_regs *bt;
+ struct tcx_thc *thc;
+ struct tcx_tec *tec;
+ u32 *cplane;
+};
+
+struct cg_cursor {
+ short enable; /* cursor is enabled */
+ struct fbcurpos cpos; /* position */
+ struct fbcurpos chot; /* hot-spot */
+ struct fbcurpos size; /* size of mask & image fields */
+ struct fbcurpos hwsize; /* hw max size */
+ int bits[2][128]; /* space for mask & image bits */
+ char color [6]; /* cursor colors */
+};
+
+struct sbus_mmap_map {
+ unsigned long voff;
+ unsigned long poff;
+ unsigned long size;
+};
+
+#define SBUS_MMAP_FBSIZE(n) (-n)
+#define SBUS_MMAP_EMPTY 0x80000000
+
+struct fb_info_sbusfb {
+ struct fb_info info;
+ struct fb_fix_screeninfo fix;
+ struct fb_var_screeninfo var;
+ struct display disp;
+ struct display_switch dispsw;
+ struct fbtype type;
+ struct linux_sbus_device *sbdp;
+ int prom_node, prom_parent;
+ union {
+ struct fb_info_creator ffb;
+ struct fb_info_cgsix cg6;
+ struct fb_info_bwtwo bw2;
+ struct fb_info_cgthree cg3;
+ struct fb_info_tcx tcx;
+ } s;
+ unsigned char *color_map;
+ struct cg_cursor cursor;
+ unsigned char hw_cursor_shown;
+ unsigned char open;
+ unsigned char mmaped;
+ unsigned char blanked;
+ int x_margin;
+ int y_margin;
+ int vtconsole;
+ int consolecnt;
+ int emulations[4];
+ struct sbus_mmap_map *mmap_map;
+ unsigned long physbase;
+ int iospace;
+ /* Methods */
+ void (*setup)(struct display *);
+ void (*setcursor)(struct fb_info_sbusfb *);
+ void (*setcurshape)(struct fb_info_sbusfb *);
+ void (*setcursormap)(struct fb_info_sbusfb *, unsigned char *, unsigned char *, unsigned char *);
+ void (*loadcmap)(struct fb_info_sbusfb *, int, int);
+ void (*blank)(struct fb_info_sbusfb *);
+ void (*unblank)(struct fb_info_sbusfb *);
+ void (*margins)(struct fb_info_sbusfb *, struct display *, int, int);
+ void (*reset)(struct fb_info_sbusfb *);
+ void (*fill)(struct fb_info_sbusfb *, struct display *, int, int, unsigned short *);
+ void (*switch_from_graph)(struct fb_info_sbusfb *);
+ void (*restore_palette)(struct fb_info_sbusfb *);
+};
+
+extern char *creatorfb_init(struct fb_info_sbusfb *);
+extern char *cgsixfb_init(struct fb_info_sbusfb *);
+extern char *cgthreefb_init(struct fb_info_sbusfb *);
+extern char *tcxfb_init(struct fb_info_sbusfb *);
+extern char *leofb_init(struct fb_info_sbusfb *);
+extern char *bwtwofb_init(struct fb_info_sbusfb *);
+extern char *cgfourteenfb_init(struct fb_info_sbusfb *);
+
+#define sbusfbinfod(disp) ((struct fb_info_sbusfb *)(disp->fb_info))
+#define sbusfbinfo(info) ((struct fb_info_sbusfb *)(info))
+#define CM(i, j) [3*(i)+(j)]
+
+#define SBUSFBINIT_SIZECHANGE ((char *)-1)
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index e2c553392..1831e6b33 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -8,7 +8,6 @@
* for more details.
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -60,8 +59,7 @@ struct xxxfb_par {
/*
* If your driver supports multiple boards, you should make these arrays,
- * or allocate them dynamically (using mem_start for builtin drivers, and
- * kmalloc() for loaded modules).
+ * or allocate them dynamically (using kmalloc()).
*/
static struct xxxfb_info fb_info;
@@ -245,15 +243,15 @@ static struct display_switch *xxx_get_dispsw(const void *par,
* If you don't have any appropriate operations, simple fill in the NULL
* pointer, and there will be no text output.
*/
-#ifdef CONFIG_FBCON_CFB8
+#ifdef FBCON_HAS_CFB8
if (is_cfb8)
return &fbcon_cfb8;
#endif
-#ifdef CONFIG_FBCON_CFB16
+#ifdef FBCON_HAS_CFB16
if (is_cfb16)
return &fbcon_cfb16;
#endif
-#ifdef CONFIG_FBCON_CFB32
+#ifdef FBCON_HAS_CFB32
if (is_cfb32)
return &fbcon_cfb32;
#endif
@@ -271,16 +269,15 @@ struct fbgen_hwswitch xxx_switch = {
-/* ------------ Hardware Independant Functions ------------ */
+/* ------------ Hardware Independent Functions ------------ */
/*
* Initialization
*/
-__initfunc(unsigned long xxxfb_init(unsigned long mem_start))
+__initfunc(void xxxfb_init(void))
{
- int err;
struct fb_var_screeninfo var;
fb_info.fbhw = &xxx_switch;
@@ -296,18 +293,15 @@ __initfunc(unsigned long xxxfb_init(unsigned long mem_start))
/* This should give a reasonable default video mode */
fbgen_get_var(&disp.var, -1, &fb_info.gen);
fbgen_do_set_var(var, 1, &fbinfo.gen);
- err = register_framebuffer(&fb_info.gen.info);
- if (err < 0)
- return err;
fbgen_set_disp(-1, &fb_info.gen.info);
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.node),
fb_info.modename);
/* uncomment this if your driver cannot be unloaded */
/* MOD_INC_USE_COUNT; */
-
- return mem_start;
}
@@ -344,14 +338,14 @@ __initfunc(void xxxfb_setup(char *options, int *ints))
* Frame buffer operations
*/
-static int xxxfb_open(const struct fb_info *info)
+static int xxxfb_open(const struct fb_info *info, int user)
{
/* Nothing, only a usage count for the moment */
MOD_INC_USE_COUNT;
return 0;
}
-static int xxxfb_release(const struct fb_info *info)
+static int xxxfb_release(const struct fb_info *info, int user)
{
MOD_DEC_USE_COUNT;
return 0;
@@ -365,7 +359,7 @@ static int xxxfb_release(const struct fb_info *info)
static struct fb_ops xxxfb_ops = {
xxxfb_open, xxxfb_release, fbgen_get_fix, fbgen_get_var, fbgen_set_var,
- fbgen_get_cmap, fbgen_set_cmap, fbgen_pan_display, NULL, fbgen_ioctl
+ fbgen_get_cmap, fbgen_set_cmap, fbgen_pan_display, fbgen_ioctl
};
@@ -379,7 +373,8 @@ static struct fb_ops xxxfb_ops = {
#ifdef MODULE
int init_module(void)
{
- return xxxfb_init(NULL);
+ xxxfb_init();
+ return 0;
}
void cleanup_module(void)
diff --git a/drivers/video/tcxfb.c b/drivers/video/tcxfb.c
new file mode 100644
index 000000000..181b6c53e
--- /dev/null
+++ b/drivers/video/tcxfb.c
@@ -0,0 +1,290 @@
+/* $Id: tcxfb.c,v 1.1 1998/07/21 14:50:44 jj Exp $
+ * tcxfb.c: TCX 24/8bit frame buffer driver
+ *
+ * Copyright (C) 1996,1998 Jakub Jelinek (jj@ultra.linux.cz)
+ * Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
+ * Copyright (C) 1996 Eddie C. Dost (ecd@skynet.be)
+ */
+
+#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 "sbusfb.h"
+#include <asm/io.h>
+
+#include "fbcon-cfb8.h"
+
+/* THC definitions */
+#define TCX_THC_MISC_REV_SHIFT 16
+#define TCX_THC_MISC_REV_MASK 15
+#define TCX_THC_MISC_VSYNC_DIS (1 << 25)
+#define TCX_THC_MISC_HSYNC_DIS (1 << 24)
+#define TCX_THC_MISC_RESET (1 << 12)
+#define TCX_THC_MISC_VIDEO (1 << 10)
+#define TCX_THC_MISC_SYNC (1 << 9)
+#define TCX_THC_MISC_VSYNC (1 << 8)
+#define TCX_THC_MISC_SYNC_ENAB (1 << 7)
+#define TCX_THC_MISC_CURS_RES (1 << 6)
+#define TCX_THC_MISC_INT_ENAB (1 << 5)
+#define TCX_THC_MISC_INT (1 << 4)
+#define TCX_THC_MISC_INIT 0x9f
+#define TCX_THC_REV_REV_SHIFT 20
+#define TCX_THC_REV_REV_MASK 15
+#define TCX_THC_REV_MINREV_SHIFT 28
+#define TCX_THC_REV_MINREV_MASK 15
+
+/* The contents are unknown */
+struct tcx_tec {
+ volatile u32 tec_matrix;
+ volatile u32 tec_clip;
+ volatile u32 tec_vdc;
+};
+
+struct tcx_thc {
+ volatile u32 thc_rev;
+ u32 thc_pad0[511];
+ volatile u32 thc_hs; /* hsync timing */
+ volatile u32 thc_hsdvs;
+ volatile u32 thc_hd;
+ volatile u32 thc_vs; /* vsync timing */
+ volatile u32 thc_vd;
+ volatile u32 thc_refresh;
+ volatile u32 thc_misc;
+ u32 thc_pad1[56];
+ volatile u32 thc_cursxy; /* cursor x,y position (16 bits each) */
+ volatile u32 thc_cursmask[32]; /* cursor mask bits */
+ volatile u32 thc_cursbits[32]; /* what to show where mask enabled */
+};
+
+static struct sbus_mmap_map tcx_mmap_map[] = {
+ { TCX_RAM8BIT, 0, SBUS_MMAP_FBSIZE(1) },
+ { TCX_RAM24BIT, 0, SBUS_MMAP_FBSIZE(4) },
+ { TCX_UNK3, 0, SBUS_MMAP_FBSIZE(8) },
+ { TCX_UNK4, 0, SBUS_MMAP_FBSIZE(8) },
+ { TCX_CONTROLPLANE, 0, SBUS_MMAP_FBSIZE(4) },
+ { TCX_UNK6, 0, SBUS_MMAP_FBSIZE(8) },
+ { TCX_UNK7, 0, SBUS_MMAP_FBSIZE(8) },
+ { TCX_TEC, 0, PAGE_SIZE },
+ { TCX_BTREGS, 0, PAGE_SIZE },
+ { TCX_THC, 0, PAGE_SIZE },
+ { TCX_DHC, 0, PAGE_SIZE },
+ { TCX_ALT, 0, PAGE_SIZE },
+ { TCX_UNK2, 0, 0x20000 },
+ { 0, 0, 0 }
+};
+
+static void tcx_set_control_plane (struct fb_info_sbusfb *fb)
+{
+ u32 *p, *pend;
+
+ p = fb->s.tcx.cplane;
+ if (!p) return;
+ for (pend = p + fb->type.fb_size; p < pend; p++)
+ *p &= 0xffffff;
+}
+
+static void tcx_switch_from_graph (struct fb_info_sbusfb *fb)
+{
+ /* Reset control plane to 8bit mode if necessary */
+ if (fb->open && fb->mmaped)
+ tcx_set_control_plane (fb);
+}
+
+static void tcx_loadcmap (struct fb_info_sbusfb *fb, int index, int count)
+{
+ struct bt_regs *bt = fb->s.tcx.bt;
+ int i;
+
+ bt->addr = index << 24;
+ for (i = index; count--; i++){
+ bt->color_map = fb->color_map CM(i,0) << 24;
+ bt->color_map = fb->color_map CM(i,1) << 24;
+ bt->color_map = fb->color_map CM(i,2) << 24;
+ }
+}
+
+static void tcx_restore_palette (struct fb_info_sbusfb *fb)
+{
+ struct bt_regs *bt = fb->s.tcx.bt;
+
+ bt->addr = 0;
+ bt->color_map = 0xffffffff;
+ bt->color_map = 0xffffffff;
+ bt->color_map = 0xffffffff;
+}
+
+static void tcx_setcursormap (struct fb_info_sbusfb *fb, u8 *red, u8 *green, u8 *blue)
+{
+ struct bt_regs *bt = fb->s.tcx.bt;
+
+ /* Note the 2 << 24 is different from cg6's 1 << 24 */
+ bt->addr = 2 << 24;
+ bt->cursor = red[0] << 24;
+ bt->cursor = green[0] << 24;
+ bt->cursor = blue[0] << 24;
+ bt->addr = 3 << 24;
+ bt->cursor = red[1] << 24;
+ bt->cursor = green[1] << 24;
+ bt->cursor = blue[1] << 24;
+ bt->addr = 0;
+}
+
+/* Set cursor shape */
+static void tcx_setcurshape (struct fb_info_sbusfb *fb)
+{
+ struct tcx_thc *thc = fb->s.tcx.thc;
+ int i;
+
+ for (i = 0; i < 32; i++){
+ thc->thc_cursmask [i] = fb->cursor.bits[0][i];
+ thc->thc_cursbits [i] = fb->cursor.bits[1][i];
+ }
+}
+
+/* Load cursor information */
+static void tcx_setcursor (struct fb_info_sbusfb *fb)
+{
+ unsigned int v;
+ struct cg_cursor *c = &fb->cursor;
+
+ if (c->enable)
+ v = ((c->cpos.fbx - c->chot.fbx) << 16)
+ |((c->cpos.fby - c->chot.fby) & 0xffff);
+ else
+ /* Magic constant to turn off the cursor */
+ v = ((65536-32) << 16) | (65536-32);
+ fb->s.tcx.thc->thc_cursxy = v;
+}
+
+static void tcx_blank (struct fb_info_sbusfb *fb)
+{
+ fb->s.tcx.thc->thc_misc &= ~TCX_THC_MISC_VIDEO;
+ /* This should put us in power-save */
+ fb->s.tcx.thc->thc_misc |= TCX_THC_MISC_VSYNC_DIS;
+ fb->s.tcx.thc->thc_misc |= TCX_THC_MISC_HSYNC_DIS;
+}
+
+static void tcx_unblank (struct fb_info_sbusfb *fb)
+{
+ fb->s.tcx.thc->thc_misc &= ~TCX_THC_MISC_VSYNC_DIS;
+ fb->s.tcx.thc->thc_misc &= ~TCX_THC_MISC_HSYNC_DIS;
+ fb->s.tcx.thc->thc_misc |= TCX_THC_MISC_VIDEO;
+}
+
+static void tcx_reset (struct fb_info_sbusfb *fb)
+{
+ if (fb->open && fb->mmaped)
+ tcx_set_control_plane(fb);
+
+ /* Turn off stuff in the Transform Engine. */
+ fb->s.tcx.tec->tec_matrix = 0;
+ fb->s.tcx.tec->tec_clip = 0;
+ fb->s.tcx.tec->tec_vdc = 0;
+
+ /* Enable cursor in Brooktree DAC. */
+ fb->s.tcx.bt->addr = 0x06 << 24;
+ fb->s.tcx.bt->control |= 0x03 << 24;
+}
+
+static void tcx_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 };
+
+__initfunc(char *tcxfb_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[0].phys_addr;
+ int lowdepth;
+
+#ifndef FBCON_HAS_CFB8
+ return NULL;
+#endif
+
+ lowdepth = prom_getbool (fb->prom_node, "tcx-8-bit");
+
+ if (lowdepth) {
+ strcpy(fb->info.modename, "TCX8");
+ strcpy(fix->id, "TCX8");
+ } else {
+ strcpy(fb->info.modename, "TCX24");
+ strcpy(fix->id, "TCX24");
+ }
+ 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, "tcx_ram", fb->iospace, 0);
+ disp->screen_base += fix->line_length * fb->y_margin + fb->x_margin;
+ fb->s.tcx.tec = (struct tcx_tec *)sparc_alloc_io(fb->sbdp->reg_addrs[7].phys_addr, 0,
+ sizeof(struct tcx_tec), "tcx_tec", fb->iospace, 0);
+ fb->s.tcx.thc = (struct tcx_thc *)sparc_alloc_io(fb->sbdp->reg_addrs[9].phys_addr, 0,
+ sizeof(struct tcx_thc), "tcx_thc", fb->iospace, 0);
+ fb->s.tcx.bt = (struct bt_regs *)sparc_alloc_io(fb->sbdp->reg_addrs[8].phys_addr, 0,
+ sizeof(struct bt_regs), "tcx_dac", fb->iospace, 0);
+ if (!lowdepth) {
+ fb->s.tcx.cplane = (u32 *)sparc_alloc_io(fb->sbdp->reg_addrs[4].phys_addr, 0,
+ type->fb_size*4, "tcx_cplane", fb->iospace, 0);
+ type->fb_depth = 24;
+ fb->switch_from_graph = tcx_switch_from_graph;
+ } else {
+ /* As there can be one tcx in a machine only, we can write directly into
+ tcx_mmap_map */
+ tcx_mmap_map[1].size = SBUS_MMAP_EMPTY;
+ tcx_mmap_map[4].size = SBUS_MMAP_EMPTY;
+ tcx_mmap_map[5].size = SBUS_MMAP_EMPTY;
+ tcx_mmap_map[6].size = SBUS_MMAP_EMPTY;
+ }
+ fb->dispsw = fbcon_cfb8;
+
+ fb->margins = tcx_margins;
+ fb->loadcmap = tcx_loadcmap;
+ if (prom_getbool (fb->prom_node, "hw-cursor")) {
+ fb->setcursor = tcx_setcursor;
+ fb->setcursormap = tcx_setcursormap;
+ fb->setcurshape = tcx_setcurshape;
+ }
+ fb->restore_palette = tcx_restore_palette;
+ fb->blank = tcx_blank;
+ fb->unblank = tcx_unblank;
+ fb->reset = tcx_reset;
+
+ fb->physbase = 0;
+ fb->mmap_map = tcx_mmap_map;
+
+ /* Initialize Brooktree DAC */
+ fb->s.tcx.bt->addr = 0x04 << 24; /* color planes */
+ fb->s.tcx.bt->control = 0xff << 24;
+ fb->s.tcx.bt->addr = 0x05 << 24;
+ fb->s.tcx.bt->control = 0x00 << 24;
+ fb->s.tcx.bt->addr = 0x06 << 24; /* overlay plane */
+ fb->s.tcx.bt->control = 0x73 << 24;
+ fb->s.tcx.bt->addr = 0x07 << 24;
+ fb->s.tcx.bt->control = 0x00 << 24;
+
+ sprintf(idstring, "tcx at %x.%08lx Rev %d.%d %s", fb->iospace, phys,
+ (fb->s.tcx.thc->thc_rev >> TCX_THC_REV_REV_SHIFT) & TCX_THC_REV_REV_MASK,
+ (fb->s.tcx.thc->thc_rev >> TCX_THC_REV_MINREV_SHIFT) & TCX_THC_REV_MINREV_MASK,
+ lowdepth ? "8-bit only" : "24-bit depth");
+
+ tcx_reset(fb);
+
+ return idstring;
+}
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index 7e74f7449..d15d87a6b 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -21,8 +21,6 @@
*
* KNOWN PROBLEMS/TO DO ==================================================== */
-
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/kernel.h>
@@ -40,6 +38,7 @@
#include <linux/selection.h>
#include <asm/io.h>
+#include "fbcon.h"
#include "fbcon-cfb8.h"
#include "fbcon-cfb32.h"
@@ -252,8 +251,8 @@ static struct fb_var_screeninfo fb_var = { 0, };
* Interface used by the world
*/
-static int tgafb_open(struct fb_info *info);
-static int tgafb_release(struct fb_info *info);
+static int tgafb_open(struct fb_info *info, int user);
+static int tgafb_release(struct fb_info *info, int user);
static int tgafb_get_fix(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info);
static int tgafb_get_var(struct fb_var_screeninfo *var, int con,
@@ -274,7 +273,7 @@ static int tgafb_ioctl(struct inode *inode, struct file *file, u_int cmd,
* Interface to the low level console driver
*/
-unsigned long tgafb_init(unsigned long mem_start);
+void tgafb_init(void);
static int tgafbcon_switch(int con, struct fb_info *info);
static int tgafbcon_updatevar(int con, struct fb_info *info);
static void tgafbcon_blank(int blank, struct fb_info *info);
@@ -296,7 +295,7 @@ static void do_install_cmap(int con, struct fb_info *info);
static struct fb_ops tgafb_ops = {
tgafb_open, tgafb_release, tgafb_get_fix, tgafb_get_var, tgafb_set_var,
- tgafb_get_cmap, tgafb_set_cmap, tgafb_pan_display, NULL, tgafb_ioctl
+ tgafb_get_cmap, tgafb_set_cmap, tgafb_pan_display, tgafb_ioctl
};
@@ -304,7 +303,7 @@ static struct fb_ops tgafb_ops = {
* Open/Release the frame buffer device
*/
-static int tgafb_open(struct fb_info *info)
+static int tgafb_open(struct fb_info *info, int user)
{
/*
* Nothing, only a usage count for the moment
@@ -314,7 +313,7 @@ static int tgafb_open(struct fb_info *info)
return(0);
}
-static int tgafb_release(struct fb_info *info)
+static int tgafb_release(struct fb_info *info, int user)
{
MOD_DEC_USE_COUNT;
return(0);
@@ -453,15 +452,15 @@ static int tgafb_ioctl(struct inode *inode, struct file *file, u_int cmd,
* Initialisation
*/
-__initfunc(unsigned long tgafb_init(unsigned long mem_start))
+__initfunc(void tgafb_init(void))
{
- int i, j, temp, err;
+ int i, j, temp;
unsigned char *cbp;
struct pci_dev *pdev;
pdev = pci_find_device(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_TGA, NULL);
if (!pdev)
- return mem_start;
+ return;
tga_mem_base = pdev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK;
#ifdef DEBUG
printk("tgafb_init: mem_base 0x%x\n", tga_mem_base);
@@ -480,7 +479,7 @@ __initfunc(unsigned long tgafb_init(unsigned long mem_start))
break;
default:
printk("TGA type (0x%x) unrecognized!\n", tga_type);
- return mem_start;
+ return;
}
tga_regs_base = ((unsigned long)tga_mem_base + TGA_REGS_OFFSET);
@@ -689,12 +688,13 @@ __initfunc(unsigned long tgafb_init(unsigned long mem_start))
fb_var.xres = fb_var.xres_virtual = 640;
fb_var.yres = fb_var.yres_virtual = 480;
fb_fix.line_length = 80*fb_var.bits_per_pixel;
- fb_fix.smem_start = (char *)(tga_fb_base + LCA_DENSE_MEM);
+ fb_fix.smem_start = (char *)__pa(tga_fb_base + dense_mem(tga_fb_base));
fb_fix.smem_len = fb_fix.line_length*fb_var.yres;
fb_fix.type = FB_TYPE_PACKED_PIXELS;
fb_fix.type_aux = 0;
- fb_fix.mmio_start = (unsigned char *)tga_regs_base;
+ fb_fix.mmio_start = (char *)__pa(tga_regs_base);
fb_fix.mmio_len = 0x1000; /* Is this sufficient? */
+ fb_fix.accel = FB_ACCEL_DEC_TGA;
fb_var.xoffset = fb_var.yoffset = 0;
fb_var.grayscale = 0;
@@ -714,7 +714,7 @@ __initfunc(unsigned long tgafb_init(unsigned long mem_start))
fb_var.nonstd = 0;
fb_var.activate = 0;
fb_var.height = fb_var.width = -1;
- fb_var.accel = FB_ACCEL_TGA;
+ fb_var.accel_flags = 0;
fb_var.pixclock = 39722;
fb_var.left_margin = 40;
fb_var.right_margin = 24;
@@ -729,7 +729,7 @@ __initfunc(unsigned long tgafb_init(unsigned long mem_start))
disp.cmap.start = 0;
disp.cmap.len = 0;
disp.cmap.red = disp.cmap.green = disp.cmap.blue = disp.cmap.transp = NULL;
- disp.screen_base = fb_fix.smem_start;
+ disp.screen_base = (char *)tga_fb_base + dense_mem(tga_fb_base);
disp.visual = fb_fix.visual;
disp.type = fb_fix.type;
disp.type_aux = fb_fix.type_aux;
@@ -739,12 +739,12 @@ __initfunc(unsigned long tgafb_init(unsigned long mem_start))
disp.can_soft_blank = 1;
disp.inverse = 0;
switch (tga_type) {
-#ifdef CONFIG_FBCON_CFB8
+#ifdef FBCON_HAS_CFB8
case 0: /* 8-plane */
disp.dispsw = &fbcon_cfb8;
break;
#endif
-#ifdef CONFIG_FBCON_CFB32
+#ifdef FBCON_HAS_CFB32
case 1: /* 24-plane */
case 3: /* 24plusZ */
disp.dispsw = &fbcon_cfb32;
@@ -753,6 +753,7 @@ __initfunc(unsigned long tgafb_init(unsigned long mem_start))
default:
disp.dispsw = NULL;
}
+ disp.scrollmode = SCROLL_YREDRAW;
strcpy(fb_info.modename, fb_fix.id);
fb_info.node = -1;
@@ -764,15 +765,13 @@ __initfunc(unsigned long tgafb_init(unsigned long mem_start))
fb_info.updatevar = &tgafbcon_updatevar;
fb_info.blank = &tgafbcon_blank;
- err = register_framebuffer(&fb_info);
- if (err < 0)
- return mem_start;
-
tgafb_set_var(&fb_var, -1, &fb_info);
+ if (register_framebuffer(&fb_info) < 0)
+ return;
+
printk("fb%d: %s frame buffer device\n", GET_FB_IDX(fb_info.node),
fb_fix.id);
- return mem_start;
}
@@ -840,10 +839,10 @@ static int tgafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
palette[regno].green = green;
palette[regno].blue = blue;
-#ifdef CONFIG_FBCON_CFB32
+#ifdef FBCON_HAS_CFB32
if (regno < 16 && tga_type != 0)
fbcon_cfb32_cmap[regno] = (red << 16) | (green << 8) | blue;
-#endif /* CONFIG_FBCON_CFB32 */
+#endif
/* How to set a single color register?? */
@@ -927,9 +926,6 @@ set_cursor(int currcons)
if (currcons != fg_console || console_blanked || vcmode == KD_GRAPHICS)
return;
- if (__real_origin != __origin)
- __set_origin(__real_origin);
-
save_flags(flags); cli();
if (deccm) {
diff --git a/drivers/video/txtcon.c b/drivers/video/txtcon.c
deleted file mode 100644
index 83165b49b..000000000
--- a/drivers/video/txtcon.c
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * linux/drivers/video/txtcon.c -- Low level text mode based console driver
- *
- * Copyright (C) 1995 Geert Uytterhoeven
- *
- *
- * This file is currently only a skeleton, since all Amigas and Ataris have
- * bitmapped graphics.
- *
- *
- * 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/errno.h>
-#include <linux/types.h>
-#include <linux/kdev_t.h>
-#include <linux/console.h>
-
-
- /*
- * Interface used by the world
- */
-
-static unsigned long txtcon_startup(unsigned long kmem_start,
- const char **display_desc);
-static void txtcon_init(struct vc_data *conp);
-static void txtcon_deinit(struct vc_data *conp);
-static void txtcon_clear(struct vc_data *conp, int sy, int sx, int height,
- int width);
-static void txtcon_putc(struct vc_data *conp, int c, int y, int x);
-static void txtcon_putcs(struct vc_data *conp, const char *s, int count, int y,
- int x);
-static void txtcon_cursor(struct vc_data *conp, int mode);
-static void txtcon_scroll(struct vc_data *conp, int t, int b, int dir,
- int count);
-static void txtcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
- int height, int width);
-static int txtcon_switch(struct vc_data *conp);
-static int txtcon_blank(int blank);
-static int txtcon_get_font(struct vc_data *conp, int *w, int *h, char *data);
-static int txtcon_set_font(struct vc_data *conp, int w, int h, char *data);
-static int txtcon_set_palette(struct vc_data *conp, unsigned char *table);
-static int txtcon_scrolldelta(int lines);
-static int txtcon_set_mode(struct vc_data *conp, int mode);
-
-
-static unsigned long txtcon_startup(unsigned long kmem_start,
- const char **display_desc)
-{
- return kmem_start;
-}
-
-
-static void txtcon_init(struct vc_data *conp)
-{
- /* ... */
-}
-
-
-static void txtcon_deinit(struct vc_data *conp)
-{
- /* ... */
-}
-
-
-/* ====================================================================== */
-
-/* txtcon_XXX routines - interface used by the world */
-
-
-static void txtcon_clear(struct vc_data *conp, int sy, int sx, int height,
- int width)
-{
- /* ... */
-}
-
-
-static void txtcon_putc(struct vc_data *conp, int c, int y, int x)
-{
- /* ... */
-}
-
-
-static void txtcon_putcs(struct vc_data *conp, const char *s, int count, int y,
- int x)
-{
- /* ... */
-}
-
-
-static void txtcon_cursor(struct vc_data *conp, int mode)
-{
- /* ... */
-}
-
-
-static void txtcon_scroll(struct vc_data *conp, int t, int b, int dir,
- int count)
-{
- /* ... */
-}
-
-
-static void txtcon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- /* ... */
-}
-
-
-static int txtcon_switch(struct vc_data *conp)
-{
- return -ENOSYS;
-}
-
-
-static int txtcon_blank(int blank)
-{
- return -ENOSYS;
-}
-
-
-static int txtcon_get_font(struct vc_data *conp, int *w, int *h, char *data)
-{
- return -ENOSYS;
-}
-
-
-static int txtcon_set_font(struct vc_data *conp, int w, int h, char *data)
-{
- return -ENOSYS;
-}
-
-
-static int txtcon_set_palette(struct vc_data *conp, unsigned char *table)
-{
- return -ENOSYS;
-}
-
-
-static int txtcon_scrolldelta(int lines)
-{
- return -ENOSYS;
-}
-
-static int txtcon_set_mode(struct vc_data *conp, int mode)
-{
- return -ENOSYS;
-}
-
-
-/* ====================================================================== */
-
- /*
- * The console `switch' structure for the text mode based console
- */
-
-struct consw txt_con = {
- txtcon_startup,
- txtcon_init,
- txtcon_deinit,
- txtcon_clear,
- txtcon_putc,
- txtcon_putcs,
- txtcon_cursor,
- txtcon_scroll,
- txtcon_bmove,
- txtcon_switch,
- txtcon_blank,
- txtcon_get_font,
- txtcon_set_font,
- txtcon_set_palette,
- txtcon_scrolldelta,
- txtcon_set_mode
-};
diff --git a/drivers/video/vesafb.c b/drivers/video/vesafb.c
new file mode 100644
index 000000000..cf1534a9a
--- /dev/null
+++ b/drivers/video/vesafb.c
@@ -0,0 +1,478 @@
+/*
+ * framebuffer driver for VBE 2.0 compliant graphic boards
+ *
+ * switching to graphics mode happens at boot time (while
+ * running in real mode, see arch/i386/video.S).
+ *
+ * (c) 1998 Gerd Knorr <kraxel@cs.tu-berlin.de>
+ *
+ */
+
+#include <linux/module.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/delay.h>
+#include <linux/fb.h>
+#include <linux/console.h>
+#include <linux/selection.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+
+#include "fbcon.h"
+#include "fbcon-cfb8.h"
+#include "fbcon-cfb16.h"
+#include "fbcon-cfb32.h"
+
+#define dac_reg (0x3c8)
+#define dac_val (0x3c9)
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * card parameters
+ */
+
+/* card */
+char *video_base;
+int video_size;
+char *video_vbase; /* mapped */
+
+/* mode */
+int video_bpp;
+int video_width;
+int video_height;
+int video_type = FB_TYPE_PACKED_PIXELS;
+int video_visual;
+int video_linelength;
+int video_cmap_len;
+
+/* --------------------------------------------------------------------- */
+
+static struct fb_var_screeninfo vesafb_defined = {
+ 0,0,0,0, /* W,H, W, H (virtual) load xres,xres_virtual*/
+ 0,0, /* virtual -> visible no offset */
+ 8, /* depth -> load bits_per_pixel */
+ 0, /* greyscale ? */
+ {0,0,0}, /* R */
+ {0,0,0}, /* G */
+ {0,0,0}, /* B */
+ {0,0,0}, /* transparency */
+ 0, /* standard pixel format */
+ FB_ACTIVATE_NOW,
+ -1,-1,
+ 0,
+ 0L,0L,0L,0L,0L,
+ 0L,0L,0, /* No sync info */
+ FB_VMODE_NONINTERLACED,
+ {0,0,0,0,0,0}
+};
+
+static struct display disp;
+static struct fb_info fb_info;
+static struct { u_char red, green, blue, pad; } palette[256];
+
+static int inverse = 0;
+
+static int currcon = 0;
+
+/* --------------------------------------------------------------------- */
+/* speed up scrolling */
+
+#define USE_REDRAW 1
+#define USE_MEMMOVE 2
+
+static int vesafb_scroll = USE_REDRAW;
+static struct display_switch vesafb_sw;
+
+/* --------------------------------------------------------------------- */
+
+ /*
+ * Open/Release the frame buffer device
+ */
+
+static int vesafb_open(struct fb_info *info, int user)
+{
+ /*
+ * Nothing, only a usage count for the moment
+ */
+ MOD_INC_USE_COUNT;
+ return(0);
+}
+
+static int vesafb_release(struct fb_info *info, int user)
+{
+ MOD_DEC_USE_COUNT;
+ return(0);
+}
+
+static int fb_update_var(int con, struct fb_info *info)
+{
+ return 0;
+}
+
+static int vesafb_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info)
+{
+ memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+ strcpy(fix->id,"VESA VGA");
+
+ fix->smem_start=(char *) video_base;
+ fix->smem_len=video_size;
+ fix->type = video_type;
+ fix->visual = video_visual;
+ fix->xpanstep=0;
+ fix->ypanstep=0;
+ fix->ywrapstep=0;
+ fix->line_length=video_linelength;
+ return 0;
+}
+
+static int vesafb_get_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ if(con==-1)
+ memcpy(var, &vesafb_defined, sizeof(struct fb_var_screeninfo));
+ else
+ *var=fb_display[con].var;
+ return 0;
+}
+
+static void vesafb_set_disp(int con)
+{
+ struct fb_fix_screeninfo fix;
+ struct display *display;
+ struct display_switch *sw;
+
+ if (con >= 0)
+ display = &fb_display[con];
+ else
+ display = &disp; /* used during initialization */
+
+ vesafb_get_fix(&fix, con, 0);
+
+ memset(display, 0, sizeof(struct display));
+ display->screen_base = video_vbase;
+ display->visual = fix.visual;
+ display->type = fix.type;
+ display->type_aux = fix.type_aux;
+ display->ypanstep = fix.ypanstep;
+ display->ywrapstep = fix.ywrapstep;
+ display->line_length = fix.line_length;
+ display->next_line = fix.line_length;
+ display->can_soft_blank = 0;
+ display->inverse = inverse;
+ vesafb_get_var(&display->var, -1, &fb_info);
+
+ switch (video_bpp) {
+#ifdef FBCON_HAS_CFB8
+ case 8:
+ sw = &fbcon_cfb8;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB16
+ case 15:
+ case 16:
+ sw = &fbcon_cfb16;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB32
+ case 32:
+ sw = &fbcon_cfb32;
+ break;
+#endif
+ default:
+ return;
+ }
+ memcpy(&vesafb_sw, sw, sizeof(*sw));
+ display->dispsw = &vesafb_sw;
+ if (vesafb_scroll == USE_REDRAW) {
+ display->scrollmode = SCROLL_YREDRAW;
+ vesafb_sw.bmove = fbcon_redraw_bmove;
+ }
+}
+
+static int vesafb_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ memcpy(var, &vesafb_defined, sizeof(struct fb_var_screeninfo));
+ return 0;
+}
+
+static int vesa_getcolreg(unsigned regno, unsigned *red, unsigned *green,
+ unsigned *blue, unsigned *transp,
+ struct fb_info *fb_info)
+{
+ /*
+ * Read a single color register and split it into colors/transparent.
+ * Return != 0 for invalid regno.
+ */
+
+ if (regno >= video_cmap_len)
+ return 1;
+
+ *red = palette[regno].red;
+ *green = palette[regno].green;
+ *blue = palette[regno].blue;
+ return 0;
+}
+
+static int vesa_setcolreg(unsigned regno, unsigned red, unsigned green,
+ unsigned blue, unsigned transp,
+ struct fb_info *fb_info)
+{
+ /*
+ * Set a single color register. The values supplied are
+ * already rounded down to the hardware's capabilities
+ * (according to the entries in the `var' structure). Return
+ * != 0 for invalid regno.
+ */
+
+ if (regno >= video_cmap_len)
+ return 1;
+
+ palette[regno].red = red;
+ palette[regno].green = green;
+ palette[regno].blue = blue;
+
+ switch (video_bpp) {
+#ifdef FBCON_HAS_CFB8
+ case 8:
+ /* Hmm, can we do it _always_ this way ??? */
+ outb_p(regno, dac_reg);
+ outb_p(red, dac_val);
+ outb_p(green, dac_val);
+ outb_p(blue, dac_val);
+ break;
+#endif
+#ifdef FBCON_HAS_CFB16
+ case 15:
+ case 16:
+ fbcon_cfb16_cmap[regno] =
+ (red << vesafb_defined.red.offset) | (green << 5) | blue;
+ break;
+#endif
+#ifdef FBCON_HAS_CFB24
+ case 24:
+ /* FIXME: todo */
+ break;
+#endif
+#ifdef FBCON_HAS_CFB32
+ case 32:
+ fbcon_cfb32_cmap[regno] =
+ (red << vesafb_defined.red.offset) |
+ (green << vesafb_defined.green.offset) |
+ (blue << vesafb_defined.blue.offset);
+ break;
+#endif
+ }
+ return 0;
+}
+
+static void do_install_cmap(int con, struct fb_info *info)
+{
+ if (con != currcon)
+ return;
+ if (fb_display[con].cmap.len)
+ fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
+ vesa_setcolreg, info);
+ else
+ fb_set_cmap(fb_default_cmap(video_cmap_len),
+ &fb_display[con].var, 1, vesa_setcolreg,
+ info);
+}
+
+static int vesafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ if (con == currcon) /* current console? */
+ return fb_get_cmap(cmap, &fb_display[con].var, kspc, vesa_getcolreg, info);
+ else if (fb_display[con].cmap.len) /* non default colormap? */
+ fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+ else
+ fb_copy_cmap(fb_default_cmap(video_cmap_len),
+ cmap, kspc ? 0 : 2);
+ return 0;
+}
+
+static int vesafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ int err;
+
+ if (!fb_display[con].cmap.len) { /* no colormap allocated? */
+ err = fb_alloc_cmap(&fb_display[con].cmap,video_cmap_len,0);
+ if (err)
+ return err;
+ }
+ if (con == currcon) /* current console? */
+ return fb_set_cmap(cmap, &fb_display[con].var, kspc, vesa_setcolreg, info);
+ else
+ fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+ return 0;
+}
+
+static int vesafb_pan_display(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ /* no panning */
+ return -EINVAL;
+}
+
+static int vesafb_ioctl(struct inode *inode, struct file *file,
+ unsigned int cmd, unsigned long arg, int con,
+ struct fb_info *info)
+{
+ return -EINVAL;
+}
+
+static struct fb_ops vesafb_ops = {
+ vesafb_open,
+ vesafb_release,
+ vesafb_get_fix,
+ vesafb_get_var,
+ vesafb_set_var,
+ vesafb_get_cmap,
+ vesafb_set_cmap,
+ vesafb_pan_display,
+ vesafb_ioctl
+};
+
+void vesafb_setup(char *options, int *ints)
+{
+ char *this_opt;
+
+ fb_info.fontname[0] = '\0';
+
+ if (!options || !*options)
+ return;
+
+ for(this_opt=strtok(options,","); this_opt; this_opt=strtok(NULL,",")) {
+ if (!*this_opt) continue;
+
+ printk("vesafb_setup: option %s\n", this_opt);
+
+ if (! strcmp(this_opt, "inverse"))
+ inverse=1;
+ else if (! strcmp(this_opt, "redraw"))
+ vesafb_scroll = USE_REDRAW;
+ else if (! strcmp(this_opt, "memmove"))
+ vesafb_scroll = USE_MEMMOVE;
+ else if (!strncmp(this_opt, "font:", 5))
+ strcpy(fb_info.fontname, this_opt+5);
+ }
+}
+
+static int vesafb_switch(int con, struct fb_info *info)
+{
+ /* Do we have to save the colormap? */
+ if (fb_display[currcon].cmap.len)
+ fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1,
+ vesa_getcolreg, info);
+
+ currcon = con;
+ /* Install new colormap */
+ do_install_cmap(con, info);
+ return 0;
+}
+
+/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
+
+static void vesafb_blank(int blank, struct fb_info *info)
+{
+ /* Not supported */
+}
+
+__initfunc(void vesafb_init(void))
+{
+ int i,j;
+
+ if (screen_info.orig_video_isVGA != VIDEO_TYPE_VLFB)
+ return;
+
+ video_base = (char*)screen_info.lfb_base;
+ video_bpp = screen_info.lfb_depth;
+ video_width = screen_info.lfb_width;
+ video_height = screen_info.lfb_height;
+ video_linelength = screen_info.lfb_linelength;
+ video_size = video_linelength * video_height /* screen_info.lfb_size */;
+ video_visual = (video_bpp == 8) ?
+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
+ video_vbase = ioremap((unsigned long)video_base, video_size);
+
+ printk("vesafb: %dx%dx%d, linelength=%d\n",
+ video_width, video_height, video_bpp, video_linelength);
+ printk("vesafb: framebuffer at 0x%p, mapped to 0x%p, size %d\n",
+ video_base, video_vbase, video_size);
+ if (vesafb_scroll == USE_REDRAW) printk("vesafb: scrolling=redraw\n");
+ if (vesafb_scroll == USE_MEMMOVE) printk("vesafb: scrolling=memmove\n");
+
+ vesafb_defined.xres=video_width;
+ vesafb_defined.yres=video_height;
+ vesafb_defined.xres_virtual=video_width;
+ vesafb_defined.yres_virtual=video_height;
+ vesafb_defined.bits_per_pixel=video_bpp;
+
+ if (video_bpp > 8) {
+ vesafb_defined.red.offset = screen_info.red_pos;
+ vesafb_defined.red.length = screen_info.red_size;
+ vesafb_defined.green.offset = screen_info.green_pos;
+ vesafb_defined.green.length = screen_info.green_size;
+ vesafb_defined.blue.offset = screen_info.blue_pos;
+ 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: "
+ "size=%d:%d:%d:%d, shift=%d:%d:%d:%d\n",
+ screen_info.rsvd_size,
+ screen_info.red_size,
+ screen_info.green_size,
+ screen_info.blue_size,
+ screen_info.rsvd_pos,
+ screen_info.red_pos,
+ screen_info.green_pos,
+ screen_info.blue_pos);
+ video_cmap_len = 16;
+ } else {
+ vesafb_defined.red.length = 6;
+ vesafb_defined.green.length = 6;
+ vesafb_defined.blue.length = 6;
+ for(i = 0; i < 16; i++) {
+ j = color_table[i];
+ palette[i].red = default_red[j];
+ palette[i].green = default_grn[j];
+ palette[i].blue = default_blu[j];
+ }
+ video_cmap_len = 256;
+ }
+ request_region(0x3c0, 32, "vga+");
+
+ strcpy(fb_info.modename, "VESA VGA");
+ fb_info.changevar = NULL;
+ fb_info.node = -1;
+ fb_info.fbops = &vesafb_ops;
+ fb_info.disp=&disp;
+ fb_info.switch_con=&vesafb_switch;
+ fb_info.updatevar=&fb_update_var;
+ fb_info.blank=&vesafb_blank;
+ vesafb_set_disp(-1);
+
+ if (register_framebuffer(&fb_info)<0)
+ return;
+
+ printk("fb%d: %s frame buffer device\n",
+ GET_FB_IDX(fb_info.node), fb_info.modename);
+}
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-basic-offset: 8
+ * End:
+ */
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index eea430ffa..f2bc39cd0 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -8,7 +8,6 @@
* more details.
*/
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -56,7 +55,7 @@ static struct fb_var_screeninfo vfb_default = {
/* 640x480, 8 bpp */
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, 20000, 64, 64, 32, 32, 64, 2,
+ 0, 0, -1, -1, 0, 20000, 64, 64, 32, 32, 64, 2,
0, FB_VMODE_NONINTERLACED
};
@@ -69,8 +68,8 @@ static int vfb_enable = 0; /* disabled by default */
void vfb_setup(char *options, int *ints);
-static int vfb_open(struct fb_info *info);
-static int vfb_release(struct fb_info *info);
+static int vfb_open(struct fb_info *info, int user);
+static int vfb_release(struct fb_info *info, int user);
static int vfb_get_fix(struct fb_fix_screeninfo *fix, int con,
struct fb_info *info);
static int vfb_get_var(struct fb_var_screeninfo *var, int con,
@@ -91,7 +90,7 @@ static int vfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
* Interface to the low level console driver
*/
-unsigned long vfb_init(unsigned long mem_start);
+void 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);
@@ -114,7 +113,7 @@ static void do_install_cmap(int con, struct fb_info *info);
static struct fb_ops vfb_ops = {
vfb_open, vfb_release, vfb_get_fix, vfb_get_var, vfb_set_var, vfb_get_cmap,
- vfb_set_cmap, vfb_pan_display, NULL, vfb_ioctl
+ vfb_set_cmap, vfb_pan_display, vfb_ioctl
};
@@ -122,7 +121,7 @@ static struct fb_ops vfb_ops = {
* Open/Release the frame buffer device
*/
-static int vfb_open(struct fb_info *info)
+static int vfb_open(struct fb_info *info, int user)
{
/*
* Nothing, only a usage count for the moment
@@ -132,7 +131,7 @@ static int vfb_open(struct fb_info *info)
return(0);
}
-static int vfb_release(struct fb_info *info)
+static int vfb_release(struct fb_info *info, int user)
{
MOD_DEC_USE_COUNT;
return(0);
@@ -250,7 +249,7 @@ static int vfb_set_var(struct fb_var_screeninfo *var, int con,
struct fb_fix_screeninfo fix;
vfb_encode_fix(&fix, var);
- display->screen_base = (u_char *)fix.smem_start;
+ display->screen_base = (char *)videomemory;
display->visual = fix.visual;
display->type = fix.type;
display->type_aux = fix.type_aux;
@@ -260,37 +259,37 @@ static int vfb_set_var(struct fb_var_screeninfo *var, int con,
display->can_soft_blank = 1;
display->inverse = 0;
switch (var->bits_per_pixel) {
-#ifdef CONFIG_FBCON_MFB
+#ifdef FBCON_HAS_MFB
case 1:
display->dispsw = &fbcon_mfb;
break;
#endif
-#ifdef CONFIG_FBCON_CFB2
+#ifdef FBCON_HAS_CFB2
case 2:
display->dispsw = &fbcon_cfb2;
break;
#endif
-#ifdef CONFIG_FBCON_CFB4
+#ifdef FBCON_HAS_CFB4
case 4:
display->dispsw = &fbcon_cfb4;
break;
#endif
-#ifdef CONFIG_FBCON_CFB8
+#ifdef FBCON_HAS_CFB8
case 8:
display->dispsw = &fbcon_cfb8;
break;
#endif
-#ifdef CONFIG_FBCON_CFB16
+#ifdef FBCON_HAS_CFB16
case 16:
display->dispsw = &fbcon_cfb16;
break;
#endif
-#ifdef CONFIG_FBCON_CFB24
+#ifdef FBCON_HAS_CFB24
case 24:
display->dispsw = &fbcon_cfb24;
break;
#endif
-#ifdef CONFIG_FBCON_CFB32
+#ifdef FBCON_HAS_CFB32
case 32:
display->dispsw = &fbcon_cfb32;
break;
@@ -417,21 +416,13 @@ __initfunc(void vfb_setup(char *options, int *ints))
* Initialisation
*/
-__initfunc(unsigned long vfb_init(unsigned long mem_start))
+__initfunc(void vfb_init(void))
{
- int err;
-
if (!vfb_enable)
- return mem_start;
-
- if (mem_start) {
- videomemory = mem_start;
- mem_start += videomemorysize;
- } else
- videomemory = (u_long)vmalloc(videomemorysize);
+ return;
- if (!videomemory)
- return mem_start;
+ if (!(videomemory = (u_long)vmalloc(videomemorysize)))
+ return;
strcpy(fb_info.modename, vfb_name);
fb_info.changevar = NULL;
@@ -442,15 +433,15 @@ __initfunc(unsigned long vfb_init(unsigned long mem_start))
fb_info.updatevar = &vfbcon_updatevar;
fb_info.blank = &vfbcon_blank;
- err = register_framebuffer(&fb_info);
- if (err < 0)
- return mem_start;
-
vfb_set_var(&vfb_default, -1, &fb_info);
+ if (register_framebuffer(&fb_info) < 0) {
+ vfree((void *)videomemory);
+ return;
+ }
+
printk("fb%d: Virtual frame buffer device, using %ldK of video memory\n",
GET_FB_IDX(fb_info.node), videomemorysize>>10);
- return mem_start;
}
@@ -501,7 +492,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 = (caddr_t)videomemory;
+ fix->smem_start = (char *)videomemory;
fix->smem_len = videomemorysize;
fix->type = FB_TYPE_PACKED_PIXELS;
fix->type_aux = 0;
@@ -629,13 +620,14 @@ static void do_install_cmap(int con, struct fb_info *info)
#ifdef MODULE
int init_module(void)
{
- return(vfb_init(NULL));
+ vfb_init();
+ return 0;
}
void cleanup_module(void)
{
unregister_framebuffer(&fb_info);
- vfree(videomemory);
+ vfree((void *)videomemory);
}
#endif /* MODULE */
diff --git a/drivers/video/vgacon.c b/drivers/video/vgacon.c
index 623ea799d..a464d389a 100644
--- a/drivers/video/vgacon.c
+++ b/drivers/video/vgacon.c
@@ -3,6 +3,8 @@
*
* Created 28 Sep 1997 by Geert Uytterhoeven
*
+ * Rewritten by Martin Mares <mj@ucw.cz>, July 1998
+ *
* This file is based on the old console.c, vga.c and vesa_blank.c drivers.
*
* Copyright (C) 1991, 1992 Linus Torvalds
@@ -31,20 +33,7 @@
* more details.
*/
-
-
-
-/* KNOWN PROBLEMS/TO DO ===================================================== *
- *
- * - monochrome attribute encoding (convert abscon <-> VGA style)
- *
- * - speed up scrolling by changing the screen origin
- *
- * - add support for palette, loadable fonts and VESA blanking
- *
- * KNOWN PROBLEMS/TO DO ==================================================== */
-
-
+#include <linux/config.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/fs.h>
@@ -61,8 +50,6 @@
#include <linux/init.h>
#include <asm/io.h>
-#include <asm/uaccess.h>
-#include <asm/linux_logo.h>
#define BLANK 0x0020
@@ -70,121 +57,76 @@
#define CAN_LOAD_EGA_FONTS /* undefine if the user must not do this */
#define CAN_LOAD_PALETTE /* undefine if the user must not do this */
-#define dac_reg (0x3c8)
-#define dac_val (0x3c9)
-
-#ifdef __powerpc__
-#define VGA_OFFSET _ISA_MEM_BASE;
-#else
-#define VGA_OFFSET 0x0
-#endif
-
-
-/*
- * Interface used by the world
+/* You really do _NOT_ want to define this, unless you have buggy
+ * Trident VGA which will resize cursor when moving it between column
+ * 15 & 16. If you define this and your VGA is OK, inverse bug will
+ * appear.
*/
+#undef TRIDENT_GLITCH
-static unsigned long vgacon_startup(unsigned long kmem_start,
- const char **display_desc);
-static void vgacon_init(struct vc_data *conp);
-static void vgacon_deinit(struct vc_data *conp);
-static void vgacon_clear(struct vc_data *conp, int sy, int sx, int height,
- int width);
-static void vgacon_putc(struct vc_data *conp, int c, int ypos, int xpos);
-static void vgacon_putcs(struct vc_data *conp, const char *s, int count,
- int ypos, int xpos);
-static void vgacon_cursor(struct vc_data *conp, int mode);
-static void vgacon_scroll(struct vc_data *conp, int t, int b, int dir,
- int count);
-static void vgacon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
- int height, int width);
-static int vgacon_switch(struct vc_data *conp);
-static int vgacon_blank(int blank);
-static int vgacon_get_font(struct vc_data *conp, int *w, int *h, char *data);
-static int vgacon_set_font(struct vc_data *conp, int w, int h, char *data);
-static int vgacon_set_palette(struct vc_data *conp, unsigned char *table);
-static int vgacon_scrolldelta(int lines);
-static int vgacon_set_mode(struct vc_data *conp, int mode);
+#undef VGA_CAN_DO_64KB
+#define dac_reg 0x3c8
+#define dac_val 0x3c9
+#define attrib_port 0x3c0
+#define seq_port_reg 0x3c4
+#define seq_port_val 0x3c5
+#define gr_port_reg 0x3ce
+#define gr_port_val 0x3cf
+#define video_misc_rd 0x3cc
+#define video_misc_wr 0x3c2
/*
- * Internal routines
+ * Interface used by the world
*/
-static int vgacon_show_logo(void);
+static const char *vgacon_startup(void);
+static void vgacon_init(struct vc_data *c, int init);
+static void vgacon_deinit(struct vc_data *c);
+static void vgacon_cursor(struct vc_data *c, int mode);
+static int vgacon_switch(struct vc_data *c);
+static int vgacon_blank(struct vc_data *c, int blank);
+static int vgacon_font_op(struct vc_data *c, struct console_font_op *op);
+static int vgacon_set_palette(struct vc_data *c, unsigned char *table);
+static int vgacon_scrolldelta(struct vc_data *c, int lines);
+static int vgacon_set_origin(struct vc_data *c);
+static void vgacon_save_screen(struct vc_data *c);
+static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, int lines);
+static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, u8 blink, u8 underline, u8 reverse);
+static void vgacon_invert_region(struct vc_data *c, u16 *p, int count);
+static unsigned long vgacon_uni_pagedir[2];
/* Description of the hardware situation */
-static unsigned long vga_video_mem_base; /* Base of video memory */
-static unsigned long vga_video_mem_term; /* End of video memory */
-static unsigned short vga_video_port_reg; /* Video register select port */
-static unsigned short vga_video_port_val; /* Video register value port */
-static unsigned long vga_video_num_columns; /* Number of text columns */
-static unsigned long vga_video_num_lines; /* Number of text lines */
-static unsigned long vga_video_size_row;
-static unsigned long vga_video_screen_size;
-
-static int vga_can_do_color = 0;
-static unsigned long vga_default_font_height; /* Height of default screen font */
-
-static unsigned char vga_video_type;
-static unsigned char vga_has_wrapped; /* all of videomem is data of fg_console */
-static unsigned char vga_hardscroll_enabled;
-static unsigned char vga_hardscroll_disabled_by_init = 0;
-
-
-
- /*
- * VGA screen access
- */
-
-static inline void vga_writew(unsigned short val, unsigned short * addr)
-{
-#ifdef __powerpc__
- st_le16(addr, val);
-#else
- writew(val, (unsigned long) addr);
-#endif /* !__powerpc__ */
-}
-
-static inline unsigned short vga_readw(unsigned short * addr)
-{
-#ifdef __powerpc__
- return ld_le16(addr);
-#else
- return readw((unsigned long) addr);
-#endif /* !__powerpc__ */
-}
-
-static inline void vga_memsetw(void * s, unsigned short c, unsigned int count)
+static unsigned long vga_vram_base; /* Base of video memory */
+static unsigned long vga_vram_end; /* End of video memory */
+static u16 vga_video_port_reg; /* Video register select port */
+static u16 vga_video_port_val; /* Video register value port */
+static unsigned int vga_video_num_columns; /* Number of text columns */
+static unsigned int vga_video_num_lines; /* Number of text lines */
+static int vga_can_do_color = 0; /* Do we support colors? */
+static unsigned int vga_default_font_height; /* Height of default screen font */
+static unsigned char vga_video_type; /* Card type */
+static unsigned char vga_hardscroll_enabled;
+static unsigned char vga_hardscroll_user_enable = 1;
+static unsigned char vga_font_is_default = 1;
+static int vga_vesa_blanked;
+static int vga_palette_blanked;
+static int vga_is_gfx;
+static int vga_512_chars;
+static int vga_video_font_height;
+
+
+void no_scroll(char *str, int *ints)
{
- unsigned short * addr = (unsigned short *) s;
-
- while (count) {
- count--;
- vga_writew(c, addr++);
- }
-}
-
-static inline void vga_memmovew(unsigned short *to, unsigned short *from,
- unsigned int count)
-{
- if (to < from) {
- while (count) {
- count--;
- vga_writew(vga_readw(from++), to++);
- }
- } else {
- from += count;
- to += count;
- while (count) {
- count--;
- vga_writew(vga_readw(--from), --to);
- }
- }
+ /*
+ * Disabling scrollback is required for the Braillex ib80-piezo
+ * Braille reader made by F.H. Papenmeier (Germany).
+ * Use the "no-scroll" bootflag.
+ */
+ vga_hardscroll_user_enable = vga_hardscroll_enabled = 0;
}
-
/*
* 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
@@ -209,58 +151,67 @@ static inline void write_vga(unsigned char reg, unsigned int val)
#endif
}
-
-__initfunc(static unsigned long vgacon_startup(unsigned long kmem_start,
- const char **display_desc))
+__initfunc(static const char *vgacon_startup(void))
{
- unsigned short saved;
- unsigned short *p;
+ const char *display_desc = NULL;
+ u16 saved;
+ u16 *p;
+
+ if (ORIG_VIDEO_ISVGA == VIDEO_TYPE_VLFB) {
+ no_vga:
+#ifdef CONFIG_DUMMY_CONSOLE
+ conswitchp = &dummy_con;
+ return conswitchp->con_startup();
+#else
+ return NULL;
+#endif
+ }
+
vga_video_num_lines = ORIG_VIDEO_LINES;
vga_video_num_columns = ORIG_VIDEO_COLS;
- vga_video_size_row = 2 * ORIG_VIDEO_COLS;
- vga_video_screen_size = vga_video_num_lines * vga_video_size_row;
if (ORIG_VIDEO_MODE == 7) /* Is this a monochrome display? */
{
- vga_video_mem_base = 0xb0000 + VGA_OFFSET;
+ vga_vram_base = 0xb0000;
vga_video_port_reg = 0x3b4;
vga_video_port_val = 0x3b5;
if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
{
vga_video_type = VIDEO_TYPE_EGAM;
- vga_video_mem_term = 0xb8000 + VGA_OFFSET;
- *display_desc = "EGA+";
+ vga_vram_end = 0xb8000;
+ display_desc = "EGA+";
request_region(0x3b0,16,"ega");
}
else
{
vga_video_type = VIDEO_TYPE_MDA;
- vga_video_mem_term = 0xb2000 + VGA_OFFSET;
- *display_desc = "*MDA";
+ vga_vram_end = 0xb2000;
+ display_desc = "*MDA";
request_region(0x3b0,12,"mda");
request_region(0x3bf, 1,"mda");
+ vga_video_font_height = 16;
}
}
else /* If not, it is color. */
{
vga_can_do_color = 1;
- vga_video_mem_base = 0xb8000 + VGA_OFFSET;
- vga_video_port_reg = 0x3d4;
- vga_video_port_val = 0x3d5;
+ vga_vram_base = 0xb8000;
+ vga_video_port_reg = 0x3d4;
+ vga_video_port_val = 0x3d5;
if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10)
{
- int i ;
+ int i;
- vga_video_mem_term = 0xc0000 + VGA_OFFSET;
+ vga_vram_end = 0xc0000;
if (!ORIG_VIDEO_ISVGA) {
vga_video_type = VIDEO_TYPE_EGAC;
- *display_desc = "EGA";
+ display_desc = "EGA";
request_region(0x3c0,32,"ega");
} else {
vga_video_type = VIDEO_TYPE_VGAC;
- *display_desc = "VGA+";
+ display_desc = "VGA+";
request_region(0x3c0,32,"vga+");
#ifdef VGA_CAN_DO_64KB
@@ -270,8 +221,8 @@ __initfunc(static unsigned long vgacon_startup(unsigned long kmem_start,
* controllers (it seems like setting MM=01
* and COE=1 isn't necessarily a good idea)
*/
- vga_video_mem_base = 0xa0000 + VGA_OFFSET;
- vga_video_mem_term = 0xb0000 + VGA_OFFSET;
+ vga_vram_base = 0xa0000;
+ vga_vram_end = 0xb0000;
outb_p (6, 0x3ce) ;
outb_p (6, 0x3cf) ;
#endif
@@ -303,287 +254,764 @@ __initfunc(static unsigned long vgacon_startup(unsigned long kmem_start,
else
{
vga_video_type = VIDEO_TYPE_CGA;
- vga_video_mem_term = 0xba000 + VGA_OFFSET;
- *display_desc = "*CGA";
+ vga_vram_end = 0xba000;
+ display_desc = "*CGA";
request_region(0x3d4,2,"cga");
+ vga_video_font_height = 8;
}
}
+ vga_vram_base = VGA_MAP_MEM(vga_vram_base);
+ vga_vram_end = VGA_MAP_MEM(vga_vram_end);
/*
* Find out if there is a graphics card present.
* Are there smarter methods around?
*/
- p = (unsigned short *)vga_video_mem_base;
- saved = vga_readw(p);
- vga_writew(0xAA55, p);
- if (vga_readw(p) != 0xAA55) {
- vga_writew(saved, p);
- return kmem_start;
+ p = (u16 *)vga_vram_base;
+ saved = scr_readw(p);
+ scr_writew(0xAA55, p);
+ if (scr_readw(p) != 0xAA55) {
+ scr_writew(saved, p);
+ goto no_vga;
}
- vga_writew(0x55AA, p);
- if (vga_readw(p) != 0x55AA) {
- vga_writew(saved, p);
- return kmem_start;
+ scr_writew(0x55AA, p);
+ if (scr_readw(p) != 0x55AA) {
+ scr_writew(saved, p);
+ goto no_vga;
}
- vga_writew(saved, p);
+ scr_writew(saved, p);
- vga_hardscroll_enabled = (vga_hardscroll_disabled_by_init ? 0 :
- (vga_video_type == VIDEO_TYPE_EGAC
+ if (vga_video_type == VIDEO_TYPE_EGAC
|| vga_video_type == VIDEO_TYPE_VGAC
- || vga_video_type == VIDEO_TYPE_EGAM));
- vga_has_wrapped = 0;
-
- if (vga_video_type == VIDEO_TYPE_VGAC
- || vga_video_type == VIDEO_TYPE_EGAC
- || vga_video_type == VIDEO_TYPE_EGAM)
- {
+ || vga_video_type == VIDEO_TYPE_EGAM) {
+ vga_hardscroll_enabled = vga_hardscroll_user_enable;
vga_default_font_height = ORIG_VIDEO_POINTS;
- video_font_height = ORIG_VIDEO_POINTS;
+ vga_video_font_height = ORIG_VIDEO_POINTS;
/* This may be suboptimal but is a safe bet - go with it */
video_scan_lines =
- video_font_height * vga_video_num_lines;
+ vga_video_font_height * vga_video_num_lines;
}
+ video_font_height = vga_video_font_height;
- if (!console_show_logo)
- console_show_logo = vgacon_show_logo;
-
- return kmem_start;
+ return display_desc;
}
+static void vgacon_init(struct vc_data *c, int init)
+{
+ unsigned long p;
+
+ /* We cannot be loaded as a module, therefore init is always 1 */
+ c->vc_can_do_color = vga_can_do_color;
+ c->vc_cols = vga_video_num_columns;
+ c->vc_rows = vga_video_num_lines;
+ c->vc_complement_mask = 0x7700;
+ p = *c->vc_uni_pagedir_loc;
+ if (c->vc_uni_pagedir_loc == &c->vc_uni_pagedir ||
+ !--c->vc_uni_pagedir_loc[1])
+ con_free_unimap(c->vc_num);
+ c->vc_uni_pagedir_loc = vgacon_uni_pagedir;
+ vgacon_uni_pagedir[1]++;
+ if (!vgacon_uni_pagedir[0] && p)
+ con_set_default_unimap(c->vc_num);
+}
-static void vgacon_init(struct vc_data *conp)
+static inline void vga_set_mem_top(struct vc_data *c)
{
- conp->vc_cols = vga_video_num_columns;
- conp->vc_rows = vga_video_num_lines;
- conp->vc_can_do_color = vga_can_do_color;
+ write_vga(12, (c->vc_visible_origin-vga_vram_base)/2);
}
-static void vgacon_deinit(struct vc_data *conp)
+static void vgacon_deinit(struct vc_data *c)
{
+ /* When closing the last console, reset video origin */
+ if (!--vgacon_uni_pagedir[1]) {
+ c->vc_visible_origin = vga_vram_base;
+ vga_set_mem_top(c);
+ con_free_unimap(c->vc_num);
+ }
+ c->vc_uni_pagedir_loc = &c->vc_uni_pagedir;
+ con_set_default_unimap(c->vc_num);
}
+static u8 vgacon_build_attr(struct vc_data *c, u8 color, u8 intensity, u8 blink, u8 underline, u8 reverse)
+{
+ u8 attr = color;
-/* ====================================================================== */
+ if (vga_can_do_color) {
+ if (underline)
+ attr = (attr & 0xf0) | c->vc_ulcolor;
+ else if (intensity == 0)
+ attr = (attr & 0xf0) | c->vc_halfcolor;
+ }
+ if (reverse)
+ attr = ((attr) & 0x88) | ((((attr) >> 4) | ((attr) << 4)) & 0x77);
+ if (blink)
+ attr ^= 0x80;
+ if (intensity == 2)
+ attr ^= 0x08;
+ if (!vga_can_do_color) {
+ if (underline)
+ attr = (attr & 0xf8) | 0x01;
+ else if (intensity == 0)
+ attr = (attr & 0xf0) | 0x08;
+ }
+ return attr;
+}
-static void vgacon_clear(struct vc_data *conp, int sy, int sx, int height,
- int width)
+static void vgacon_invert_region(struct vc_data *c, u16 *p, int count)
{
- int rows;
- unsigned long dest;
-
- if (console_blanked)
- return;
-
- dest = vga_video_mem_base + sy*vga_video_size_row + sx*2;
- if (sx == 0 && width == vga_video_num_columns)
- vga_memsetw((void *)dest, conp->vc_video_erase_char, height * width);
- else
- for (rows = height; rows-- ; dest += vga_video_size_row)
- vga_memsetw((void *)dest, conp->vc_video_erase_char, width);
-}
+ int col = vga_can_do_color;
+ while (count--) {
+ u16 a = scr_readw(p);
+ if (col)
+ a = ((a) & 0x88ff) | (((a) & 0x7000) >> 4) | (((a) & 0x0700) << 4);
+ else
+ a ^= ((a & 0x0700) == 0x0100) ? 0x7000 : 0x7700;
+ scr_writew(a, p++);
+ }
+}
-static void vgacon_putc(struct vc_data *conp, int c, int ypos, int xpos)
+static void vgacon_set_cursor_size(int xpos, int from, int to)
{
- u16 *p;
+ unsigned long flags;
+ int curs, cure;
+ static int lastfrom, lastto;
- if (console_blanked)
- return;
-
- p = (u16 *)(vga_video_mem_base+ypos*vga_video_size_row+xpos*2);
- vga_writew(conp->vc_attr << 8 | c, p);
-}
+#ifdef TRIDENT_GLITCH
+ if (xpos<16) from--, to--;
+#endif
+ if ((from == lastfrom) && (to == lastto)) return;
+ lastfrom = from; lastto = to;
-static void vgacon_putcs(struct vc_data *conp, const char *s, int count,
- int ypos, int xpos)
-{
- u16 *p;
- u16 sattr;
+ save_flags(flags); cli();
+ outb_p(0x0a, vga_video_port_reg); /* Cursor start */
+ curs = inb_p(vga_video_port_val);
+ outb_p(0x0b, vga_video_port_reg); /* Cursor end */
+ cure = inb_p(vga_video_port_val);
- if (console_blanked)
- return;
+ curs = (curs & 0xc0) | from;
+ cure = (cure & 0xe0) | to;
- p = (u16 *)(vga_video_mem_base+ypos*vga_video_size_row+xpos*2);
- sattr = conp->vc_attr << 8;
- while (count--)
- vga_writew(sattr | *s++, p++);
+ outb_p(0x0a, vga_video_port_reg); /* Cursor start */
+ outb_p(curs, vga_video_port_val);
+ outb_p(0x0b, vga_video_port_reg); /* Cursor end */
+ outb_p(cure, vga_video_port_val);
+ restore_flags(flags);
}
-
-static void vgacon_cursor(struct vc_data *conp, int mode)
+static void vgacon_cursor(struct vc_data *c, int mode)
{
+ if (c->vc_origin != c->vc_visible_origin)
+ vgacon_scrolldelta(c, 0);
switch (mode) {
case CM_ERASE:
- write_vga(14, (vga_video_mem_term - vga_video_mem_base - 1)>>1);
+ write_vga(14, (vga_vram_end - vga_vram_base - 1)/2);
break;
case CM_MOVE:
case CM_DRAW:
- write_vga(14, conp->vc_y*vga_video_num_columns+conp->vc_x);
+ write_vga(14, (c->vc_pos-vga_vram_base)/2);
+ switch (c->vc_cursor_type & 0x0f) {
+ case CUR_UNDERLINE:
+ vgacon_set_cursor_size(c->vc_x,
+ video_font_height - (video_font_height < 10 ? 2 : 3),
+ video_font_height - (video_font_height < 10 ? 1 : 2));
+ break;
+ case CUR_TWO_THIRDS:
+ vgacon_set_cursor_size(c->vc_x,
+ video_font_height / 3,
+ video_font_height - (video_font_height < 10 ? 1 : 2));
+ break;
+ case CUR_LOWER_THIRD:
+ vgacon_set_cursor_size(c->vc_x,
+ (video_font_height*2) / 3,
+ video_font_height - (video_font_height < 10 ? 1 : 2));
+ break;
+ case CUR_LOWER_HALF:
+ vgacon_set_cursor_size(c->vc_x,
+ video_font_height / 2,
+ video_font_height - (video_font_height < 10 ? 1 : 2));
+ break;
+ case CUR_NONE:
+ vgacon_set_cursor_size(c->vc_x, 31, 30);
+ break;
+ default:
+ vgacon_set_cursor_size(c->vc_x, 1, video_font_height);
+ break;
+ }
break;
}
}
+static int vgacon_switch(struct vc_data *c)
+{
+ /*
+ * We need to save screen size here as it's the only way
+ * we can spot the screen has been resized and we need to
+ * set size of freshly allocated screens ourselves.
+ */
+ vga_video_num_columns = c->vc_cols;
+ vga_video_num_lines = c->vc_rows;
+ if (vga_is_gfx)
+ return 1;
+ scr_memcpyw_to((u16 *) c->vc_origin, (u16 *) c->vc_screenbuf, c->vc_screenbuf_size);
+ return 0; /* Redrawing not needed */
+}
-static void vgacon_scroll(struct vc_data *conp, int t, int b, int dir,
- int count)
+static void vga_set_palette(struct vc_data *c, unsigned char *table)
{
- if (console_blanked)
- return;
+ int i, j ;
- vgacon_cursor(conp, CM_ERASE);
+ for (i=j=0; i<16; i++) {
+ outb_p (table[i], dac_reg) ;
+ outb_p (c->vc_palette[j++]>>2, dac_val) ;
+ outb_p (c->vc_palette[j++]>>2, dac_val) ;
+ outb_p (c->vc_palette[j++]>>2, dac_val) ;
+ }
+}
- switch (dir) {
- case SM_UP:
- if (count > conp->vc_rows) /* Maximum realistic size */
- count = conp->vc_rows;
- vgacon_bmove(conp, t+count, 0, t, 0, b-t-count, conp->vc_cols);
- vgacon_clear(conp, b-count, 0, count, conp->vc_cols);
- break;
+static int vgacon_set_palette(struct vc_data *c, unsigned char *table)
+{
+#ifdef CAN_LOAD_PALETTE
- case SM_DOWN:
- if (count > conp->vc_rows) /* Maximum realistic size */
- count = conp->vc_rows;
- /*
- * Fixed bmove() should end Arno's frustration with copying?
- * Confucius says:
- * Man who copies in wrong direction, end up with trashed
- * data
- */
- vgacon_bmove(conp, t, 0, t+count, 0, b-t-count, conp->vc_cols);
- vgacon_clear(conp, t, 0, count, conp->vc_cols);
- break;
+ if (vga_video_type != VIDEO_TYPE_VGAC || vga_palette_blanked)
+ return -EINVAL;
+ vga_set_palette(c, table);
+ return 0;
+#else
+ return -EINVAL;
+#endif
+}
- case SM_LEFT:
- vgacon_bmove(conp, 0, t+count, 0, t, conp->vc_rows, b-t-count);
- vgacon_clear(conp, 0, b-count, conp->vc_rows, count);
- break;
+/* structure holding original VGA register settings */
+static struct {
+ unsigned char SeqCtrlIndex; /* Sequencer Index reg. */
+ unsigned char CrtCtrlIndex; /* CRT-Contr. Index reg. */
+ unsigned char CrtMiscIO; /* Miscellaneous register */
+ unsigned char HorizontalTotal; /* CRT-Controller:00h */
+ unsigned char HorizDisplayEnd; /* CRT-Controller:01h */
+ unsigned char StartHorizRetrace; /* CRT-Controller:04h */
+ unsigned char EndHorizRetrace; /* CRT-Controller:05h */
+ unsigned char Overflow; /* CRT-Controller:07h */
+ unsigned char StartVertRetrace; /* CRT-Controller:10h */
+ unsigned char EndVertRetrace; /* CRT-Controller:11h */
+ unsigned char ModeControl; /* CRT-Controller:17h */
+ unsigned char ClockingMode; /* Seq-Controller:01h */
+} vga_state;
+
+static void vga_vesa_blank(int mode)
+{
+ /* save original values of VGA controller registers */
+ if(!vga_vesa_blanked) {
+ cli();
+ vga_state.SeqCtrlIndex = inb_p(seq_port_reg);
+ vga_state.CrtCtrlIndex = inb_p(vga_video_port_reg);
+ vga_state.CrtMiscIO = inb_p(video_misc_rd);
+ sti();
+
+ outb_p(0x00,vga_video_port_reg); /* HorizontalTotal */
+ vga_state.HorizontalTotal = inb_p(vga_video_port_val);
+ outb_p(0x01,vga_video_port_reg); /* HorizDisplayEnd */
+ vga_state.HorizDisplayEnd = inb_p(vga_video_port_val);
+ outb_p(0x04,vga_video_port_reg); /* StartHorizRetrace */
+ vga_state.StartHorizRetrace = inb_p(vga_video_port_val);
+ outb_p(0x05,vga_video_port_reg); /* EndHorizRetrace */
+ vga_state.EndHorizRetrace = inb_p(vga_video_port_val);
+ outb_p(0x07,vga_video_port_reg); /* Overflow */
+ vga_state.Overflow = inb_p(vga_video_port_val);
+ outb_p(0x10,vga_video_port_reg); /* StartVertRetrace */
+ vga_state.StartVertRetrace = inb_p(vga_video_port_val);
+ outb_p(0x11,vga_video_port_reg); /* EndVertRetrace */
+ vga_state.EndVertRetrace = inb_p(vga_video_port_val);
+ outb_p(0x17,vga_video_port_reg); /* ModeControl */
+ vga_state.ModeControl = inb_p(vga_video_port_val);
+ outb_p(0x01,seq_port_reg); /* ClockingMode */
+ vga_state.ClockingMode = inb_p(seq_port_val);
+ }
- case SM_RIGHT:
- vgacon_bmove(conp, 0, t, 0, t+count, conp->vc_rows, b-t-count);
- vgacon_clear(conp, 0, t, conp->vc_rows, count);
- break;
- }
-}
+ /* assure that video is enabled */
+ /* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */
+ cli();
+ outb_p(0x01,seq_port_reg);
+ outb_p(vga_state.ClockingMode | 0x20,seq_port_val);
+ /* test for vertical retrace in process.... */
+ if ((vga_state.CrtMiscIO & 0x80) == 0x80)
+ outb_p(vga_state.CrtMiscIO & 0xef,video_misc_wr);
-static void vgacon_bmove(struct vc_data *conp, int sy, int sx, int dy, int dx,
- int height, int width)
-{
- unsigned long src, dst;
- int rows;
-
- if (console_blanked)
- return;
-
- if (sx == 0 && dx == 0 && width == vga_video_num_columns) {
- src = vga_video_mem_base + sy * vga_video_size_row;
- dst = vga_video_mem_base + dy * vga_video_size_row;
- vga_memmovew((unsigned short *)dst, (unsigned short *)src,
- height * width);
- } else if (dy < sy || (dy == sy && dx < sx)) {
- src = vga_video_mem_base + sy * vga_video_size_row + sx * 2;
- dst = vga_video_mem_base + dy * vga_video_size_row + dx * 2;
- for (rows = height; rows-- ;) {
- vga_memmovew((unsigned short *)dst, (unsigned short *)src, width);
- src += vga_video_size_row;
- dst += vga_video_size_row;
+ /*
+ * Set <End of vertical retrace> to minimum (0) and
+ * <Start of vertical Retrace> to maximum (incl. overflow)
+ * Result: turn off vertical sync (VSync) pulse.
+ */
+ if (mode & VESA_VSYNC_SUSPEND) {
+ outb_p(0x10,vga_video_port_reg); /* StartVertRetrace */
+ outb_p(0xff,vga_video_port_val); /* maximum value */
+ outb_p(0x11,vga_video_port_reg); /* EndVertRetrace */
+ outb_p(0x40,vga_video_port_val); /* minimum (bits 0..3) */
+ outb_p(0x07,vga_video_port_reg); /* Overflow */
+ outb_p(vga_state.Overflow | 0x84,vga_video_port_val); /* bits 9,10 of vert. retrace */
}
- } else {
- src = vga_video_mem_base + (sy+height-1) * vga_video_size_row + sx * 2;
- dst = vga_video_mem_base + (dy+height-1) * vga_video_size_row + dx * 2;
- for (rows = height; rows-- ;) {
- vga_memmovew((unsigned short *)dst, (unsigned short *)src, width);
- src -= vga_video_size_row;
- dst -= vga_video_size_row;
+
+ if (mode & VESA_HSYNC_SUSPEND) {
+ /*
+ * Set <End of horizontal retrace> to minimum (0) and
+ * <Start of horizontal Retrace> to maximum
+ * Result: turn off horizontal sync (HSync) pulse.
+ */
+ outb_p(0x04,vga_video_port_reg); /* StartHorizRetrace */
+ outb_p(0xff,vga_video_port_val); /* maximum */
+ outb_p(0x05,vga_video_port_reg); /* EndHorizRetrace */
+ outb_p(0x00,vga_video_port_val); /* minimum (0) */
}
- }
-}
+ /* restore both index registers */
+ outb_p(vga_state.SeqCtrlIndex,seq_port_reg);
+ outb_p(vga_state.CrtCtrlIndex,vga_video_port_reg);
+ sti();
+}
-static int vgacon_switch(struct vc_data *conp)
+static void vga_vesa_unblank(void)
{
- return 0;
+ /* restore original values of VGA controller registers */
+ cli();
+ outb_p(vga_state.CrtMiscIO,video_misc_wr);
+
+ outb_p(0x00,vga_video_port_reg); /* HorizontalTotal */
+ outb_p(vga_state.HorizontalTotal,vga_video_port_val);
+ outb_p(0x01,vga_video_port_reg); /* HorizDisplayEnd */
+ outb_p(vga_state.HorizDisplayEnd,vga_video_port_val);
+ outb_p(0x04,vga_video_port_reg); /* StartHorizRetrace */
+ outb_p(vga_state.StartHorizRetrace,vga_video_port_val);
+ outb_p(0x05,vga_video_port_reg); /* EndHorizRetrace */
+ outb_p(vga_state.EndHorizRetrace,vga_video_port_val);
+ outb_p(0x07,vga_video_port_reg); /* Overflow */
+ outb_p(vga_state.Overflow,vga_video_port_val);
+ outb_p(0x10,vga_video_port_reg); /* StartVertRetrace */
+ outb_p(vga_state.StartVertRetrace,vga_video_port_val);
+ outb_p(0x11,vga_video_port_reg); /* EndVertRetrace */
+ outb_p(vga_state.EndVertRetrace,vga_video_port_val);
+ outb_p(0x17,vga_video_port_reg); /* ModeControl */
+ outb_p(vga_state.ModeControl,vga_video_port_val);
+ outb_p(0x01,seq_port_reg); /* ClockingMode */
+ outb_p(vga_state.ClockingMode,seq_port_val);
+
+ /* restore index/control registers */
+ outb_p(vga_state.SeqCtrlIndex,seq_port_reg);
+ outb_p(vga_state.CrtCtrlIndex,vga_video_port_reg);
+ sti();
}
+static void vga_pal_blank(void)
+{
+ int i;
+
+ for (i=0; i<16; i++) {
+ outb_p (i, dac_reg) ;
+ outb_p (0, dac_val) ;
+ outb_p (0, dac_val) ;
+ outb_p (0, dac_val) ;
+ }
+}
-static int vgacon_blank(int blank)
+static int vgacon_blank(struct vc_data *c, int blank)
{
- if (blank) {
- vga_memsetw((void *)vga_video_mem_base, BLANK, vga_video_screen_size/2);
- return 0;
- } else {
- /* Tell console.c that it has to restore the screen itself */
- return 1;
- }
- return 0;
+ switch (blank) {
+ case 0: /* Unblank */
+ if (vga_vesa_blanked) {
+ vga_vesa_unblank();
+ vga_vesa_blanked = 0;
+ }
+ if (vga_palette_blanked) {
+ vga_set_palette(c, color_table);
+ vga_palette_blanked = 0;
+ return 0;
+ }
+ vga_is_gfx = 0;
+ /* Tell console.c that it has to restore the screen itself */
+ return 1;
+ case 1: /* Normal blanking */
+ if (vga_video_type == VIDEO_TYPE_VGAC) {
+ vga_pal_blank();
+ vga_palette_blanked = 1;
+ return 0;
+ }
+ scr_memsetw((void *)vga_vram_base, BLANK, vc_cons[0].d->vc_screenbuf_size);
+ return 1;
+ case -1: /* Entering graphic mode */
+ scr_memsetw((void *)vga_vram_base, BLANK, vc_cons[0].d->vc_screenbuf_size);
+ vga_is_gfx = 1;
+ return 1;
+ default: /* VESA blanking */
+ if (vga_video_type == VIDEO_TYPE_VGAC) {
+ vga_vesa_blank(blank-1);
+ vga_vesa_blanked = blank;
+ }
+ return 0;
+ }
}
+/*
+ * PIO_FONT support.
+ *
+ * The font loading code goes back to the codepage package by
+ * Joel Hoffman (joel@wam.umd.edu). (He reports that the original
+ * reference is: "From: p. 307 of _Programmer's Guide to PC & PS/2
+ * Video Systems_ by Richard Wilton. 1987. Microsoft Press".)
+ *
+ * Change for certain monochrome monitors by Yury Shevchuck
+ * (sizif@botik.yaroslavl.su).
+ */
+
+#ifdef CAN_LOAD_EGA_FONTS
-static int vgacon_get_font(struct vc_data *conp, int *w, int *h, char *data)
+#define colourmap 0xa0000
+/* Pauline Middelink <middelin@polyware.iaf.nl> reports that we
+ should use 0xA0000 for the bwmap as well.. */
+#define blackwmap 0xa0000
+#define cmapsz 8192
+
+static int
+vgacon_do_font_op(char *arg, int set, int ch512)
{
- /* TODO */
- return -ENOSYS;
-}
+ int i;
+ char *charmap;
+ int beg;
+ unsigned short video_port_status = vga_video_port_reg + 6;
+ int font_select = 0x00;
+
+ if (vga_video_type != VIDEO_TYPE_EGAM) {
+ charmap = (char *)VGA_MAP_MEM(colourmap);
+ beg = 0x0e;
+#ifdef VGA_CAN_DO_64KB
+ if (vga_video_type == VIDEO_TYPE_VGAC)
+ beg = 0x06;
+#endif
+ } else {
+ charmap = (char *)VGA_MAP_MEM(blackwmap);
+ beg = 0x0a;
+ }
+
+#ifdef BROKEN_GRAPHICS_PROGRAMS
+ /*
+ * All fonts are loaded in slot 0 (0:1 for 512 ch)
+ */
+ if (!arg)
+ return -EINVAL; /* Return to default font not supported */
-static int vgacon_set_font(struct vc_data *conp, int w, int h, char *data)
+ vga_font_is_default = 0;
+ font_select = ch512 ? 0x04 : 0x00;
+#else
+ /*
+ * The default font is kept in slot 0 and is never touched.
+ * A custom font is loaded in slot 2 (256 ch) or 2:3 (512 ch)
+ */
+
+ if (set) {
+ vga_font_is_default = !arg;
+ if (!arg)
+ ch512 = 0; /* Default font is always 256 */
+ font_select = arg ? (ch512 ? 0x0e : 0x0a) : 0x00;
+ }
+
+ if ( !vga_font_is_default )
+ charmap += 4*cmapsz;
+#endif
+
+ cli();
+ outb_p( 0x00, seq_port_reg ); /* First, the sequencer */
+ outb_p( 0x01, seq_port_val ); /* Synchronous reset */
+ outb_p( 0x02, seq_port_reg );
+ outb_p( 0x04, seq_port_val ); /* CPU writes only to map 2 */
+ outb_p( 0x04, seq_port_reg );
+ outb_p( 0x07, seq_port_val ); /* Sequential addressing */
+ outb_p( 0x00, seq_port_reg );
+ outb_p( 0x03, seq_port_val ); /* Clear synchronous reset */
+
+ outb_p( 0x04, gr_port_reg ); /* Now, the graphics controller */
+ outb_p( 0x02, gr_port_val ); /* select map 2 */
+ outb_p( 0x05, gr_port_reg );
+ outb_p( 0x00, gr_port_val ); /* disable odd-even addressing */
+ outb_p( 0x06, gr_port_reg );
+ outb_p( 0x00, gr_port_val ); /* map start at A000:0000 */
+ sti();
+
+ if (arg) {
+ if (set)
+ for (i=0; i<cmapsz ; i++)
+ vga_writeb(arg[i], charmap + i);
+ else
+ for (i=0; i<cmapsz ; i++)
+ arg[i] = vga_readb(charmap + i);
+
+ /*
+ * In 512-character mode, the character map is not contiguous if
+ * we want to remain EGA compatible -- which we do
+ */
+
+ if (ch512) {
+ charmap += 2*cmapsz;
+ arg += cmapsz;
+ if (set)
+ for (i=0; i<cmapsz ; i++)
+ vga_writeb(arg[i], charmap+i);
+ else
+ for (i=0; i<cmapsz ; i++)
+ arg[i] = vga_readb(charmap+i);
+ }
+ }
+
+ cli();
+ outb_p( 0x00, seq_port_reg ); /* First, the sequencer */
+ outb_p( 0x01, seq_port_val ); /* Synchronous reset */
+ outb_p( 0x02, seq_port_reg );
+ outb_p( 0x03, seq_port_val ); /* CPU writes to maps 0 and 1 */
+ outb_p( 0x04, seq_port_reg );
+ outb_p( 0x03, seq_port_val ); /* odd-even addressing */
+ if (set) {
+ outb_p( 0x03, seq_port_reg ); /* Character Map Select */
+ outb_p( font_select, seq_port_val );
+ }
+ outb_p( 0x00, seq_port_reg );
+ outb_p( 0x03, seq_port_val ); /* clear synchronous reset */
+
+ outb_p( 0x04, gr_port_reg ); /* Now, the graphics controller */
+ outb_p( 0x00, gr_port_val ); /* select map 0 for CPU */
+ outb_p( 0x05, gr_port_reg );
+ outb_p( 0x10, gr_port_val ); /* enable even-odd addressing */
+ outb_p( 0x06, gr_port_reg );
+ outb_p( beg, gr_port_val ); /* map starts at b800:0 or b000:0 */
+
+ /* if 512 char mode is already enabled don't re-enable it. */
+ if ((set)&&(ch512!=vga_512_chars)) { /* attribute controller */
+ int i;
+ for(i=0; i<MAX_NR_CONSOLES; i++) {
+ struct vc_data *c = vc_cons[i].d;
+ if (c && c->vc_sw == &vga_con)
+ c->vc_hi_font_mask = ch512 ? 0x0800 : 0;
+ }
+ vga_512_chars=ch512;
+ /* 256-char: enable intensity bit
+ 512-char: disable intensity bit */
+ inb_p( video_port_status ); /* clear address flip-flop */
+ outb_p ( 0x12, attrib_port ); /* color plane enable register */
+ outb_p ( ch512 ? 0x07 : 0x0f, attrib_port );
+ /* Wilton (1987) mentions the following; I don't know what
+ it means, but it works, and it appears necessary */
+ inb_p( video_port_status );
+ outb_p ( 0x20, attrib_port );
+ }
+ sti();
+
+ return 0;
+}
+
+/*
+ * Adjust the screen to fit a font of a certain height
+ */
+static int
+vgacon_adjust_height(unsigned fontheight)
{
- /* TODO */
- return -ENOSYS;
+ int rows, maxscan;
+ unsigned char ovr, vde, fsr;
+
+ if (fontheight == vga_video_font_height)
+ return 0;
+
+ vga_video_font_height = video_font_height = fontheight;
+
+ rows = video_scan_lines/fontheight; /* Number of video rows we end up with */
+ maxscan = rows*fontheight - 1; /* Scan lines to actually display-1 */
+
+ /* Reprogram the CRTC for the new font size
+ Note: the attempt to read the overflow register will fail
+ on an EGA, but using 0xff for the previous value appears to
+ be OK for EGA text modes in the range 257-512 scan lines, so I
+ guess we don't need to worry about it.
+
+ The same applies for the spill bits in the font size and cursor
+ registers; they are write-only on EGA, but it appears that they
+ are all don't care bits on EGA, so I guess it doesn't matter. */
+
+ cli();
+ outb_p( 0x07, vga_video_port_reg ); /* CRTC overflow register */
+ ovr = inb_p(vga_video_port_val);
+ outb_p( 0x09, vga_video_port_reg ); /* Font size register */
+ fsr = inb_p(vga_video_port_val);
+ sti();
+
+ vde = maxscan & 0xff; /* Vertical display end reg */
+ ovr = (ovr & 0xbd) + /* Overflow register */
+ ((maxscan & 0x100) >> 7) +
+ ((maxscan & 0x200) >> 3);
+ fsr = (fsr & 0xe0) + (fontheight-1); /* Font size register */
+
+ cli();
+ outb_p( 0x07, vga_video_port_reg ); /* CRTC overflow register */
+ outb_p( ovr, vga_video_port_val );
+ outb_p( 0x09, vga_video_port_reg ); /* Font size */
+ outb_p( fsr, vga_video_port_val );
+ outb_p( 0x12, vga_video_port_reg ); /* Vertical display limit */
+ outb_p( vde, vga_video_port_val );
+ sti();
+
+ vc_resize_all(rows, 0); /* Adjust console size */
+ return 0;
}
-static int vgacon_set_palette(struct vc_data *conp, unsigned char *table)
+static int vgacon_font_op(struct vc_data *c, struct console_font_op *op)
{
- int i, j ;
+ int rc;
- if (vga_video_type != VIDEO_TYPE_VGAC || console_blanked ||
- vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
+ if (vga_video_type < VIDEO_TYPE_EGAM)
return -EINVAL;
- for (i=j=0; i<16; i++) {
- outb_p (table[i], dac_reg) ;
- outb_p (vc_cons[fg_console].d->vc_palette[j++]>>2, dac_val) ;
- outb_p (vc_cons[fg_console].d->vc_palette[j++]>>2, dac_val) ;
- outb_p (vc_cons[fg_console].d->vc_palette[j++]>>2, dac_val) ;
- }
- return 0;
+ if (op->op == KD_FONT_OP_SET) {
+ if (op->width != 8 || (op->charcount != 256 && op->charcount != 512))
+ return -EINVAL;
+ rc = vgacon_do_font_op(op->data, 1, op->charcount == 512);
+ if (!rc && !(op->flags & KD_FONT_FLAG_DONT_RECALC))
+ rc = vgacon_adjust_height(op->height);
+ } else if (op->op == KD_FONT_OP_GET) {
+ op->width = 8;
+ op->height = vga_video_font_height;
+ op->charcount = vga_512_chars ? 512 : 256;
+ if (!op->data) return 0;
+ rc = vgacon_do_font_op(op->data, 0, 0);
+ } else
+ rc = -ENOSYS;
+ return rc;
}
-static int vgacon_scrolldelta(int lines)
+#else
+
+static int vgacon_font_op(struct vc_data *c, struct console_font_op *op)
{
- /* TODO */
- return -ENOSYS;
+ return -ENOSYS;
}
-static int vgacon_set_mode(struct vc_data *conp, int mode)
+#endif
+
+static int vgacon_scrolldelta(struct vc_data *c, int lines)
{
- return -ENOSYS;
+ if (!lines) /* Turn scrollback off */
+ c->vc_visible_origin = c->vc_origin;
+ else {
+ int p = c->vc_visible_origin - vga_vram_base;
+ int margin = c->vc_rows/4 * c->vc_size_row;
+ p += lines * c->vc_size_row;
+ if (lines < 0 && p < margin)
+ p = 0;
+ c->vc_visible_origin = p + vga_vram_base;
+ if (lines > 0 && c->vc_visible_origin > c->vc_origin - margin)
+ c->vc_visible_origin = c->vc_origin;
+ }
+ vga_set_mem_top(c);
+ return 1;
}
+static int vgacon_set_origin(struct vc_data *c)
+{
+ if (vga_is_gfx || /* We don't play origin tricks in graphic modes */
+ (console_blanked && !vga_palette_blanked)) /* Nor we write to blanked screens */
+ return 0;
+ c->vc_origin = c->vc_visible_origin = vga_vram_base;
+ vga_set_mem_top(c);
+ return 1;
+}
-__initfunc(static int vgacon_show_logo( void ))
+static void vgacon_save_screen(struct vc_data *c)
{
- int height = 0;
- char *p;
-
- printk(linux_serial_image);
- for (p = linux_serial_image; *p; p++)
- if (*p == '\n')
- height++;
- return height;
+ static int vga_bootup_console = 0;
+
+ if (!vga_bootup_console) {
+ /* This is a gross hack, but here is the only place we can
+ * set bootup console parameters without messing up generic
+ * console initialization routines.
+ */
+ vga_bootup_console = 1;
+ c->vc_x = ORIG_X;
+ c->vc_y = ORIG_Y;
+ }
+ if (vga_is_gfx)
+ return;
+ scr_memcpyw_from((u16 *) c->vc_screenbuf, (u16 *) c->vc_origin, c->vc_screenbuf_size);
}
+static int vgacon_scroll(struct vc_data *c, int t, int b, int dir, int lines)
+{
+ unsigned long oldo;
+ unsigned int delta;
+
+ if (t || b != c->vc_rows || vga_is_gfx)
+ return 0;
+
+ if (c->vc_origin != c->vc_visible_origin)
+ vgacon_scrolldelta(c, 0);
+
+ if (!vga_hardscroll_enabled || lines >= c->vc_rows/2)
+ return 0;
+
+ oldo = c->vc_origin;
+ delta = lines * c->vc_size_row;
+ if (dir == SM_UP) {
+ if (c->vc_scr_end + delta >= vga_vram_end) {
+ scr_memcpyw((u16 *)vga_vram_base,
+ (u16 *)(oldo + delta),
+ c->vc_screenbuf_size - delta);
+ c->vc_origin = vga_vram_base;
+ } else
+ c->vc_origin += delta;
+ scr_memsetw((u16 *)(c->vc_origin + c->vc_screenbuf_size - delta), c->vc_video_erase_char, delta);
+ } else {
+ if (oldo - delta < vga_vram_base) {
+ scr_memmovew((u16 *)(vga_vram_end - c->vc_screenbuf_size + delta),
+ (u16 *)oldo,
+ c->vc_screenbuf_size - delta);
+ c->vc_origin = vga_vram_end - c->vc_screenbuf_size;
+ } else
+ c->vc_origin -= delta;
+ c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
+ scr_memsetw((u16 *)(c->vc_origin), c->vc_video_erase_char, delta);
+ }
+ c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
+ c->vc_visible_origin = c->vc_origin;
+ vga_set_mem_top(c);
+ c->vc_pos = (c->vc_pos - oldo) + c->vc_origin;
+ return 1;
+}
/*
* The console `switch' structure for the VGA based console
*/
+static int vgacon_dummy(struct vc_data *c)
+{
+ return 0;
+}
+
+#define DUMMY (void *) vgacon_dummy
+
struct consw vga_con = {
- vgacon_startup, vgacon_init, vgacon_deinit, vgacon_clear, vgacon_putc,
- vgacon_putcs, vgacon_cursor, vgacon_scroll, vgacon_bmove, vgacon_switch,
- vgacon_blank, vgacon_get_font, vgacon_set_font, vgacon_set_palette,
- vgacon_scrolldelta, vgacon_set_mode
+ vgacon_startup,
+ vgacon_init,
+ vgacon_deinit,
+ DUMMY, /* con_clear */
+ DUMMY, /* con_putc */
+ DUMMY, /* con_putcs */
+ vgacon_cursor,
+ vgacon_scroll, /* con_scroll */
+ DUMMY, /* con_bmove */
+ vgacon_switch,
+ vgacon_blank,
+ vgacon_font_op,
+ vgacon_set_palette,
+ vgacon_scrolldelta,
+ vgacon_set_origin,
+ vgacon_save_screen,
+ vgacon_build_attr,
+ vgacon_invert_region
};
diff --git a/drivers/video/vgafb.c b/drivers/video/vgafb.c
new file mode 100644
index 000000000..c8fc4c9a0
--- /dev/null
+++ b/drivers/video/vgafb.c
@@ -0,0 +1,764 @@
+/*
+ * linux/drivers/video/vgafb.c -- VGA frame buffer device
+ *
+ * Created 28 Mar 1998 by Geert Uytterhoeven
+ * Hardware cursor support added on 14 Apr 1998 by Emmanuel Marty
+ *
+ * This file is heavily based on vgacon.c. Read about its contributors there.
+ *
+ * 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.
+ */
+
+
+
+
+/* KNOWN PROBLEMS/TO DO ===================================================== *
+ *
+ * - add support for loadable fonts and VESA blanking
+ *
+ * - for now only VGA _text_ mode is supported
+ *
+ * KNOWN PROBLEMS/TO DO ==================================================== */
+
+
+#include <linux/module.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/ioport.h>
+#include <linux/init.h>
+#include <linux/selection.h>
+#include <linux/console.h>
+#include <linux/vt_kern.h>
+
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#include "fbcon.h"
+#include "fbcon-vga.h"
+
+
+#define BLANK 0x0020
+
+#define CAN_LOAD_EGA_FONTS /* undefine if the user must not do this */
+#define CAN_LOAD_PALETTE /* undefine if the user must not do this */
+
+#define dac_reg (0x3c8)
+#define dac_val (0x3c9)
+
+#ifdef __powerpc__
+#define VGA_OFFSET _ISA_MEM_BASE;
+#else
+#define VGA_OFFSET 0x0
+#endif
+
+
+static int currcon = 0;
+static struct display disp;
+static struct fb_info fb_info;
+static struct { u_char red, green, blue, pad; } palette[16];
+
+static struct fb_fix_screeninfo fb_fix = { { 0, } };
+static struct fb_var_screeninfo fb_var = { 0, };
+
+
+/* Description of the hardware situation */
+static unsigned char vga_video_type;
+static unsigned long vga_video_mem_base; /* Base of video memory */
+static unsigned long vga_video_mem_term; /* End of video memory */
+static u16 vga_video_port_reg; /* Video register select port */
+static u16 vga_video_port_val; /* Video register value port */
+static unsigned long vga_video_num_columns; /* Number of text columns */
+static unsigned long vga_video_num_lines; /* Number of text lines */
+static int vga_can_do_color = 0;
+
+
+ /*
+ * VGA screen access
+ */
+
+static inline void vga_writew(u16 val, u16 *addr)
+{
+#ifdef __powerpc__
+ st_le16(addr, val);
+#else
+ writew(val, (unsigned long)addr);
+#endif /* !__powerpc__ */
+}
+
+static inline u16 vga_readw(u16 *addr)
+{
+#ifdef __powerpc__
+ return ld_le16(addr);
+#else
+ return readw((unsigned long)addr);
+#endif /* !__powerpc__ */
+}
+
+/*
+ * 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
+ * console during heavy scrolling activity. However there is the remote
+ * possibility that some pre-dinosaur hardware won't like the back to back
+ * I/O. Since the Xservers get away with it, we should be able to as well.
+ */
+static inline void write_vga(unsigned char reg, unsigned int val)
+{
+#ifndef SLOW_VGA
+ unsigned int v1, v2;
+
+ v1 = reg + (val & 0xff00);
+ v2 = reg + 1 + ((val << 8) & 0xff00);
+ outw(v1, vga_video_port_reg);
+ outw(v2, vga_video_port_reg);
+#else
+ outb_p(reg, vga_video_port_reg);
+ outb_p(val >> 8, vga_video_port_val);
+ outb_p(reg+1, vga_video_port_reg);
+ outb_p(val & 0xff, vga_video_port_val);
+#endif
+}
+
+static inline void vga_set_origin(unsigned short location)
+{
+ write_vga(12, location >> 1);
+}
+
+static inline void vga_set_cursor(int location)
+{
+ write_vga(14, location >> 1);
+}
+
+static void vga_set_split(unsigned short linenum)
+{
+ unsigned long flags;
+ unsigned char overflow, fontsize;
+
+ if (vga_video_type != VIDEO_TYPE_VGAC) {
+ return;
+ }
+
+ save_flags(flags); cli();
+
+ outb_p(0x07, vga_video_port_reg);
+ overflow = inb_p(vga_video_port_val);
+
+ outb_p(0x09, vga_video_port_reg);
+ fontsize = inb_p(vga_video_port_val);
+
+ overflow &= ~0x10; overflow |= (linenum & 0x100) ? 0x10 : 0;
+ fontsize &= ~0x40; fontsize |= (linenum & 0x200) ? 0x40 : 0;
+ linenum &= 0xff;
+
+ outb_p(0x18, vga_video_port_reg);
+ outb_p(linenum, vga_video_port_val);
+
+ outb_p(0x07, vga_video_port_reg);
+ outb_p(overflow, vga_video_port_val);
+
+ outb_p(0x09, vga_video_port_reg);
+ outb_p(fontsize, vga_video_port_val);
+
+ restore_flags(flags);
+}
+
+static inline void vga_set_palreg(u_int regno, u_int red,
+ u_int green, u_int blue)
+{
+ unsigned long flags;
+
+ save_flags(flags); cli();
+
+ outb_p(regno, dac_reg);
+ outb_p(red, dac_val);
+ outb_p(green, dac_val);
+ outb_p(blue, dac_val);
+
+ restore_flags(flags);
+}
+
+
+ /*
+ * Interface used by the world
+ */
+
+static int vgafb_open(struct fb_info *info, int user);
+static int vgafb_release(struct fb_info *info, int user);
+static int vgafb_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info);
+static int vgafb_get_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int vgafb_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int vgafb_pan_display(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info);
+static int vgafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+static int vgafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info);
+static int vgafb_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
+ */
+
+void vgafb_init(void);
+void vgafb_setup(char *options, int *ints);
+static int vgafbcon_switch(int con, struct fb_info *info);
+static int vgafbcon_updatevar(int con, struct fb_info *info);
+static void vgafbcon_blank(int blank, struct fb_info *info);
+
+
+ /*
+ * VGA text console with hardware cursor
+ */
+
+static struct display_switch fbcon_vgafb;
+
+
+ /*
+ * Internal routines
+ */
+
+static int vgafb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+ u_int *transp, struct fb_info *info);
+static int vgafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info);
+static void do_install_cmap(int con, struct fb_info *info);
+
+
+static struct fb_ops vgafb_ops = {
+ vgafb_open, vgafb_release, vgafb_get_fix, vgafb_get_var, vgafb_set_var,
+ vgafb_get_cmap, vgafb_set_cmap, vgafb_pan_display, vgafb_ioctl
+};
+
+
+ /*
+ * Open/Release the frame buffer device
+ */
+
+static int vgafb_open(struct fb_info *info, int user)
+
+{
+ /*
+ * Nothing, only a usage count for the moment
+ */
+
+ MOD_INC_USE_COUNT;
+ return(0);
+}
+
+static int vgafb_release(struct fb_info *info, int user)
+{
+ MOD_DEC_USE_COUNT;
+ return(0);
+}
+
+
+ /*
+ * Get the Fixed Part of the Display
+ */
+
+static int vgafb_get_fix(struct fb_fix_screeninfo *fix, int con,
+ struct fb_info *info)
+{
+ memcpy(fix, &fb_fix, sizeof(fb_fix));
+ return 0;
+}
+
+
+ /*
+ * Get the User Defined Part of the Display
+ */
+
+static int vgafb_get_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ memcpy(var, &fb_var, sizeof(fb_var));
+ return 0;
+}
+
+
+ /*
+ * Set the User Defined Part of the Display
+ */
+
+static int vgafb_set_var(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ struct display *display;
+ int oldbpp = -1, err;
+
+ if (con >= 0)
+ display = &fb_display[con];
+ else
+ display = &disp; /* used during initialization */
+
+ if (var->xres > fb_var.xres || var->yres > fb_var.yres ||
+ var->xres_virtual > fb_var.xres_virtual ||
+ var->yres_virtual > fb_var.yres_virtual ||
+ var->bits_per_pixel > fb_var.bits_per_pixel ||
+ var->nonstd || !(var->accel_flags & FB_ACCELF_TEXT) ||
+ (var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED)
+ return -EINVAL;
+ memcpy(var, &fb_var, sizeof(fb_var));
+
+ if ((var->activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
+ oldbpp = display->var.bits_per_pixel;
+ display->var = *var;
+ vga_set_origin(var->yoffset/video_font_height*fb_fix.line_length);
+ }
+
+ if (oldbpp != var->bits_per_pixel) {
+ if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
+ return err;
+ do_install_cmap(con, info);
+ }
+ return 0;
+}
+
+
+ /*
+ * Pan or Wrap the Display
+ *
+ * This call looks only at xoffset, yoffset and the FB_VMODE_YWRAP flag
+ */
+
+static int vgafb_pan_display(struct fb_var_screeninfo *var, int con,
+ struct fb_info *info)
+{
+ if (var->xoffset || var->yoffset+var->yres > var->yres_virtual)
+ return -EINVAL;
+
+ vga_set_origin(var->yoffset/video_font_height*fb_fix.line_length);
+ return 0;
+}
+
+
+ /*
+ * Get the Colormap
+ */
+
+static int vgafb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ if (con == currcon) /* current console? */
+ return fb_get_cmap(cmap, &fb_display[con].var, kspc, vgafb_getcolreg,
+ info);
+ else if (fb_display[con].cmap.len) /* non default colormap? */
+ fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+ else
+ fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+ cmap, kspc ? 0 : 2);
+ return 0;
+}
+
+
+ /*
+ * Set the Colormap
+ */
+
+static int vgafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+ struct fb_info *info)
+{
+ int err;
+
+ if (!fb_display[con].cmap.len) { /* no colormap allocated? */
+ if ((err = fb_alloc_cmap(&fb_display[con].cmap,
+ 1<<fb_display[con].var.bits_per_pixel, 0)))
+ return err;
+ }
+ if (con == currcon) { /* current console? */
+ err = fb_set_cmap(cmap, &fb_display[con].var, kspc, vgafb_setcolreg,
+ info);
+ return err;
+ } else
+ fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
+ return 0;
+}
+
+
+static int vgafb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+ u_long arg, int con, struct fb_info *info)
+{
+ return -EINVAL;
+}
+
+
+ /*
+ * Move hardware vga cursor
+ */
+
+static void fbcon_vgafb_cursor(struct display *p, int mode, int x, int y)
+{
+ switch (mode) {
+ case CM_ERASE:
+ vga_set_cursor(vga_video_mem_term - vga_video_mem_base - 1);
+ break;
+
+ case CM_MOVE:
+ case CM_DRAW:
+ vga_set_cursor(y*p->next_line + (x << 1));
+ break;
+ }
+}
+
+
+ /*
+ * Initialisation
+ */
+
+__initfunc(void vgafb_init(void))
+{
+ u16 saved;
+ u16 *p;
+
+ if (screen_info.orig_video_isVGA == VIDEO_TYPE_VLFB)
+ return;
+
+ vga_video_num_lines = ORIG_VIDEO_LINES;
+ vga_video_num_columns = ORIG_VIDEO_COLS;
+
+ if (ORIG_VIDEO_MODE == 7) { /* Is this a monochrome display? */
+ vga_video_mem_base = 0xb0000 + VGA_OFFSET;
+ vga_video_port_reg = 0x3b4;
+ vga_video_port_val = 0x3b5;
+ if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) {
+ vga_video_type = VIDEO_TYPE_EGAM;
+ vga_video_mem_term = 0xb8000 + VGA_OFFSET;
+ strcpy(fb_fix.id, "EGA+");
+ request_region(0x3b0, 16, "ega");
+ } else {
+ vga_video_type = VIDEO_TYPE_MDA;
+ vga_video_mem_term = 0xb1000 + VGA_OFFSET;
+ strcpy(fb_fix.id, "*MDA");
+ request_region(0x3b0, 12, "mda");
+ request_region(0x3bf, 1, "mda");
+ }
+ } else { /* If not, it is color. */
+ vga_can_do_color = 1;
+ vga_video_mem_base = 0xb8000 + VGA_OFFSET;
+ vga_video_port_reg = 0x3d4;
+ vga_video_port_val = 0x3d5;
+ if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) {
+ int i;
+
+ vga_video_mem_term = 0xc0000 + VGA_OFFSET;
+
+ if (!ORIG_VIDEO_ISVGA) {
+ vga_video_type = VIDEO_TYPE_EGAC;
+ strcpy(fb_fix.id, "EGA");
+ request_region(0x3c0, 32, "ega");
+ } else {
+ vga_video_type = VIDEO_TYPE_VGAC;
+ strcpy(fb_fix.id, "VGA+");
+ request_region(0x3c0, 32, "vga+");
+
+#ifdef VGA_CAN_DO_64KB
+ /*
+ * get 64K rather than 32K of video RAM.
+ * This doesn't actually work on all "VGA"
+ * controllers (it seems like setting MM=01
+ * and COE=1 isn't necessarily a good idea)
+ */
+ vga_video_mem_base = 0xa0000 + VGA_OFFSET;
+ vga_video_mem_term = 0xb0000 + VGA_OFFSET;
+ outb_p(6, 0x3ce);
+ outb_p(6, 0x3cf);
+#endif
+
+ /*
+ * Normalise the palette registers, to point
+ * the 16 screen colours to the first 16
+ * DAC entries.
+ */
+
+ for (i = 0; i < 16; i++) {
+ inb_p(0x3da);
+ outb_p(i, 0x3c0);
+ outb_p(i, 0x3c0);
+ }
+ outb_p(0x20, 0x3c0);
+
+ /* now set the DAC registers back to their
+ * default values */
+
+ for (i = 0; i < 16; i++) {
+ vga_set_palreg(color_table[i], default_red[i],
+ default_grn[i], default_blu[i]);
+ }
+ }
+ } else {
+ vga_video_type = VIDEO_TYPE_CGA;
+ vga_video_mem_term = 0xba000 + VGA_OFFSET;
+ strcpy(fb_fix.id, "*CGA");
+ request_region(0x3d4, 2, "cga");
+ }
+ }
+
+ /*
+ * Find out if there is a graphics card present.
+ * Are there smarter methods around?
+ */
+ p = (u16 *)vga_video_mem_base;
+ saved = vga_readw(p);
+ vga_writew(0xAA55, p);
+ if (vga_readw(p) != 0xAA55) {
+ vga_writew(saved, p);
+ return;
+ }
+ vga_writew(0x55AA, p);
+ if (vga_readw(p) != 0x55AA) {
+ vga_writew(saved, p);
+ return;
+ }
+ vga_writew(saved, p);
+
+ if (vga_video_type == VIDEO_TYPE_VGAC
+ || vga_video_type == VIDEO_TYPE_EGAC
+ || vga_video_type == VIDEO_TYPE_EGAM) {
+ video_font_height = ORIG_VIDEO_POINTS;
+ } else {
+ video_font_height = 16;
+ }
+
+ /* This may be suboptimal but is a safe bet - go with it */
+ video_scan_lines = video_font_height * vga_video_num_lines;
+
+ fb_fix.smem_start = (char *) vga_video_mem_base;
+ fb_fix.smem_len = vga_video_mem_term - vga_video_mem_base;
+ fb_fix.type = FB_TYPE_TEXT;
+ fb_fix.type_aux = vga_can_do_color ? FB_AUX_TEXT_CGA : FB_AUX_TEXT_MDA;
+ fb_fix.visual = FB_VISUAL_PSEUDOCOLOR;
+ fb_fix.xpanstep = 0;
+ fb_fix.ypanstep = video_font_height;
+ fb_fix.ywrapstep = 0;
+ fb_fix.line_length = 2*vga_video_num_columns;
+ fb_fix.mmio_start = NULL;
+ fb_fix.mmio_len = 0;
+ fb_fix.accel = FB_ACCEL_NONE;
+
+ fb_var.xres = vga_video_num_columns*8;
+ fb_var.yres = vga_video_num_lines*video_font_height;
+ fb_var.xres_virtual = fb_var.xres;
+ /* the cursor is put at the end of the video memory, hence the -2 */
+ fb_var.yres_virtual = ((fb_fix.smem_len-2)/fb_fix.line_length)*
+ video_font_height;
+
+ fb_var.xoffset = fb_var.yoffset = 0;
+ fb_var.bits_per_pixel = vga_can_do_color ? 4 : 1;
+ fb_var.grayscale = !vga_can_do_color;
+ fb_var.red.offset = 0;
+ fb_var.red.length = 6;
+ fb_var.red.msb_right = 0;
+ fb_var.green.offset = 0;
+ fb_var.green.length = 6;
+ fb_var.green.msb_right = 0;
+ fb_var.blue.offset = 0;
+ fb_var.blue.length = 6;
+ fb_var.blue.msb_right = 0;
+ fb_var.transp.offset = 0;
+ fb_var.transp.length = 0;
+ fb_var.transp.msb_right = 0;
+ fb_var.nonstd = 0;
+ fb_var.activate = 0;
+ fb_var.height = fb_var.width = -1;
+ fb_var.accel_flags = FB_ACCELF_TEXT;
+ fb_var.pixclock = 39722; /* 25.175 MHz */
+ fb_var.left_margin = 40;
+ fb_var.right_margin = 24;
+ fb_var.upper_margin = 39;
+ fb_var.lower_margin = 9;
+ fb_var.hsync_len = 96;
+ fb_var.vsync_len = 2;
+ fb_var.sync = 0;
+ fb_var.vmode = FB_VMODE_NONINTERLACED;
+
+ disp.var = fb_var;
+ disp.cmap.start = 0;
+ disp.cmap.len = 0;
+ disp.cmap.red = NULL;
+ disp.cmap.green = NULL;
+ disp.cmap.blue = NULL;
+ disp.cmap.transp = NULL;
+
+#ifdef __i386__
+ disp.screen_base = ioremap((unsigned long) fb_fix.smem_start,
+ fb_fix.smem_len);
+#else
+ disp.screen_base = bus_to_virt((unsigned long) fb_fix.smem_start);
+#endif
+ disp.visual = fb_fix.visual;
+ disp.type = fb_fix.type;
+ disp.type_aux = fb_fix.type_aux;
+ disp.ypanstep = fb_fix.ypanstep;
+ disp.ywrapstep = fb_fix.ywrapstep;
+ disp.line_length = fb_fix.line_length;
+ disp.can_soft_blank = vga_can_do_color;
+ disp.inverse = 0;
+ disp.dispsw = &fbcon_vgafb;
+
+ strcpy(fb_info.modename, fb_fix.id);
+ fb_info.node = -1;
+ fb_info.fbops = &vgafb_ops;
+ fb_info.disp = &disp;
+ fb_info.fontname[0] = '\0';
+ fb_info.changevar = NULL;
+ fb_info.switch_con = &vgafbcon_switch;
+ fb_info.updatevar = &vgafbcon_updatevar;
+ fb_info.blank = &vgafbcon_blank;
+
+ vgafb_set_var(&fb_var, -1, &fb_info);
+
+ if (register_framebuffer(&fb_info) < 0)
+ return;
+
+ printk("fb%d: VGA frame buffer device, using %dK of video memory\n",
+ GET_FB_IDX(fb_info.node), fb_fix.smem_len>>10);
+}
+
+__initfunc(void vgafb_setup(char *options, int *ints))
+{
+ /* nothing yet */
+}
+
+ /*
+ * Update the `var' structure (called by fbcon.c)
+ */
+
+static int vgafbcon_updatevar(int con, struct fb_info *info)
+{
+ if (con == currcon) {
+ struct fb_var_screeninfo *var = &fb_display[currcon].var;
+
+ /* hardware scrolling */
+
+ vga_set_origin(var->yoffset / video_font_height *
+ fb_fix.line_length);
+
+ vga_set_split(var->yres - ((var->vmode & FB_VMODE_YWRAP) ?
+ var->yoffset+1 : 0));
+ }
+
+ return 0;
+}
+
+static int vgafbcon_switch(int con, struct fb_info *info)
+{
+ /* Do we have to save the colormap? */
+ if (fb_display[currcon].cmap.len)
+ fb_get_cmap(&fb_display[currcon].cmap, &fb_display[currcon].var, 1,
+ vgafb_getcolreg, info);
+
+ currcon = con;
+ /* Install new colormap */
+ do_install_cmap(con, info);
+ vgafbcon_updatevar(con, info);
+ return 0;
+}
+
+ /*
+ * Blank the display.
+ */
+
+static void vgafbcon_blank(int blank, struct fb_info *info)
+{
+ int i;
+
+ if (blank)
+ for (i = 0; i < 16; i++) {
+ vga_set_palreg(i, 0, 0, 0);
+ }
+ else
+ for (i = 0; i < 16; i++) {
+ vga_set_palreg(i, palette[i].red, palette[i].green,
+ palette[i].blue);
+ }
+}
+
+
+ /*
+ * Read a single color register and split it into
+ * colors/transparent. Return != 0 for invalid regno.
+ */
+
+static int vgafb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+ u_int *transp, struct fb_info *info)
+{
+ if (regno > 15)
+ return 1;
+ *red = palette[regno].red;
+ *green = palette[regno].green;
+ *blue = palette[regno].blue;
+ return 0;
+}
+
+
+ /*
+ * Set a single color register. The values supplied are already
+ * rounded down to the hardware's capabilities (according to the
+ * entries in the var structure). Return != 0 for invalid regno.
+ */
+
+static int vgafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+ u_int transp, struct fb_info *info)
+{
+ if (regno > 15)
+ return 1;
+ palette[regno].red = red;
+ palette[regno].green = green;
+ palette[regno].blue = blue;
+
+ vga_set_palreg(regno, red, green, blue);
+
+ return 0;
+}
+
+static void do_install_cmap(int con, struct fb_info *info)
+{
+ if (con != currcon)
+ return;
+ if (fb_display[con].cmap.len)
+ fb_set_cmap(&fb_display[con].cmap, &fb_display[con].var, 1,
+ vgafb_setcolreg, info);
+ else
+ fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
+ &fb_display[con].var, 1, vgafb_setcolreg,
+ info);
+}
+
+
+ /*
+ * VGA text console with hardware cursor
+ */
+
+static struct display_switch fbcon_vgafb = {
+ fbcon_vga_setup, fbcon_vga_bmove, fbcon_vga_clear, fbcon_vga_putc,
+ fbcon_vga_putcs, fbcon_vga_revc, fbcon_vgafb_cursor, NULL, NULL,
+ FONTWIDTH(8)
+};
+
+
+#ifdef MODULE
+int init_module(void)
+{
+ vgafb_init();
+ return 0;
+}
+
+void cleanup_module(void)
+{
+ unregister_framebuffer(&fb_info);
+}
+#endif /* MODULE */
diff --git a/drivers/video/virgefb.c b/drivers/video/virgefb.c
index d08e4a722..927fbb46d 100644
--- a/drivers/video/virgefb.c
+++ b/drivers/video/virgefb.c
@@ -16,7 +16,6 @@
#undef VIRGEFBDEBUG
-#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
@@ -90,6 +89,7 @@ struct virgefb_par {
int xres;
int yres;
int bpp;
+ int accel;
};
static struct virgefb_par current_par;
@@ -163,49 +163,49 @@ static struct fb_videomode virgefb_predefined[] __initdata = {
"640x480-8", { /* Cybervision 8 bpp */
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, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}, {
"800x600-8", { /* Cybervision 8 bpp */
800, 600, 800, 600, 0, 0, 8, 0,
{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCEL_NONE, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}, {
"1024x768-8", { /* Cybervision 8 bpp */
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, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}, {
"1152x886-8", { /* Cybervision 8 bpp */
1152, 886, 1152, 886, 0, 0, 8, 0,
{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCEL_NONE, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}, {
"1280x1024-8", { /* Cybervision 8 bpp */
1280, 1024, 1280, 1024, 0, 0, 8, 0,
{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCEL_NONE, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}, {
"1600x1200-8", { /* Cybervision 8 bpp */
1600, 1200, 1600, 1200, 0, 0, 8, 0,
{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCEL_NONE, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ 0, 0, -1, -1, FB_ACCELF_TEXT, VIRGE8_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}, {
"800x600-16", { /* Cybervision 16 bpp */
800, 600, 800, 600, 0, 0, 16, 0,
{11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},
- 0, 0, -1, -1, FB_ACCEL_NONE, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
+ 0, 0, -1, -1, 0, VIRGE16_PIXCLOCK, 64, 96, 35, 12, 112, 2,
FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
}
}
@@ -237,8 +237,8 @@ static struct fb_var_screeninfo virgefb_default;
void virgefb_setup(char *options, int *ints);
-static int virgefb_open(struct fb_info *info);
-static int virgefb_release(struct fb_info *info);
+static int virgefb_open(struct fb_info *info, int user);
+static int virgefb_release(struct fb_info *info, int user);
static int virgefb_get_fix(struct fb_fix_screeninfo *fix, int con, struct
fb_info *info);
static int virgefb_get_var(struct fb_var_screeninfo *var, int con, struct
@@ -259,7 +259,7 @@ static int virgefb_ioctl(struct inode *inode, struct file *file, u_int cmd,
* Interface to the low level console driver
*/
-unsigned long virgefb_init(unsigned long mem_start);
+void 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);
@@ -269,7 +269,7 @@ static void Cyberfb_blank(int blank, struct fb_info *info);
* Text console acceleration
*/
-#ifdef CONFIG_FBCON_CFB8
+#ifdef FBCON_HAS_CFB8
static struct display_switch fbcon_virge8;
#endif
@@ -370,12 +370,11 @@ static int Cyber_init(void)
static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
struct virgefb_par *par)
{
- int i;
-
+ memset(fix, 0, sizeof(struct fb_fix_screeninfo));
strcpy(fix->id, virgefb_name);
- fix->smem_start = (caddr_t)CyberMem;
+ fix->smem_start = (char *)CyberMem;
fix->smem_len = CyberSize;
- fix->mmio_start = (unsigned char *)CyberRegs;
+ fix->mmio_start = (char *)CyberRegs;
fix->mmio_len = 0x10000; /* TODO: verify this for the CV64/3D */
fix->type = FB_TYPE_PACKED_PIXELS;
@@ -389,10 +388,7 @@ static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,
fix->ypanstep = 0;
fix->ywrapstep = 0;
fix->line_length = 0;
-
- for (i = 0; i < arraysize(fix->reserved); i++)
- fix->reserved[i] = 0;
-
+ fix->accel = FB_ACCEL_S3_VIRGE;
return(0);
}
@@ -409,6 +405,10 @@ static int Cyber_decode_var(struct fb_var_screeninfo *var,
par->xres = var->xres;
par->yres = var->yres;
par->bpp = var->bits_per_pixel;
+ if (var->accel_flags & FB_ACCELF_TEXT)
+ par->accel = FB_ACCELF_TEXT;
+ else
+ par->accel = 0;
#else
if (Cyberfb_Cyber8) {
par->xres = VIRGE8_WIDTH;
@@ -432,8 +432,7 @@ static int Cyber_decode_var(struct fb_var_screeninfo *var,
static int Cyber_encode_var(struct fb_var_screeninfo *var,
struct virgefb_par *par)
{
- int i;
-
+ memset(var, 0, sizeof(struct fb_var_screeninfo));
var->xres = par->xres;
var->yres = par->yres;
var->xres_virtual = par->xres;
@@ -470,7 +469,7 @@ static int Cyber_encode_var(struct fb_var_screeninfo *var,
var->height = -1;
var->width = -1;
- var->accel = FB_ACCEL_S3VIRGE;
+ var->accel_flags = (par->accel && par->bpp == 8) ? FB_ACCELF_TEXT : 0;
DPRINTK("accel CV64/3D\n");
var->vmode = FB_VMODE_NONINTERLACED;
@@ -489,9 +488,6 @@ static int Cyber_encode_var(struct fb_var_screeninfo *var,
var->hsync_len = 112;
var->vsync_len = 2;
- for (i = 0; i < arraysize(var->reserved); i++)
- var->reserved[i] = 0;
-
return(0);
}
@@ -768,7 +764,7 @@ static void do_install_cmap(int con, struct fb_info *info)
* Open/Release the frame buffer device
*/
-static int virgefb_open(struct fb_info *info)
+static int virgefb_open(struct fb_info *info, int user)
{
/*
* Nothing, only a usage count for the moment
@@ -778,7 +774,7 @@ static int virgefb_open(struct fb_info *info)
return(0);
}
-static int virgefb_release(struct fb_info *info)
+static int virgefb_release(struct fb_info *info, int user)
{
MOD_DEC_USE_COUNT;
return(0);
@@ -841,7 +837,7 @@ static void virgefb_set_disp(int con, struct fb_info *info)
virgefb_get_fix(&fix, con, info);
if (con == -1)
con = 0;
- display->screen_base = (u_char *)fix.smem_start;
+ display->screen_base = fix.smem_start;
display->visual = fix.visual;
display->type = fix.type;
display->type_aux = fix.type_aux;
@@ -850,12 +846,16 @@ static void virgefb_set_disp(int con, struct fb_info *info)
display->can_soft_blank = 1;
display->inverse = Cyberfb_inverse;
switch (display->var.bits_per_pixel) {
-#ifdef CONFIG_FBCON_CFB8
+#ifdef FBCON_HAS_CFB8
case 8:
- display->dispsw = &fbcon_virge8;
+ if (display->var.accel_flags & FB_ACCELF_TEXT) {
+ display->dispsw = &fbcon_virge8;
+#warning FIXME: We should reinit the graphics engine here
+ } else
+ display->dispsw = &fbcon_virge8;
break;
#endif
-#ifdef CONFIG_FBCON_CFB16
+#ifdef FBCON_HAS_CFB16
case 16:
display->dispsw = &fbcon_cfb16;
break;
@@ -874,7 +874,7 @@ static void virgefb_set_disp(int con, struct fb_info *info)
static int virgefb_set_var(struct fb_var_screeninfo *var, int con,
struct fb_info *info)
{
- int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp;
+ int err, oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel;
if ((err = do_fb_set_var(var, con == currcon)))
return(err);
@@ -884,11 +884,13 @@ static int virgefb_set_var(struct fb_var_screeninfo *var, int con,
oldvxres = fb_display[con].var.xres_virtual;
oldvyres = fb_display[con].var.yres_virtual;
oldbpp = fb_display[con].var.bits_per_pixel;
+ oldaccel = fb_display[con].var.accel_flags;
fb_display[con].var = *var;
if (oldxres != var->xres || oldyres != var->yres ||
oldvxres != var->xres_virtual ||
oldvyres != var->yres_virtual ||
- oldbpp != var->bits_per_pixel) {
+ oldbpp != var->bits_per_pixel ||
+ oldaccel != var->accel_flags) {
virgefb_set_disp(con, info);
(*fb_info.changevar)(con);
fb_alloc_cmap(&fb_display[con].cmap, 0, 0);
@@ -969,7 +971,7 @@ static int virgefb_ioctl(struct inode *inode, struct file *file,
static struct fb_ops virgefb_ops = {
virgefb_open, virgefb_release, virgefb_get_fix, virgefb_get_var,
virgefb_set_var, virgefb_get_cmap, virgefb_set_cmap,
- virgefb_pan_display, NULL, virgefb_ioctl
+ virgefb_pan_display, virgefb_ioctl
};
@@ -1007,15 +1009,14 @@ __initfunc(void virgefb_setup(char *options, int *ints))
* Initialization
*/
-__initfunc(unsigned long virgefb_init(unsigned long mem_start))
+__initfunc(void virgefb_init(void))
{
- int err;
struct virgefb_par par;
unsigned long board_addr;
const struct ConfigDev *cd;
if (!(CyberKey = zorro_find(ZORRO_PROD_PHASE5_CYBERVISION64_3D, 0, 0)))
- return mem_start;
+ return;
cd = zorro_get_board (CyberKey);
zorro_config_board (CyberKey, 0);
@@ -1030,22 +1031,17 @@ __initfunc(unsigned long virgefb_init(unsigned long mem_start))
CyberMem = ZTWO_VADDR(board_addr);
printk("CV3D detected running in Z2 mode ... not yet supported!\n");
- return -ENODEV;
+ return;
}
else
{
- CyberVGARegs = kernel_map(board_addr +0x0c000000,
- 0x00010000,
- KERNELMAP_NOCACHE_SER,
- &mem_start);
+ CyberVGARegs = kernel_map(board_addr +0x0c000000, 0x00010000,
+ KERNELMAP_NOCACHE_SER, NULL);
CyberRegs = (char *)kernel_map(board_addr +0x05000000,
0x00010000,
- KERNELMAP_NOCACHE_SER,
- &mem_start);
- CyberMem = kernel_map(board_addr + 0x04800000,
- 0x00400000,
- KERNELMAP_NOCACHE_SER,
- &mem_start);
+ KERNELMAP_NOCACHE_SER, NULL);
+ CyberMem = kernel_map(board_addr + 0x04800000, 0x00400000,
+ KERNELMAP_NOCACHE_SER, NULL);
printk("CV3D detected running in Z3 mode\n");
}
@@ -1060,10 +1056,6 @@ __initfunc(unsigned long virgefb_init(unsigned long mem_start))
fb_info.updatevar = &Cyberfb_updatevar;
fb_info.blank = &Cyberfb_blank;
- err = register_framebuffer(&fb_info);
- if (err < 0)
- return mem_start;
-
fbhw->init();
fbhw->decode_var(&virgefb_default, &par);
fbhw->encode_var(&virgefb_default, &par);
@@ -1073,13 +1065,14 @@ __initfunc(unsigned long virgefb_init(unsigned long mem_start))
virgefb_set_disp(-1, &fb_info);
do_install_cmap(0, &fb_info);
+ if (register_framebuffer(&fb_info) < 0)
+ return;
+
printk("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 mem_start;
}
@@ -1145,7 +1138,7 @@ __initfunc(static int get_video_mode(const char *name))
* Text console acceleration
*/
-#ifdef CONFIG_FBCON_CFB8
+#ifdef FBCON_HAS_CFB8
static void fbcon_virge8_bmove(struct display *p, int sy, int sx, int dy,
int dx, int height, int width)
{
@@ -1169,7 +1162,8 @@ static void fbcon_virge8_clear(struct vc_data *conp, struct display *p, int sy,
static struct display_switch fbcon_virge8 = {
fbcon_cfb8_setup, fbcon_virge8_bmove, fbcon_virge8_clear, fbcon_cfb8_putc,
- fbcon_cfb8_putcs, fbcon_cfb8_revc
+ fbcon_cfb8_putcs, fbcon_cfb8_revc, NULL, NULL, fbcon_cfb8_clear_margins,
+ FONTWIDTH(8)
};
#endif
@@ -1177,7 +1171,8 @@ static struct display_switch fbcon_virge8 = {
#ifdef MODULE
int init_module(void)
{
- return(virgefb_init(NULL));
+ virgefb_init();
+ return 0;
}
void cleanup_module(void)